@aerol-ai/aerolvm-sdk 0.5.1 → 0.5.3

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, type RetryConfig } 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, CreateTemplateOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, IngressTarget, Lifecycle, ListOptions, MountSpecRedacted, RegisterSnapshotOptions, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions, Template } from "./types.js";
4
+ import type { BuildImageOptions, BuildImageResult, CloneGeneration, CreateOptions, CreateSessionOptions, CreateTemplateOptions, CreateWasmModuleOptions, PushWasmModuleOptions, PushWasmModuleResult, ExecStreamHandle, ExecStreamOptions, HealthStatus, IngressTarget, Lifecycle, ListOptions, MountSpecRedacted, RegisterSnapshotOptions, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions, Template, WasmModule } from "./types.js";
5
5
  type FetchLike = typeof fetch;
6
6
  export interface MicroVMConfig {
7
7
  patToken?: string;
@@ -48,6 +48,13 @@ export declare class MicroVM {
48
48
  buildImage(image: Image, options?: BuildImageOptions): Promise<BuildImageResult>;
49
49
  health(): Promise<HealthStatus>;
50
50
  mounts(sandboxID: string): Promise<MountSpecRedacted[]>;
51
+ /**
52
+ * Read a sandbox's clone-generation token. The token changes whenever the
53
+ * sandbox is resumed from a snapshot, so a change signals "this is a clone."
54
+ * Read-only — the SDK cannot reseed a process inside the guest; see the
55
+ * "Randomness in cloned sandboxes" docs page for the in-guest reseed pattern.
56
+ */
57
+ cloneGeneration(sandboxID: string): Promise<CloneGeneration>;
51
58
  execStream(sandboxID: string, options: ExecStreamOptions): ExecStreamHandle;
52
59
  createSession(sandboxID: string, options: CreateSessionOptions): Promise<Session>;
53
60
  listSessions(sandboxID: string): Promise<Session[]>;
@@ -72,6 +79,21 @@ export declare class MicroVM {
72
79
  listTemplates(): Promise<Template[]>;
73
80
  getTemplate(id: string): Promise<Template>;
74
81
  deleteTemplate(id: string): Promise<void>;
82
+ /**
83
+ * Register a WASM module in the host catalogue. Resolution is synchronous —
84
+ * the returned row is typically already `ready`. Use the row's `id` or
85
+ * `moduleRef` on subsequent `create` calls with `runtime: "wasm"`.
86
+ */
87
+ createWasmModule(options: CreateWasmModuleOptions): Promise<WasmModule>;
88
+ listWasmModules(): Promise<WasmModule[]>;
89
+ getWasmModule(id: string): Promise<WasmModule>;
90
+ deleteWasmModule(id: string): Promise<void>;
91
+ /**
92
+ * Upload a compiled core-wasip1 module to the registry under your own
93
+ * credentials and get back the `oci://` ref to use as `moduleRef` on create.
94
+ * The daemon validates and forwards the bytes; it never stores them.
95
+ */
96
+ pushWasmModule(options: PushWasmModuleOptions): Promise<PushWasmModuleResult>;
75
97
  /**
76
98
  * Re-run the snapshot phase against an existing template. Idempotent
77
99
  * under concurrent retry: the daemon's CAS collapses N parallel calls
package/dist/MicroVM.js CHANGED
@@ -1,4 +1,4 @@
1
- import { APIClient } from "./internal/client.js";
1
+ import { APIClient, stripTrailingSlashes } from "./internal/client.js";
2
2
  import { Sandbox } from "./Sandbox.js";
3
3
  const defaultAPIURL = "http://127.0.0.1:21212";
4
4
  const authRequiredErrorMessage = "PAT token is required. Set patToken or SB_PAT_TOKEN.";
@@ -80,6 +80,15 @@ export class MicroVM {
80
80
  async mounts(sandboxID) {
81
81
  return this.client.mounts(sandboxID);
82
82
  }
83
+ /**
84
+ * Read a sandbox's clone-generation token. The token changes whenever the
85
+ * sandbox is resumed from a snapshot, so a change signals "this is a clone."
86
+ * Read-only — the SDK cannot reseed a process inside the guest; see the
87
+ * "Randomness in cloned sandboxes" docs page for the in-guest reseed pattern.
88
+ */
89
+ async cloneGeneration(sandboxID) {
90
+ return this.client.cloneGeneration(sandboxID);
91
+ }
83
92
  execStream(sandboxID, options) {
84
93
  return this.client.execStream(sandboxID, options);
85
94
  }
@@ -132,6 +141,31 @@ export class MicroVM {
132
141
  async deleteTemplate(id) {
133
142
  await this.client.deleteTemplate(id);
134
143
  }
144
+ /**
145
+ * Register a WASM module in the host catalogue. Resolution is synchronous —
146
+ * the returned row is typically already `ready`. Use the row's `id` or
147
+ * `moduleRef` on subsequent `create` calls with `runtime: "wasm"`.
148
+ */
149
+ async createWasmModule(options) {
150
+ return this.client.createWasmModule(options);
151
+ }
152
+ async listWasmModules() {
153
+ return this.client.listWasmModules();
154
+ }
155
+ async getWasmModule(id) {
156
+ return this.client.getWasmModule(id);
157
+ }
158
+ async deleteWasmModule(id) {
159
+ await this.client.deleteWasmModule(id);
160
+ }
161
+ /**
162
+ * Upload a compiled core-wasip1 module to the registry under your own
163
+ * credentials and get back the `oci://` ref to use as `moduleRef` on create.
164
+ * The daemon validates and forwards the bytes; it never stores them.
165
+ */
166
+ async pushWasmModule(options) {
167
+ return this.client.pushWasmModule(options);
168
+ }
135
169
  /**
136
170
  * Re-run the snapshot phase against an existing template. Idempotent
137
171
  * under concurrent retry: the daemon's CAS collapses N parallel calls
@@ -164,7 +198,7 @@ export class MicroVM {
164
198
  }
165
199
  }
166
200
  function normalizeURL(value) {
167
- return value.replace(/\/+$/, "");
201
+ return stripTrailingSlashes(value);
168
202
  }
169
203
  function readEnv(name) {
170
204
  if (typeof process === "undefined" || !process.env) {
package/dist/index.d.ts CHANGED
@@ -3,4 +3,4 @@ export { Sandbox } from "./Sandbox.js";
3
3
  export { Image } from "./Image.js";
4
4
  export type { MicroVMConfig } from "./MicroVM.js";
5
5
  export type { RetryConfig } from "./internal/client.js";
6
- export type { AddCustomDomainOptions, BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CreateTemplateOptions, CustomDomain, CustomDomainDNSRecords, CustomDomainStatus, DNSRecord, DNSRecordType, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, Failover, FailoverPolicy, HealthStatus, IngressTarget, IngressTargetSource, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegisterSnapshotOptions, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, Template, TemplatePushState, TemplateStatus, UpdateLifecycleOptions, } from "./types.js";
6
+ export type { AddCustomDomainOptions, BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CloneGeneration, CreateOptions, CreateSessionOptions, CreateTemplateOptions, CreateWasmModuleOptions, CustomDomain, CustomDomainDNSRecords, CustomDomainStatus, DNSRecord, DNSRecordType, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, Failover, FailoverPolicy, HealthStatus, IngressTarget, IngressTargetSource, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegisterSnapshotOptions, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, Template, TemplatePushState, TemplateStatus, WasmModule, WasmModuleStatus, PushWasmModuleOptions, PushWasmModuleResult, UpdateLifecycleOptions, } from "./types.js";
@@ -1,5 +1,5 @@
1
1
  import { Image } from "../Image.js";
2
- import type { AddCustomDomainOptions, BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CreateTemplateOptions, CustomDomain, CustomDomainDNSRecords, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, Failover, HealthStatus, IngressTarget, Lifecycle, ListOptions, MountSpecRedacted, NetworkUsage, RegisterSnapshotOptions, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions, Template } from "../types.js";
2
+ import type { AddCustomDomainOptions, BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CreateTemplateOptions, CreateWasmModuleOptions, PushWasmModuleOptions, PushWasmModuleResult, CustomDomain, CloneGeneration, CustomDomainDNSRecords, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, Failover, HealthStatus, IngressTarget, Lifecycle, ListOptions, MountSpecRedacted, NetworkUsage, RegisterSnapshotOptions, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions, Template, WasmModule } 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
@@ -54,6 +54,12 @@ export interface APIClientConfig {
54
54
  */
55
55
  retry?: RetryConfig;
56
56
  }
57
+ /**
58
+ * Trim trailing slashes from a URL without a backtracking regex. The natural
59
+ * `value.replace(/\/+$/, "")` is an anchored `+` quantifier — a polynomial
60
+ * ReDoS shape that CodeQL flags — so we strip by index instead, which is O(n).
61
+ */
62
+ export declare function stripTrailingSlashes(value: string): string;
57
63
  export declare class APIClient {
58
64
  readonly baseURL: string;
59
65
  readonly apiVersion: APIVersion;
@@ -144,12 +150,18 @@ export declare class APIClient {
144
150
  reconcile(): Promise<void>;
145
151
  health(): Promise<HealthStatus>;
146
152
  mounts(id: string): Promise<MountSpecRedacted[]>;
153
+ cloneGeneration(id: string): Promise<CloneGeneration>;
147
154
  getNetworkUsage(id: string): Promise<NetworkUsage>;
148
155
  setNetworkLimits(id: string, options: SetNetworkLimitsOptions): Promise<NetworkUsage>;
149
156
  createTemplate(options: CreateTemplateOptions): Promise<Template>;
150
157
  listTemplates(): Promise<Template[]>;
151
158
  getTemplate(id: string): Promise<Template>;
152
159
  deleteTemplate(id: string): Promise<void>;
160
+ createWasmModule(options: CreateWasmModuleOptions): Promise<WasmModule>;
161
+ listWasmModules(): Promise<WasmModule[]>;
162
+ getWasmModule(id: string): Promise<WasmModule>;
163
+ deleteWasmModule(id: string): Promise<void>;
164
+ pushWasmModule(options: PushWasmModuleOptions): Promise<PushWasmModuleResult>;
153
165
  rebuildTemplate(id: string): Promise<Template>;
154
166
  private wrap;
155
167
  private doJSON;
@@ -196,6 +208,13 @@ export declare class SandboxResource implements Sandbox {
196
208
  constructor(client: APIClient, sandbox: Sandbox);
197
209
  refresh(): Promise<this>;
198
210
  exec(command: string | ExecRequest): Promise<ExecResult>;
211
+ /**
212
+ * Read this sandbox's clone-generation token. The token changes whenever the
213
+ * sandbox is resumed from a snapshot. Use it to detect that a sandbox is a
214
+ * clone (e.g. to re-run setup). It does NOT reseed in-guest PRNGs — see the
215
+ * "Randomness in cloned sandboxes" docs page for the in-guest pattern.
216
+ */
217
+ cloneGeneration(): Promise<CloneGeneration>;
199
218
  execStream(options: ExecStreamOptions): ExecStreamHandle;
200
219
  createSession(options: CreateSessionOptions): Promise<Session>;
201
220
  listSessions(): Promise<Session[]>;
@@ -47,6 +47,18 @@ function isTransientTransportError(error) {
47
47
  }
48
48
  return false;
49
49
  }
50
+ /**
51
+ * Trim trailing slashes from a URL without a backtracking regex. The natural
52
+ * `value.replace(/\/+$/, "")` is an anchored `+` quantifier — a polynomial
53
+ * ReDoS shape that CodeQL flags — so we strip by index instead, which is O(n).
54
+ */
55
+ export function stripTrailingSlashes(value) {
56
+ let end = value.length;
57
+ while (end > 0 && value.charCodeAt(end - 1) === 47 /* "/" */) {
58
+ end--;
59
+ }
60
+ return value.slice(0, end);
61
+ }
50
62
  /** Sleep with ±25% jitter so concurrent callers don't thundering-herd. */
51
63
  function jitteredDelay(baseMs) {
52
64
  const jitter = 1 + (Math.random() - 0.5) * 0.5; // 0.75 – 1.25
@@ -60,7 +72,7 @@ export class APIClient {
60
72
  versionPrefix;
61
73
  retryConfig;
62
74
  constructor(config) {
63
- this.baseURL = config.baseURL.replace(/\/+$/, "");
75
+ this.baseURL = stripTrailingSlashes(config.baseURL);
64
76
  this.patToken = config.patToken ?? "";
65
77
  this.fetchFn = config.fetch ?? fetch;
66
78
  this.apiVersion = config.apiVersion ?? DEFAULT_API_VERSION;
@@ -320,6 +332,10 @@ export class APIClient {
320
332
  const response = await this.doJSON("GET", `${this.versionPrefix}/sandboxes/${id}/mounts`);
321
333
  return response.mounts.map(fromApiMountSpecRedacted);
322
334
  }
335
+ async cloneGeneration(id) {
336
+ const response = await this.doJSON("GET", `${this.versionPrefix}/sandboxes/${id}/toolbox/clone-generation`);
337
+ return fromApiCloneGeneration(response);
338
+ }
323
339
  async getNetworkUsage(id) {
324
340
  const response = await this.doJSON("GET", `${this.versionPrefix}/sandboxes/${id}/network/usage`);
325
341
  return fromApiNetworkUsage(response);
@@ -349,6 +365,44 @@ export class APIClient {
349
365
  async deleteTemplate(id) {
350
366
  await this.doJSON("DELETE", `${this.versionPrefix}/templates/${id}`);
351
367
  }
368
+ async createWasmModule(options) {
369
+ const response = await this.doJSON("POST", this.versioned("/wasm-modules"), {
370
+ id: options.id,
371
+ module_ref: options.moduleRef,
372
+ entrypoint: options.entrypoint,
373
+ });
374
+ return fromApiWasmModule(response);
375
+ }
376
+ async listWasmModules() {
377
+ const response = await this.doJSON("GET", this.versioned("/wasm-modules"));
378
+ return (response ?? []).map(fromApiWasmModule);
379
+ }
380
+ async getWasmModule(id) {
381
+ const response = await this.doJSON("GET", `${this.versionPrefix}/wasm-modules/${id}`);
382
+ return fromApiWasmModule(response);
383
+ }
384
+ async deleteWasmModule(id) {
385
+ await this.doJSON("DELETE", `${this.versionPrefix}/wasm-modules/${id}`);
386
+ }
387
+ async pushWasmModule(options) {
388
+ const params = new URLSearchParams({ name: options.name });
389
+ if (options.tag) {
390
+ params.set("tag", options.tag);
391
+ }
392
+ const headers = {
393
+ "Content-Type": "application/octet-stream",
394
+ "X-Registry-Token": options.registryToken,
395
+ };
396
+ if (options.registryUsername) {
397
+ headers["X-Registry-Username"] = options.registryUsername;
398
+ }
399
+ const response = await this.request("POST", this.versioned(`/wasm-modules/push?${params.toString()}`), { body: options.module, headers });
400
+ if (!response.ok) {
401
+ throw await decodeError(response);
402
+ }
403
+ const r = (await response.json());
404
+ return { moduleRef: r.module_ref, digest: r.digest, sizeBytes: r.size_bytes };
405
+ }
352
406
  async rebuildTemplate(id) {
353
407
  const response = await this.doJSON("POST", `${this.versionPrefix}/templates/${id}/rebuild`);
354
408
  return fromApiTemplate(response);
@@ -439,6 +493,15 @@ export class SandboxResource {
439
493
  async exec(command) {
440
494
  return this.client.exec(this.id, typeof command === "string" ? { command } : command);
441
495
  }
496
+ /**
497
+ * Read this sandbox's clone-generation token. The token changes whenever the
498
+ * sandbox is resumed from a snapshot. Use it to detect that a sandbox is a
499
+ * clone (e.g. to re-run setup). It does NOT reseed in-guest PRNGs — see the
500
+ * "Randomness in cloned sandboxes" docs page for the in-guest pattern.
501
+ */
502
+ async cloneGeneration() {
503
+ return this.client.cloneGeneration(this.id);
504
+ }
442
505
  execStream(options) {
443
506
  return this.client.execStream(this.id, options);
444
507
  }
@@ -547,6 +610,10 @@ function toApiCreateOptions(options) {
547
610
  env: options.env,
548
611
  os_user: options.osUser,
549
612
  network_block_all: options.networkBlockAll,
613
+ network_allow_out: options.networkAllowOut,
614
+ network_deny_out: options.networkDenyOut,
615
+ allow_public_traffic: options.allowPublicTraffic,
616
+ mask_request_host: options.maskRequestHost,
550
617
  network_bytes_in_limit: options.networkBytesInLimit,
551
618
  network_bytes_out_limit: options.networkBytesOutLimit,
552
619
  registry: options.registry,
@@ -674,6 +741,21 @@ function fromApiTemplate(template) {
674
741
  pushError: template.push_error,
675
742
  };
676
743
  }
744
+ function fromApiWasmModule(module) {
745
+ return {
746
+ id: module.id,
747
+ moduleRef: module.module_ref,
748
+ status: module.status,
749
+ moduleSizeBytes: module.module_size_bytes,
750
+ digest: module.digest,
751
+ entrypoint: module.entrypoint,
752
+ hasWarm: module.has_warm,
753
+ lastError: module.last_error,
754
+ createdAt: module.created_at,
755
+ updatedAt: module.updated_at,
756
+ readyAt: module.ready_at,
757
+ };
758
+ }
677
759
  function fromApiSandboxSnapshot(snapshot) {
678
760
  return {
679
761
  name: snapshot.name,
@@ -758,6 +840,12 @@ function fromApiHealthStatus(status) {
758
840
  version: status.version,
759
841
  };
760
842
  }
843
+ function fromApiCloneGeneration(gen) {
844
+ return {
845
+ generation: gen.generation,
846
+ resumedAt: gen.resumed_at ?? 0,
847
+ };
848
+ }
761
849
  function toApiMountSpec(mount) {
762
850
  return {
763
851
  type: mount.type,
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export type SandboxStatus = "creating" | "started" | "stopped" | "destroyed" | "error";
1
+ export type SandboxStatus = "creating" | "started" | "stopped" | "destroyed" | "error" | "passivated" | "awaiting_runtime";
2
+ export type Durability = "ephemeral" | "passivatable" | "durable";
2
3
  export interface RegistryAuth {
3
4
  server: string;
4
5
  username: string;
@@ -136,6 +137,32 @@ export interface CreateOptions {
136
137
  env?: Record<string, string>;
137
138
  osUser?: string;
138
139
  networkBlockAll?: boolean;
140
+ /**
141
+ * Egress allowlist of CIDRs. When set, the sandbox may reach only these
142
+ * destinations; all other outbound traffic is dropped by the host firewall.
143
+ * Mutually exclusive with `networkDenyOut`. For a full block use
144
+ * `networkBlockAll` instead.
145
+ */
146
+ networkAllowOut?: string[];
147
+ /**
148
+ * Egress blocklist of CIDRs. When set, the sandbox may reach anything except
149
+ * these destinations. Mutually exclusive with `networkAllowOut`.
150
+ */
151
+ networkDenyOut?: string[];
152
+ /**
153
+ * Whether the sandbox may be exposed to the public internet. Defaults to
154
+ * true; set `false` to make `exposePort` fail — the sandbox stays reachable
155
+ * only via the toolbox proxy and SSH gateway, not a public URL.
156
+ */
157
+ allowPublicTraffic?: boolean;
158
+ /**
159
+ * Rewrite the upstream `Host` header on ingress to exposed HTTP ports to this
160
+ * value. Frameworks that validate the Host (Vite `allowedHosts`,
161
+ * webpack-dev-server, Django `ALLOWED_HOSTS`) reject the per-sandbox public
162
+ * hostname; set this to a value they accept (e.g. `"localhost"`). Empty/unset
163
+ * passes the host through unchanged. HTTP-only; TCP/TLS exposures ignore it.
164
+ */
165
+ maskRequestHost?: string;
139
166
  /**
140
167
  * Cap on bytes the sandbox may receive from outside the container before its
141
168
  * ingress is dropped via per-IP iptables rule. `0` (default) is unlimited.
@@ -164,7 +191,15 @@ export interface CreateOptions {
164
191
  *
165
192
  * GPU access is not supported with `"gvisor"`.
166
193
  */
167
- runtime?: "docker" | "gvisor" | "kata" | "firecracker";
194
+ runtime?: "docker" | "gvisor" | "kata" | "firecracker" | "wasm";
195
+ /**
196
+ * Survival class across daemon restarts. Omit for the runtime default:
197
+ * `passivatable` for docker/gvisor/firecracker, `ephemeral` for wasm.
198
+ * `durable` is wasm-only and not yet implemented.
199
+ */
200
+ durability?: Durability;
201
+ /** WASM module reference. When runtime is wasm, may be used instead of image. */
202
+ moduleRef?: string;
168
203
  /**
169
204
  * Attach GPU resources to the sandbox. Omit for CPU-only workloads.
170
205
  * Not compatible with runtime="gvisor".
@@ -380,7 +415,13 @@ export interface Sandbox {
380
415
  * Container runtime this sandbox is running under. Empty string indicates
381
416
  * a pre-migration row that resolves to the host default at start time.
382
417
  */
383
- runtime: "" | "docker" | "gvisor" | "kata" | "firecracker";
418
+ runtime: "" | "docker" | "gvisor" | "kata" | "firecracker" | "wasm";
419
+ /** Survival class this sandbox was created with. */
420
+ durability?: Durability;
421
+ /** Resolved WASM module reference when runtime is wasm. */
422
+ moduleRef?: string;
423
+ /** sha256 hex digest of the resolved WASM module bytes. */
424
+ moduleDigest?: string;
384
425
  /** GPU configuration this sandbox was created with. Absent means no GPU. */
385
426
  gpus?: GPUOptions;
386
427
  }
@@ -474,6 +515,21 @@ export interface HealthStatus {
474
515
  sshGateway: string;
475
516
  version: string;
476
517
  }
518
+ /**
519
+ * Clone-generation marker for a sandbox. The `generation` token changes every
520
+ * time the sandbox is resumed from a snapshot (i.e. it is a clone). A
521
+ * long-lived process running *inside* the sandbox can poll this and reseed its
522
+ * own userspace PRNGs when the token changes — two clones otherwise share the
523
+ * snapshot's frozen seed state. This is a read-only signal; the SDK cannot
524
+ * reseed an in-guest process from the client side. See the "Randomness in
525
+ * cloned sandboxes" docs page.
526
+ */
527
+ export interface CloneGeneration {
528
+ /** Opaque token that changes on every resume-from-snapshot. */
529
+ generation: string;
530
+ /** Host wall-clock of the last resume, in unix nanoseconds. 0 = never resumed. */
531
+ resumedAt: number;
532
+ }
477
533
  export type BinaryLike = Uint8Array | ArrayBuffer | Blob | string;
478
534
  /**
479
535
  * Lifecycle states reported by a Firecracker rootfs template. See
@@ -535,3 +591,56 @@ export interface CreateTemplateOptions {
535
591
  /** Optional floor for the ext4 image size, in MiB. */
536
592
  minSizeMiB?: number;
537
593
  }
594
+ /** Catalogue lifecycle for POST /v1/wasm-modules rows. */
595
+ export type WasmModuleStatus = "ready" | "failed";
596
+ /**
597
+ * A WASM module catalogue entry. Resolved synchronously on the host and
598
+ * referenced by `moduleRef` when creating `runtime: "wasm"` sandboxes.
599
+ */
600
+ export interface WasmModule {
601
+ id: string;
602
+ moduleRef: string;
603
+ status: WasmModuleStatus;
604
+ moduleSizeBytes?: number;
605
+ digest?: string;
606
+ entrypoint?: string;
607
+ hasWarm: boolean;
608
+ lastError?: string;
609
+ createdAt: string;
610
+ updatedAt: string;
611
+ readyAt?: string;
612
+ }
613
+ export interface CreateWasmModuleOptions {
614
+ /** Optional explicit ID. Empty means the daemon uses the module digest. */
615
+ id?: string;
616
+ /** Module reference resolved on this host (file path, URL, etc.). */
617
+ moduleRef: string;
618
+ /** WASI entry export; defaults to `_start` on the daemon. */
619
+ entrypoint?: string;
620
+ }
621
+ /**
622
+ * Upload a compiled core-wasip1 `.wasm` to the registry. The daemon validates
623
+ * and forwards it under YOUR registry credentials — it never stores the bytes.
624
+ * The returned {@link PushWasmModuleResult.moduleRef} is what you pass as
625
+ * `moduleRef` on a later `create`.
626
+ */
627
+ export interface PushWasmModuleOptions {
628
+ /** Target repository path, e.g. `tenant/my-app`. */
629
+ name: string;
630
+ /** Image tag; defaults to `latest`. */
631
+ tag?: string;
632
+ /** The compiled core-wasip1 module bytes. */
633
+ module: Uint8Array;
634
+ /** Registry login (your AOCR username). */
635
+ registryUsername?: string;
636
+ /** Registry token (your AOCR PAT). Required. */
637
+ registryToken: string;
638
+ }
639
+ export interface PushWasmModuleResult {
640
+ /** The `oci://` ref to pass as `moduleRef` on create. */
641
+ moduleRef: string;
642
+ /** sha256 content digest of the uploaded module. */
643
+ digest: string;
644
+ /** Uploaded size in bytes. */
645
+ sizeBytes: number;
646
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerol-ai/aerolvm-sdk",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "test": "tsc -p tsconfig.test.json --outDir dist-test && node --test dist-test/*.test.js dist-test/internal/*.test.js"
22
22
  },
23
23
  "devDependencies": {
24
- "@types/node": "^25.9.1",
24
+ "@types/node": "^25.9.3",
25
25
  "typescript": "^6.0.3",
26
26
  "tsx": "^4.22.4"
27
27
  }