@theagenticguy/microvms 0.9.0 → 0.11.0

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/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- /* auto-generated by NAPI-RS */
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /* auto-generated by NAPI-RS from bindings/microvms-js/src/. Regenerate with `mise run dts`; `mise run dts:check` fails when this file drifts. */
2
3
  /* eslint-disable */
3
4
 
4
5
  /**
@@ -9,6 +10,15 @@
9
10
  */
10
11
  export declare const __napiBindingTarget: 'native' | 'wasm32-wasi' | 'wasm32-wasip1'
11
12
 
13
+ declare global {
14
+ interface __NapiRsAsyncGenerator<TOwner, T, TReturn, TNext> {
15
+ next(...[value]: [] | [TNext]): globalThis.Promise<globalThis.IteratorResult<T, TReturn | undefined>>
16
+ return(...[value]: [] | [TReturn]): globalThis.Promise<globalThis.IteratorResult<T, TReturn | undefined>>
17
+ throw(exception?: unknown): globalThis.Promise<globalThis.IteratorResult<T, TReturn | undefined>>
18
+ [globalThis.Symbol.asyncIterator](): this
19
+ }
20
+ }
21
+
12
22
  /**
13
23
  * One VM with coding agents in it: the sandbox plus the specs it is built for.
14
24
  *
@@ -51,12 +61,18 @@ export declare class AgentVm {
51
61
  dockerfile(): Promise<string>
52
62
  /**
53
63
  * The image name for these specs and this daemon binary: `agent-vm-<agents>-<hash12>`.
54
- * Content-addressed, so an unchanged binary and spec set name the image a previous run
55
- * built; `findImage` looks it up.
64
+ * Content-addressed, so an unchanged binary, spec set and size name the image a previous
65
+ * run built; `findImage` looks it up, and `ensureImage` builds or reuses it.
56
66
  */
57
67
  imageName(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<string>
58
68
  /** The ARN of an existing image named per `imageName`, or `null` when there is none. */
59
69
  findImage(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<string | null>
70
+ /**
71
+ * Builds or reuses this VM's image, named per `imageName`: resolved at once when ready,
72
+ * waited on while building, deleted and rebuilt when failed, and uploaded to
73
+ * `s3://<s3Bucket>/<s3KeyPrefix>/<name>/artifact.zip` only when a build is needed.
74
+ */
75
+ ensureImage(options: AgentEnsureOptions, size?: SizeClass | undefined | null): Promise<EnsuredImage>
60
76
  /** The artifact bytes to upload to `s3://<bucket>/<imageName>.zip` before `buildImage`. */
61
77
  buildArtifact(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<Buffer>
62
78
  /**
@@ -64,6 +80,11 @@ export declare class AgentVm {
64
80
  * uploaded `buildArtifact`'s bytes. Several minutes, server-side.
65
81
  */
66
82
  buildImage(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<Image>
83
+ /**
84
+ * Hands the VM off to another process; see `Sandbox.detach`. The adopter passes the
85
+ * same agents to `AgentVm.adopt`.
86
+ */
87
+ detach(): Promise<Detached>
67
88
  /**
68
89
  * Launches with egress and waits for the daemon to answer.
69
90
  *
@@ -131,18 +152,54 @@ export declare class BearerToken {
131
152
  toString(): string
132
153
  }
133
154
 
155
+ /**
156
+ * A report's total judged against a budget: core's `Budget::check`, the verdict
157
+ * `microvm cost --max-cost` renders.
158
+ */
159
+ export declare class BudgetVerdict {
160
+ /** The ceiling, as the caller wrote it. */
161
+ get maxUsd(): EstimatedUsd
162
+ /** `"warn"` or `"abort"`: what the caller said a breach does. */
163
+ get onBreach(): string
164
+ /** The total's floor: the whole estimate unless `isLowerBound`. */
165
+ get floor(): EstimatedUsd
166
+ /** Whether the floor is a lower bound, because a line is unpriced. */
167
+ get isLowerBound(): boolean
168
+ /** `"exact"` or `"lower-bound"`. */
169
+ get basis(): string
170
+ /** The phases whose lines are unpriced, sorted. */
171
+ get unpricedPhases(): Array<string>
172
+ /** Whether the floor is over the ceiling. At the ceiling is within it. */
173
+ get breached(): boolean
174
+ /** Whether the caller's judgement refuses the report: breached, under `"abort"`. */
175
+ get aborts(): boolean
176
+ /**
177
+ * How far over the ceiling the floor is, when breached; at least that much for a lower
178
+ * bound.
179
+ */
180
+ get overage(): EstimatedUsd | null
181
+ /** One line for a human, the one `microvm cost --max-cost` prints. */
182
+ render(): string
183
+ /**
184
+ * Core's JSON shape for the verdict, as a JSON **string**: `maxUsd`, `onBreach`, `basis`,
185
+ * `breached`, `overageAtLeastUsd`.
186
+ */
187
+ toJson(): string
188
+ }
189
+
134
190
  /** A timeout for the `ready` or `validate` image-build hook: 1..=3600 seconds. */
135
191
  export declare class BuildHookTimeout {
136
192
  /** A build-family timeout, or a refusal naming both ceilings. */
137
193
  constructor(seconds: number)
138
194
  /** The service ceiling for this family: 3600. */
139
- get maxSecs(): number
195
+ get maxSecs(): 3600
140
196
  get seconds(): number
141
197
  toString(): string
142
198
  }
143
199
 
144
200
  /**
145
- * MicroVM lifecycle by ID: get, list, suspend, resume, terminate, and wait.
201
+ * MicroVM lifecycle by ID (get, list, suspend, resume, terminate, and wait) and image
202
+ * administration (list, delete, versions and their status, builds).
146
203
  *
147
204
  * Holds no lifecycle state, so it checks nothing a `Sandbox` would (STATE-5, STATE-7,
148
205
  * STATE-12). Use it when a process has only an identifier.
@@ -170,6 +227,37 @@ export declare class ControlPlane {
170
227
  * past `timeout` rejects with a timeout.
171
228
  */
172
229
  waitForState(microvmId: string, wanted: Array<string>, options?: WaitForStateOptions | undefined | null): Promise<Microvm>
230
+ /** `ListMicrovmImages`, every page: every image in the account and region. */
231
+ listImages(): Promise<Array<ImageSummary>>
232
+ /**
233
+ * Deletes the image, its extra versions first, retrying while it refuses (an image still
234
+ * `CREATING`, or one a terminating VM holds).
235
+ *
236
+ * Resolves `true` once the service took the deletion and `false` when every attempt
237
+ * failed or `identifier` is not one the service accepts. It doesn't reject, as a
238
+ * teardown's delete shouldn't.
239
+ */
240
+ deleteImage(identifier: string, options?: DeleteImageOptions | undefined | null): Promise<boolean>
241
+ /**
242
+ * `ListMicrovmImageVersions`, every page: each version, its status, and its build
243
+ * configuration.
244
+ */
245
+ listImageVersions(identifier: string): Promise<Array<ImageVersion>>
246
+ /**
247
+ * `UpdateMicrovmImageVersion`: `status` is `"ACTIVE"` or `"INACTIVE"`.
248
+ *
249
+ * `INACTIVE` is the non-destructive retire: `RunMicrovm` refuses the version, running VMs
250
+ * keep running, and the version's readback stays. Resolves with the readback, and rejects
251
+ * when it doesn't carry the status asked for, so a 200 that didn't take isn't a rollback.
252
+ */
253
+ setImageVersionStatus(identifier: string, version: string, status: string): Promise<ImageVersion>
254
+ /**
255
+ * `ListMicrovmImageBuilds` for one version, every page: one build per Graviton
256
+ * generation. Each `buildId` is what `getImageBuild` takes.
257
+ */
258
+ listImageBuilds(identifier: string, version: string): Promise<Array<ImageBuild>>
259
+ /** `GetMicrovmImageBuild`: one build, with the snapshot sizes the listing doesn't carry. */
260
+ getImageBuild(identifier: string, version: string, buildId: string): Promise<ImageBuild>
173
261
  /** The region this plane addresses. */
174
262
  get region(): string
175
263
  }
@@ -197,7 +285,7 @@ export declare class CostReport {
197
285
  *
198
286
  * The string is judged by the core's own [`CostPhase::from_str`], which is where the
199
287
  * closed set lives. This file used to carry its own seven-element table for it, as did
200
- * `microvms-py/src/cost.rs` — two parallel lists over one enum, which would have gone
288
+ * `bindings/microvms-py/src/cost.rs` — two parallel lists over one enum, which would have gone
201
289
  * stale the first time a phase was added and would have disagreed with each other in
202
290
  * whichever direction was edited first.
203
291
  */
@@ -205,7 +293,8 @@ export declare class CostReport {
205
293
  /** Plain text, leading with what the dollars are rather than with the dollars. */
206
294
  render(): string
207
295
  /**
208
- * The `cli.py:688 report_to_dict` shape as a JSON **string**.
296
+ * Core's JSON shape for a report, as a JSON **string**: the one `microvm cost --json`
297
+ * and Python's `to_dict` emit (#255).
209
298
  *
210
299
  * A string for the same reason [`LineItem::to_json`] is: the unpriced line item omits
211
300
  * its `usd` key, which no typed return shape can express.
@@ -213,6 +302,28 @@ export declare class CostReport {
213
302
  toJson(): string
214
303
  }
215
304
 
305
+ /**
306
+ * What another process needs to adopt a VM handed off by `sandbox.detach()`.
307
+ *
308
+ * Pass the fields to `Sandbox.adopt(region, microvmId, endpoint, agentToken, port)`. The
309
+ * token is a method rather than a getter so it is never read by accident, and it is absent
310
+ * from `toString()`; `JSON.stringify` of the instance carries nothing.
311
+ */
312
+ export declare class Detached {
313
+ get microvmId(): string
314
+ get endpoint(): string
315
+ /** The region the VM runs in, ready to pass to `Sandbox.adopt`. */
316
+ get region(): Region
317
+ /** The daemon port the endpoint's proxy tokens are minted for. */
318
+ get port(): number
319
+ /** The VM's bearer credential; store it only privately. */
320
+ agentToken(): string
321
+ /** Every field, token included, for a private encrypted store. */
322
+ toObject(): DetachedObject
323
+ /** The record without its secret. */
324
+ toString(): string
325
+ }
326
+
216
327
  /**
217
328
  * Seconds, plus how we know them.
218
329
  *
@@ -391,6 +502,12 @@ export declare class ExecProcess {
391
502
  /**
392
503
  * A JS async iterator over an exec's output.
393
504
  *
505
+ * Loop over the stream itself: `for await (const event of handle.stream())`. The object
506
+ * `[Symbol.asyncIterator]()` returns has `next`, `return` and `throw` and no
507
+ * `[Symbol.asyncIterator]()` of its own, though its generated type, `__NapiRsAsyncGenerator`,
508
+ * declares one. So `for await` over that object type-checks, then throws a `TypeError`
509
+ * because it isn't async iterable (#262).
510
+ *
394
511
  * See the module docs for why this is a task and a bounded channel. The receiver is behind
395
512
  * a tokio `Mutex` because `AsyncGenerator::next` must answer a `Send + 'static` future, so
396
513
  * the guard is taken *inside* that future rather than borrowed from `&mut self`.
@@ -400,7 +517,10 @@ export declare class ExecProcess {
400
517
  *
401
518
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols
402
519
  */
403
- export declare class ExecStream {}
520
+ export declare class ExecStream {
521
+
522
+ [globalThis.Symbol.asyncIterator](): globalThis.__NapiRsAsyncGenerator<ExecStream, StreamEvent, void, undefined>
523
+ }
404
524
 
405
525
  /**
406
526
  * A running keepalive. Call `stop()` when the work is done; `done()` resolves when it
@@ -437,7 +557,7 @@ export declare class LineItem {
437
557
  get duration(): Duration | null
438
558
  get note(): string
439
559
  /**
440
- * The `cli.py` `_line_to_dict` shape as a JSON **string**.
560
+ * Core's JSON shape for a line item, as a JSON **string**.
441
561
  *
442
562
  * A string rather than an object because the unpriced case must **omit** the `usd` key
443
563
  * entirely, and a `#[napi(object)]` return type cannot express an absent key — an
@@ -476,6 +596,14 @@ export declare class NameRecord {
476
596
  /** Seconds since the epoch when the name was registered. */
477
597
  get at(): number
478
598
  get egressPosture(): string | null
599
+ /**
600
+ * The VM's tunnel identity, when it was launched with `identity: true`; `null` otherwise.
601
+ *
602
+ * Throws when the record carries one half of the pair, or a half that doesn't decode: the
603
+ * record claims a verifiable VM, and reading it as unverifiable would hide that it's
604
+ * broken. A method, like `agentToken()`, because it holds the host's secret half.
605
+ */
606
+ tunnelIdentity(): TunnelIdentity | null
479
607
  /** The record without its secrets. */
480
608
  toString(): string
481
609
  }
@@ -508,6 +636,39 @@ export declare class NameRegistry {
508
636
  * terminate, so no name outlives its VM.
509
637
  */
510
638
  releaseByVm(microvmId: string): Array<string>
639
+ /**
640
+ * Registers a record this registry didn't write, once the VM has answered one
641
+ * authenticated request with the record's token; resolves with whether it refreshed a
642
+ * record of the same VM.
643
+ *
644
+ * `session` must be attached with the record's endpoint and token (`Session.attach` from
645
+ * its fields). A name held by another VM, or by an unreadable file, is refused before any
646
+ * request, and a probe the daemon refuses writes nothing. Core's `names::import`, the rule
647
+ * `microvm attach` applies.
648
+ */
649
+ importRecord(record: NameRecord, session: Session): Promise<boolean>
650
+ }
651
+
652
+ /**
653
+ * A running port-forward. Call `stop()` when done; a garbage-collected handle stops the
654
+ * forward and cuts its open connections.
655
+ */
656
+ export declare class PortForward {
657
+ /** The local address to connect to, `host:port`, with the port the OS picked. */
658
+ get localAddress(): string
659
+ /** Whether the forward is still serving. */
660
+ get running(): boolean
661
+ /**
662
+ * Stops accepting, waits for the connections still open to end, and resolves with the
663
+ * report.
664
+ *
665
+ * With `timeout` (seconds), connections still open after it are cut and listed as
666
+ * `"failed"`. Without it, a client that keeps its connection open keeps this waiting.
667
+ * Callable again, with the same report.
668
+ */
669
+ stop(timeout?: number | undefined | null): Promise<PortForwardReport>
670
+ /** The handle without its credentials. */
671
+ toString(): string
511
672
  }
512
673
 
513
674
  /** The pinned rate table, and everything it says about itself. */
@@ -640,7 +801,7 @@ export declare class RunHookTimeout {
640
801
  /** A run-family timeout, or a refusal naming **both** ceilings. */
641
802
  constructor(seconds: number)
642
803
  /** The service ceiling for this family: 60. */
643
- get maxSecs(): number
804
+ get maxSecs(): 60
644
805
  get seconds(): number
645
806
  toString(): string
646
807
  }
@@ -698,6 +859,20 @@ export declare class Sandbox {
698
859
  static fromName(region: Region, name: string, registry: NameRegistry, port?: number | undefined | null): Promise<Sandbox>
699
860
  /** Whether this sandbox was built by `adopt` rather than by its own launch. */
700
861
  adopted(): Promise<boolean>
862
+ /**
863
+ * Hands the VM off to another process and resolves with what that process adopts it
864
+ * with.
865
+ *
866
+ * For a workflow whose steps run in different processes: the launching step calls this
867
+ * instead of dropping the sandbox (which warns that a live VM was abandoned), persists
868
+ * the record privately, and a later step calls `Sandbox.adopt` with it. The VM keeps
869
+ * running and no AWS call is made. Afterwards this sandbox is inert: `run`,
870
+ * `waitUntilRunning`, `suspend`, `resume`, and `terminate` are refused. Rejects with
871
+ * `ERR_PRECONDITION` without a live VM or when already detached.
872
+ */
873
+ detach(): Promise<Detached>
874
+ /** Whether `detach()` handed this sandbox's VM to another process. */
875
+ isDetached(): Promise<boolean>
701
876
  /** The VM id, once launched. */
702
877
  microvmId(): Promise<string | null>
703
878
  /** The proxy endpoint, once launched. */
@@ -718,6 +893,14 @@ export declare class Sandbox {
718
893
  * window; `GetMicrovm` also returns the service's idle policy.
719
894
  */
720
895
  suspendedWindowSecondsAsync(): Promise<number | null>
896
+ /**
897
+ * The tunnel identity a launch with `identity: true` generated, or that an adopted record
898
+ * carried; `null` otherwise.
899
+ *
900
+ * Holds the host's secret half: pass it to `session.tunnel(...)`, and store it only
901
+ * where the agent token goes.
902
+ */
903
+ tunnelIdentity(): Promise<TunnelIdentity | null>
721
904
  /**
722
905
  * The session, once launched.
723
906
  *
@@ -734,16 +917,48 @@ export declare class Sandbox {
734
917
  * after the caller's artifact upload: a rejection AWS raises costs the upload first.
735
918
  */
736
919
  buildImage(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<Image>
920
+ /**
921
+ * Builds or reuses the content-addressed image for a task: one call from build inputs
922
+ * to a ready image.
923
+ *
924
+ * The name is `<namePrefix>-<hash12>` over the daemon, the Dockerfile, the build
925
+ * context, the base image and the size class. A ready image is returned with
926
+ * `reused: true` and no upload; a running build is waited out; a failed image — or any
927
+ * image under `force` — is deleted and rebuilt; an absent one is uploaded to
928
+ * `s3://<s3Bucket>/<s3KeyPrefix>/<name>/artifact.zip`, created, and waited for. When a
929
+ * concurrent caller creates the name first, this call waits for that build and returns
930
+ * it with `reused: true`. Every local check runs before the first AWS call.
931
+ */
932
+ ensureImage(options: EnsureImageOptions, size?: SizeClass | undefined | null): Promise<EnsuredImage>
737
933
  /**
738
934
  * The artifact bytes to upload to `codeArtifactUri`.
739
935
  *
740
- * The upload is the caller's: S3 is not in the core's dependency set. Takes the same
936
+ * The upload is the caller's on this path (`ensureImage` uploads for itself). Takes the same
741
937
  * options as [`Self::build_image`] so the bytes a caller puts in the bucket are the bytes
742
938
  * the build will receive.
743
939
  */
744
940
  buildArtifact(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<Buffer>
745
941
  /**
746
- * Launches a MicroVM, waits for RUNNING, and resolves with its session.
942
+ * Every local guard `buildImage` runs, with zero calls: rejects with the refusal
943
+ * `buildImage` would, so a caller who uploads its own artifact checks the request before
944
+ * paying for the upload. Takes `buildImage`'s arguments.
945
+ */
946
+ preflight(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<void>
947
+ /**
948
+ * `ListManagedMicrovmImageVersions`, every page: the versions of a managed base, the
949
+ * values `buildImage`'s base-version pin takes.
950
+ *
951
+ * `baseImageArn` is the base's full ARN, such as
952
+ * `arn:aws:lambda:us-east-1:aws:microvm-image:al2023-1`; a bare name is refused.
953
+ */
954
+ managedBaseVersions(baseImageArn: string): Promise<Array<ManagedBaseVersion>>
955
+ /**
956
+ * Launches a MicroVM, waits for RUNNING and for its daemon to answer, and resolves with
957
+ * its session.
958
+ *
959
+ * `readyTimeout` bounds the wait for RUNNING; the wait for the daemon after it is
960
+ * `sessionConstants().defaultReadyTimeoutSeconds`, and a daemon that never answers
961
+ * rejects with `ERR_TIMEOUT` with the VM left RUNNING.
747
962
  *
748
963
  * # What the core refuses here, and this file does not
749
964
  *
@@ -753,7 +968,9 @@ export declare class Sandbox {
753
968
  */
754
969
  run(options?: RunOptions | undefined | null): Promise<Session>
755
970
  /**
756
- * Finishes a `run({ wait: false })`: waits for RUNNING and resolves with the session.
971
+ * Finishes a `run({ wait: false })`: waits for RUNNING and for the daemon to answer, and
972
+ * resolves with the session. `timeout` bounds the wait for RUNNING, as `readyTimeout`
973
+ * does.
757
974
  *
758
975
  * A launch whose `clientToken` adopted an existing, idle-suspended VM resumes it; a
759
976
  * fresh launch that reaches a terminal state first rejects with the service's
@@ -821,6 +1038,16 @@ export declare class Session {
821
1038
  agentToken(): Promise<string>
822
1039
  /** The endpoint this session addresses. */
823
1040
  endpoint(): Promise<string>
1041
+ /**
1042
+ * The launch's egress posture: `"open"`, `"unsealed"`, `"best-effort"`, or `"sealed"`.
1043
+ *
1044
+ * The value the CLI envelope's `egressPosture` reports for the same launch options, and
1045
+ * what `egressPostureFor` answers before the launch. A session that does not hold its
1046
+ * launch options (`Session.direct`, `Session.attach`, an adopted sandbox) reports
1047
+ * `"unsealed"`. Advertise network isolation only for `"sealed"`. Async like `endpoint()`,
1048
+ * because a sandbox-held session is read under the sandbox's lock.
1049
+ */
1050
+ egressPosture(): Promise<string>
824
1051
  /** The port the proxy token is scoped to. */
825
1052
  port(): Promise<number>
826
1053
  /** Unauthenticated liveness. */
@@ -875,6 +1102,22 @@ export declare class Session {
875
1102
  exec(execId: string): Promise<ExecHandle>
876
1103
  /** Start, wait, ack. The one-shot shape, for when output is all you want. */
877
1104
  runSync(command: string | Array<string>, options?: ExecOptions | undefined | null): Promise<ExecResult>
1105
+ /**
1106
+ * Start, stream, and collect one command: exactly one `ExecResult` back (BIND-6..10).
1107
+ *
1108
+ * With `onOutput`, each output chunk (a `StreamEvent` of kind `"output"`) is handed to it
1109
+ * as it arrives. The result then comes from the ack that follows the terminal `exit`
1110
+ * event, or, when the stream ends without one, from a wait and ack. When `timeoutSec +
1111
+ * clientGraceSec` passes first (or, with no `timeoutSec`, the VM's maximum lifetime), the
1112
+ * process group is killed and the exec waited for and acked within `clientGraceSec` once
1113
+ * more; if that fails too the result is synthesized with `posixExitCode` 124.
1114
+ *
1115
+ * A throwing `onOutput` stops delivery; the exec is still waited for and acked so nothing
1116
+ * is left behind, and then the promise rejects with the callback's message. `shell: true`
1117
+ * runs `/bin/sh -c`; for bash semantics pass `shell: "bash"` with a script string, or
1118
+ * `["bash", "-c", script]` for a daemon that predates named shells.
1119
+ */
1120
+ runToCompletion(command: string | string[], options?: CompletionRequest | undefined | null, onOutput?: ((chunk: StreamEvent) => unknown) | undefined | null): Promise<ExecResult>
878
1121
  /** Signals an exec's whole process group. Returns whether anything was signalled. */
879
1122
  kill(execId: string): Promise<boolean>
880
1123
  /**
@@ -890,8 +1133,39 @@ export declare class Session {
890
1133
  * the daemon's shape — a number here would be ambiguous between 0o755 and 755.
891
1134
  */
892
1135
  uploadFile(path: string, data: Uint8Array, mode?: string | undefined | null): Promise<void>
893
- /** Reads one file. */
894
- downloadFile(path: string): Promise<Buffer>
1136
+ /**
1137
+ * Reads one file, or lines `startLine` through `endLine` of it.
1138
+ *
1139
+ * The range is 1-based and inclusive, and the daemon slices the file, so reading lines 40
1140
+ * to 60 of a large log reads those lines alone. Either bound may be left out (line 1,
1141
+ * through EOF), and an `endLine` past the last line reads through EOF. Line 0 and an end
1142
+ * before the start reject with `ERR_INVALID_ARG` before any request.
1143
+ */
1144
+ downloadFile(path: string, options?: DownloadFileOptions | undefined | null): Promise<Buffer>
1145
+ /**
1146
+ * Brings the files of a directory in the VM back under `localDir`: the regular files
1147
+ * `globs` select, and nothing else.
1148
+ *
1149
+ * The daemon packs `remote`, and the archive describes the VM's filesystem, where
1150
+ * untrusted work runs, so core writes only regular-file members that match a glob, never
1151
+ * under `.git` whatever the globs say, and never outside `localDir`. A symlink, a special
1152
+ * file or a `../` member is skipped, not refused. `['**']` brings every regular file back.
1153
+ * Resolves to what was written; a local directory that can't be written to rejects with
1154
+ * `ERR_INVALID_ARG`.
1155
+ */
1156
+ downloadDir(remote: string, localDir: string, globs: Array<string>): Promise<Array<DownloadedFile>>
1157
+ /**
1158
+ * Syncs `localDir` into the VM's `/workspace` once, uploading only what changed.
1159
+ *
1160
+ * Core's one pass, `microvm sync`'s: the local tree is hashed and diffed against the
1161
+ * manifest the last sync left in the VM, the changed members travel as one archive, the
1162
+ * paths gone locally are removed in the VM with one `rm` whose deadline is
1163
+ * `deleteTimeout` seconds (core's default when omitted), and the manifest is rewritten.
1164
+ * `full: true` ignores the manifest and uploads everything. `.git`, `target`,
1165
+ * `node_modules` and `.venv` never travel. A tree over the daemon's budgets rejects with
1166
+ * `ERR_INVALID_ARG` before anything is sent.
1167
+ */
1168
+ syncDir(localDir: string, options?: SyncDirOptions | undefined | null): Promise<SyncReport>
895
1169
  /** Whether a path exists, distinguishing absence from every other refusal. */
896
1170
  fileExists(path: string): Promise<boolean>
897
1171
  /**
@@ -943,6 +1217,28 @@ export declare class Session {
943
1217
  * The middle string **contains the credential**. Same rule as `connectHeaders`.
944
1218
  */
945
1219
  connectSubprotocols(port: number): Promise<Array<string> | null>
1220
+ /**
1221
+ * Serves a local TCP port as a tunnel to `guestPort` in the VM, on a background task, and
1222
+ * resolves at once with its handle: `microvm tunnel`'s loop.
1223
+ *
1224
+ * Each local connection gets a WebSocket of its own through the endpoint proxy, and a
1225
+ * connection the daemon refuses is listed in the report while the tunnel keeps serving.
1226
+ * With `verifyIdentity` (a `TunnelIdentity`, such as `sandbox.tunnelIdentity()`), each
1227
+ * connection first proves the far end is the daemon of the VM that identity was launched
1228
+ * with, and a connection that can't is refused. A separate parameter rather than an
1229
+ * option, for the reason `buildImage`'s guarded values are: a class in an options object
1230
+ * can't cross an async call.
1231
+ */
1232
+ tunnel(guestPort: number, options?: ServeOptions | undefined | null, verifyIdentity?: TunnelIdentity | undefined | null): Promise<Tunnel>
1233
+ /**
1234
+ * Serves a local port as an HTTP and WebSocket forward to `guestPort` in the VM, on a
1235
+ * background task, and resolves at once with its handle: `microvm port-forward`'s loop.
1236
+ *
1237
+ * Connections are served at once rather than one after another, so a slow request
1238
+ * doesn't hold the next. A request the endpoint proxy refuses is listed in the report
1239
+ * with its status while the forward keeps serving.
1240
+ */
1241
+ portForward(guestPort: number, options?: ServeOptions | undefined | null): Promise<PortForward>
946
1242
  /**
947
1243
  * How many proxy tokens this session has minted, or `null` for a direct session.
948
1244
  *
@@ -969,6 +1265,16 @@ export declare class SizeClass {
969
1265
  * readings differ in both memory and rate, and neither has been measured.
970
1266
  */
971
1267
  static fromBaselineMib(mib: number): SizeClass
1268
+ /**
1269
+ * The smallest class whose baseline covers a resource request (BIND-14).
1270
+ *
1271
+ * `cpus` in vCPUs and `memoryMib` in MiB, each a request; `undefined` or zero is no
1272
+ * requirement on that axis, and with none on either the answer is `defaultClass()`.
1273
+ * Chosen by baseline, the billed and always-present figure. Throws `ERR_INVALID_ARG`
1274
+ * naming the largest class when no class covers the request, or for a CPU figure that is
1275
+ * not a finite non-negative number.
1276
+ */
1277
+ static fromRequest(cpus?: number | undefined | null, memoryMib?: number | undefined | null): SizeClass
972
1278
  /**
973
1279
  * The platform's default, 2048 MiB. Not the smallest — a 0.5 GB baseline fixes the
974
1280
  * guest's always-present ceiling at 2 GB, which OOM-kills a real test suite, and the
@@ -1006,6 +1312,50 @@ export declare class Total {
1006
1312
  toString(): string
1007
1313
  }
1008
1314
 
1315
+ /**
1316
+ * A running tunnel. Call `stop()` when done; a garbage-collected handle stops the tunnel and
1317
+ * cuts its open connections.
1318
+ */
1319
+ export declare class Tunnel {
1320
+ /** The local address to connect to, `host:port`, with the port the OS picked. */
1321
+ get localAddress(): string
1322
+ /** Whether the tunnel is still serving. */
1323
+ get running(): boolean
1324
+ /**
1325
+ * Stops accepting, waits for the connections still open to end, and resolves with the
1326
+ * report.
1327
+ *
1328
+ * With `timeout` (seconds), connections still open after it are cut and listed as
1329
+ * `"failed"`. Without it, a client that keeps its connection open keeps this waiting.
1330
+ * Callable again, with the same report.
1331
+ */
1332
+ stop(timeout?: number | undefined | null): Promise<TunnelReport>
1333
+ /** The handle without its credentials. */
1334
+ toString(): string
1335
+ }
1336
+
1337
+ /**
1338
+ * What a launcher keeps to verify its VM: the host's secret seed and the VM's public key,
1339
+ * both base64.
1340
+ *
1341
+ * From `sandbox.tunnelIdentity()` after a `run({ identity: true })`, from a `NameRecord`, or
1342
+ * built from the two values `microvm run --identity` prints. Holds a secret: `hostSeed()` is a
1343
+ * method rather than a getter so it's never read by accident, and `toString()` leaves it out.
1344
+ */
1345
+ export declare class TunnelIdentity {
1346
+ /**
1347
+ * Rebuilds the pair from its base64 spellings. Refuses a value that doesn't decode, or a
1348
+ * seed or key of the wrong length.
1349
+ */
1350
+ constructor(hostSeed: string, vmPublicKey: string)
1351
+ /** The host's secret half, base64. Store only privately. */
1352
+ hostSeed(): string
1353
+ /** The VM's public key, base64: the pin. Safe to print and compare. */
1354
+ get vmPublicKey(): string
1355
+ /** The pair without its secret. */
1356
+ toString(): string
1357
+ }
1358
+
1009
1359
  /**
1010
1360
  * A quantity we can measure but cannot price, because no rate is published.
1011
1361
  *
@@ -1020,6 +1370,21 @@ export declare class Unpriced {
1020
1370
  /** The layer's fixed values as JSON, for a caller that wants to reason about the guest. */
1021
1371
  export declare function agentConstants(): string
1022
1372
 
1373
+ /**
1374
+ * What `ensureImage` builds or reuses from: the daemon binary, the build role, and where
1375
+ * the artifact goes.
1376
+ */
1377
+ export interface AgentEnsureOptions {
1378
+ /** The daemon binary's bytes, zipped into the artifact. */
1379
+ binary: Uint8Array
1380
+ /** The build role, which must read the bucket and grant logs on `/aws/lambda-microvms/*`. */
1381
+ buildRoleArn: string
1382
+ /** The bucket the artifact is uploaded to, in the VM's region. */
1383
+ s3Bucket: string
1384
+ /** A key prefix inside the bucket, or absent for the bucket root. */
1385
+ s3KeyPrefix?: string
1386
+ }
1387
+
1023
1388
  /** What an agent image is derived from: the daemon binary and the build role. */
1024
1389
  export interface AgentImageOptions {
1025
1390
  /** The daemon binary's bytes, zipped into the artifact. */
@@ -1035,7 +1400,10 @@ export interface AgentImageOptions {
1035
1400
 
1036
1401
  /** Everything a launch takes beyond what the layer fixes (egress on, the image). */
1037
1402
  export interface AgentLaunchOptions {
1038
- /** The image ARN from `findImage` or `buildImage`. */
1403
+ /**
1404
+ * The image ARN from `findImage` or `buildImage`, or a bare image name, which the core
1405
+ * resolves with one `ListMicrovmImages` read.
1406
+ */
1039
1407
  imageIdentifier: string
1040
1408
  /** The execution role. Optional in the model; every real launch needs one. */
1041
1409
  executionRoleArn?: string
@@ -1060,6 +1428,15 @@ export interface AgentLaunchOptions {
1060
1428
  logStream?: string
1061
1429
  /** Turns per-VM logging off. Cannot be combined with `logGroup` or `logStream`. */
1062
1430
  disableLogging?: boolean
1431
+ /** The base environment for every exec in the VM. See `RunOptions.launchEnv`. */
1432
+ launchEnv?: Record<string, string>
1433
+ /** Launch shell-capable. See `RunOptions.shell`. */
1434
+ shell?: boolean
1435
+ /**
1436
+ * How long to wait for RUNNING. The wait for the daemon after it is the core's
1437
+ * `defaultReadyTimeoutSeconds`.
1438
+ */
1439
+ readyTimeout?: number
1063
1440
  }
1064
1441
 
1065
1442
  /** A resolved spec: the model it will use and the command `prompt` runs. */
@@ -1087,6 +1464,16 @@ export interface AgentSpecInput {
1087
1464
  cliVersion?: string
1088
1465
  }
1089
1466
 
1467
+ /**
1468
+ * The base a task Dockerfile pairs with: the managed base's `name`, so `baseImageArn` is
1469
+ * unchanged, and the Dockerfile's first `FROM` as `dockerRef`, digest pin included.
1470
+ *
1471
+ * `buildImage` refuses a Dockerfile whose first `FROM` is not the base's `dockerRef`; a base
1472
+ * derived from that Dockerfile passes by construction. Throws `ERR_INVALID_ARG` for a
1473
+ * Dockerfile with no `FROM`.
1474
+ */
1475
+ export declare function baseImageFromDockerfile(dockerfile: string): BaseImageInput
1476
+
1090
1477
  /**
1091
1478
  * The platform's managed base image, paired with the Dockerfile `FROM` it goes with.
1092
1479
  *
@@ -1129,15 +1516,23 @@ export interface BuildImageOptions {
1129
1516
  /** The daemon binary's bytes, zipped into the artifact. */
1130
1517
  binary: Uint8Array
1131
1518
  /**
1132
- * Where the artifact is uploaded to. This client does not upload — S3 is not in the
1133
- * core's dependency set — so the caller puts the bytes there and passes the URI.
1519
+ * Where the artifact is uploaded to. `buildImage` does not upload: the caller puts the
1520
+ * bytes there and passes the URI. `ensureImage` is the path that uploads for itself.
1134
1521
  */
1135
1522
  codeArtifactUri: string
1136
1523
  /** The build role, which must grant logs on `/aws/lambda-microvms/*`. */
1137
1524
  buildRoleArn: string
1138
1525
  baseImage?: BaseImageInput
1526
+ /** Pins the managed base to one version, a value `managedBaseVersions` lists. */
1527
+ baseImageVersion?: string
1139
1528
  /** A caller-supplied Dockerfile, checked against the base image's `FROM`. */
1140
1529
  dockerfile?: string
1530
+ /**
1531
+ * A directory whose one manifest+lockfile pair bakes an environment layer, by the rule
1532
+ * the CLI's `--project` uses. A directory without exactly one pair is refused before any
1533
+ * call.
1534
+ */
1535
+ projectDir?: string
1141
1536
  /** Whether to repair guest identity. A boolean, not a capability list — see above. */
1142
1537
  repairGuestIdentity?: boolean
1143
1538
  /**
@@ -1166,9 +1561,70 @@ export interface BuildImageOptions {
1166
1561
  /** Why the image build has no price, as the reason that lands on the line item. */
1167
1562
  export declare function buildUnpricedReason(): string
1168
1563
 
1564
+ /**
1565
+ * Judges `report`'s total against a ceiling of `maxUsd` (a decimal string, such as `"1.50"`),
1566
+ * with `onBreach` (`"warn"` or `"abort"`) saying what a breach does.
1567
+ *
1568
+ * `onBreach` has no default, because a breach of a lower-bound total has already been exceeded
1569
+ * by an unknown margin, and whether that warns or refuses is the caller's call. Core's
1570
+ * `Budget::check`, the gate `microvm cost --max-cost` applies.
1571
+ */
1572
+ export declare function checkBudget(report: CostReport, maxUsd: string, onBreach: string): BudgetVerdict
1573
+
1169
1574
  /** The warm-pool argument, with its own counter-argument attached. */
1170
1575
  export declare function compareResidency(size: SizeClass, holdSeconds: number, cycles?: number | undefined | null, rates?: RateTable | undefined | null): ResidencyComparison
1171
1576
 
1577
+ /**
1578
+ * How `runToCompletion` should start and collect a command.
1579
+ *
1580
+ * The `ExecOptions` a completed run can use (no `stdin`, which nothing would write, and no
1581
+ * `timeout`, which `clientGraceSec` replaces), plus the client grace.
1582
+ */
1583
+ export interface CompletionRequest {
1584
+ /**
1585
+ * `true` runs a single script string under `/bin/sh -c`; a string such as `"bash"` runs
1586
+ * it under that shell, resolved by the daemon in the guest. See `ExecOptions.shell`.
1587
+ */
1588
+ shell?: boolean | string
1589
+ cwd?: string
1590
+ env?: Record<string, string>
1591
+ /** A numeric uid, or a name the daemon resolves in the guest. See `ExecOptions.user`. */
1592
+ user?: number | string
1593
+ /** A numeric gid, or a name the daemon resolves in the guest. */
1594
+ group?: number | string
1595
+ /**
1596
+ * The daemon's own kill deadline for the child. The client deadline is this plus
1597
+ * `clientGraceSec`.
1598
+ */
1599
+ timeoutSec?: number
1600
+ /** The idempotency key. Omitted, one is minted. */
1601
+ execId?: string
1602
+ /**
1603
+ * Signal the whole process group once the command's own child exits. See
1604
+ * `ExecOptions.reapGroupOnExit`.
1605
+ */
1606
+ reapGroupOnExit?: boolean
1607
+ /** Start the child's environment from the image's `ENV`. See `ExecOptions.inheritImageEnv`. */
1608
+ inheritImageEnv?: boolean
1609
+ /**
1610
+ * How long past `timeoutSec` the client waits before it kills, and how long it then
1611
+ * waits for the killed exec's result. Defaults to the core's 60 seconds.
1612
+ */
1613
+ clientGraceSec?: number
1614
+ }
1615
+
1616
+ /** A connection that didn't end clean. */
1617
+ export interface ConnectionEnd {
1618
+ /** The local client's address, `host:port`. */
1619
+ peer: string
1620
+ /** `"refused"`, `"truncated"`, `"unproven"`, or `"failed"`. */
1621
+ kind: string
1622
+ /** The close code or the HTTP status, when the end carried one. */
1623
+ code?: number
1624
+ /** The daemon's reason, the forwarder's explanation, or the error. */
1625
+ detail: string
1626
+ }
1627
+
1172
1628
  /**
1173
1629
  * The core crate's version, for a `doctor` or `manifest` command to report.
1174
1630
  *
@@ -1190,6 +1646,105 @@ export declare function costConstants(): string
1190
1646
  /** The managed base every `docs/PLATFORM.md` measurement from 2026-08-06 onward used. */
1191
1647
  export declare function defaultBaseImage(): BaseImageInput
1192
1648
 
1649
+ /** How `deleteImage` retries while the image refuses. */
1650
+ export interface DeleteImageOptions {
1651
+ /** Attempts before giving up. Default: the core's teardown figure. */
1652
+ attempts?: number
1653
+ /** Seconds between attempts. Default: the core's teardown figure. */
1654
+ backoff?: number
1655
+ }
1656
+
1657
+ /** `Detached` as a plain object, token included, for a private store. */
1658
+ export interface DetachedObject {
1659
+ microvmId: string
1660
+ endpoint: string
1661
+ region: string
1662
+ port: number
1663
+ agentToken: string
1664
+ }
1665
+
1666
+ /** One file `downloadDir` wrote. */
1667
+ export interface DownloadedFile {
1668
+ /** The file's path under the local directory, as the archive named it. */
1669
+ path: string
1670
+ /** The file's size in bytes. */
1671
+ size: number
1672
+ }
1673
+
1674
+ /** The line range `downloadFile` reads, 1-based and inclusive. Both absent reads the file. */
1675
+ export interface DownloadFileOptions {
1676
+ /** The first line to read. Absent means line 1. */
1677
+ startLine?: number
1678
+ /** The last line to read. Absent, or past the last line, means through EOF. */
1679
+ endLine?: number
1680
+ }
1681
+
1682
+ /**
1683
+ * The egress posture `sandbox.run` with these options would report, without launching.
1684
+ *
1685
+ * One of `"open"`, `"unsealed"`, `"best-effort"`, or `"sealed"`: the value the launched
1686
+ * session's `egressPosture()` and the CLI envelope's `egressPosture` carry. Throws the launch's
1687
+ * own `ERR_INVALID_ARG` for options it would refuse. No AWS call and no credentials, so a
1688
+ * harness can decide before a build whether a no-network task is satisfiable.
1689
+ *
1690
+ * Only `"sealed"` is network isolation, and no option answers it: isolation needs a VPC
1691
+ * egress connector and separately verified VPC routing without an internet gateway or NAT
1692
+ * gateway. Omitting `egress` is `"unsealed"`; `denyEgress` is `"best-effort"`. Without a
1693
+ * `region`, each connector ARN is checked against the region it names.
1694
+ */
1695
+ export declare function egressPostureFor(egress?: boolean | undefined | null, connectors?: Array<string> | undefined | null, denyEgress?: boolean | undefined | null, region?: Region | undefined | null): string
1696
+
1697
+ /** What `ensureImage` returns: the ready image and how this call got it. */
1698
+ export interface EnsuredImage {
1699
+ /** The ready image; pass `image.identifier` to `run`. */
1700
+ image: Image
1701
+ /**
1702
+ * True when this call's own create did not build the image: it was ready, a build
1703
+ * already running was waited out, or a concurrent caller won the create race.
1704
+ */
1705
+ reused: boolean
1706
+ /** `s3://<bucket>/<prefix>/<name>/artifact.zip`, whether or not this call uploaded it. */
1707
+ artifactUri: string
1708
+ /** Whether this call uploaded the artifact. */
1709
+ uploaded: boolean
1710
+ /** What reading the build context skipped, one line each. */
1711
+ warnings: Array<string>
1712
+ }
1713
+
1714
+ /**
1715
+ * Everything `ensureImage` needs besides the size class.
1716
+ *
1717
+ * `baseImage` defaults to `baseImageFromDockerfile(dockerfile)`; `waitTimeoutSeconds` is
1718
+ * the build wait, 45 minutes by default. `contextDir` is read as `docker build` reads a
1719
+ * context: `Dockerfile.dockerignore`, else `.dockerignore`, is honoured, and symlinks are
1720
+ * skipped with a line in the result's `warnings`.
1721
+ */
1722
+ export interface EnsureImageOptions {
1723
+ /** The image name's stem; the name is `<namePrefix>-<hash12>`. */
1724
+ namePrefix: string
1725
+ /** The daemon binary's bytes. */
1726
+ binary: Uint8Array
1727
+ /** The Dockerfile, usually `wrapDockerfile(task)`. */
1728
+ dockerfile: string
1729
+ /** The directory the Dockerfile's `COPY` lines read, or omitted for none. */
1730
+ contextDir?: string
1731
+ /** The artifact bucket, in the sandbox's region. */
1732
+ s3Bucket: string
1733
+ /** A key prefix inside the bucket, or omitted for the bucket root. */
1734
+ s3KeyPrefix?: string
1735
+ /** The build role. */
1736
+ buildRoleArn: string
1737
+ baseImage?: BaseImageInput
1738
+ /** `buildImage`'s `baseImageVersion`; it joins the name's hash. */
1739
+ baseImageVersion?: string
1740
+ /** `buildImage`'s `projectDir`; the pair joins the name's hash. */
1741
+ projectDir?: string
1742
+ /** Delete what exists under the name and build afresh. */
1743
+ force?: boolean
1744
+ tags?: Record<string, string>
1745
+ waitTimeoutSeconds?: number
1746
+ }
1747
+
1193
1748
  /**
1194
1749
  * Every `ERR_*` code this library can raise, for a caller building an exhaustive switch.
1195
1750
  *
@@ -1209,12 +1764,23 @@ export declare function estimateRun(size: SizeClass, options?: PlanUsageOptions
1209
1764
 
1210
1765
  /** How an exec should be started. Every field optional; the defaults are the daemon's. */
1211
1766
  export interface ExecOptions {
1212
- /** A single script string rather than an argv. Requires `shell: true`. */
1213
- shell?: boolean
1767
+ /**
1768
+ * `true` runs a single script string under `/bin/sh -c`; a string such as `"bash"`
1769
+ * runs it under that shell, resolved by the daemon in the guest, and a shell the guest
1770
+ * does not have is refused (`unknown_shell`) before anything starts.
1771
+ */
1772
+ shell?: boolean | string
1214
1773
  cwd?: string
1215
1774
  env?: Record<string, string>
1216
- user?: number
1217
- group?: number
1775
+ /**
1776
+ * A numeric uid, or a name the daemon resolves against the guest's `/etc/passwd`. An
1777
+ * unknown name is refused (`unknown_user`) before anything starts. A user with a passwd
1778
+ * row gets `HOME`, `USER` and `LOGNAME` from it, beneath the launch environment and
1779
+ * `env`.
1780
+ */
1781
+ user?: number | string
1782
+ /** A numeric gid, or a name the daemon resolves against the guest's `/etc/group`. */
1783
+ group?: number | string
1218
1784
  /** The daemon's own kill deadline for the child, distinct from a client-side `wait`. */
1219
1785
  timeoutSec?: number
1220
1786
  /** Whether to open a stdin pipe. Writing without this is a 409. */
@@ -1233,6 +1799,12 @@ export interface ExecOptions {
1233
1799
  * guarantee for callers who rely on it.
1234
1800
  */
1235
1801
  reapGroupOnExit?: boolean
1802
+ /**
1803
+ * Start the child's environment from the image's `ENV` (minus `AGENTD_*`, never the
1804
+ * token), beneath everything else (AGENTD-11). Off by default, which keeps the child's environment
1805
+ * exactly the launch environment plus `env`.
1806
+ */
1807
+ inheritImageEnv?: boolean
1236
1808
  }
1237
1809
 
1238
1810
  /**
@@ -1271,6 +1843,22 @@ export interface ExecResult {
1271
1843
  * exec, since neither is a success.
1272
1844
  */
1273
1845
  ok: boolean
1846
+ /**
1847
+ * The exit code a POSIX shell would report (BIND-6): 124 when a deadline ended the
1848
+ * command (the daemon's, or `runToCompletion`'s client deadline), 128 plus the signal
1849
+ * for any other signal death, otherwise `exitCode`. `null` only for a running exec.
1850
+ */
1851
+ posixExitCode?: number
1852
+ /**
1853
+ * Human-readable annotations, one per condition that changes how the output reads
1854
+ * (BIND-7). Empty for a clean result; append them to stderr as they are.
1855
+ */
1856
+ notes: Array<string>
1857
+ /**
1858
+ * True when `runToCompletion` synthesized this result because nothing came back after
1859
+ * its client-deadline kill (BIND-10): `posixExitCode` is 124 and the output is unknown.
1860
+ */
1861
+ synthesized: boolean
1274
1862
  }
1275
1863
 
1276
1864
  /**
@@ -1372,6 +1960,12 @@ export interface Health {
1372
1960
  * VM's identity.
1373
1961
  */
1374
1962
  identitySteps: Array<IdentityStep>
1963
+ /**
1964
+ * How many variables the daemon's image-environment snapshot holds, or `null` when it
1965
+ * holds none. `null` is also what a daemon built before `inheritImageEnv` reports, and
1966
+ * such a daemon ignores that option. The values are never reported.
1967
+ */
1968
+ imageEnvKeys?: number
1375
1969
  }
1376
1970
 
1377
1971
  /** One lifecycle-hook invocation, as the daemon observed it. */
@@ -1437,6 +2031,92 @@ export interface Image {
1437
2031
  logStream?: string
1438
2032
  }
1439
2033
 
2034
+ /**
2035
+ * One build of an image version: one per Graviton generation, so a version's builds differ
2036
+ * in `chipsetGeneration`. `getImageBuild` adds the snapshot sizes the listing lacks.
2037
+ */
2038
+ export interface ImageBuild {
2039
+ imageArn: string
2040
+ imageVersion: string
2041
+ /** What `getImageBuild` takes, and nothing else in the API mints one. */
2042
+ buildId: string
2043
+ /** `buildState`, as the service spells it. */
2044
+ buildState: string
2045
+ architecture: string
2046
+ chipset: string
2047
+ chipsetGeneration: string
2048
+ /** Unix seconds. */
2049
+ createdAt: number
2050
+ /**
2051
+ * Why the build is in this state, when the service said: where a failed build's reason
2052
+ * lives.
2053
+ */
2054
+ stateReason?: string
2055
+ /**
2056
+ * `snapshotBuild.memorySnapshotSizeInBytes`, from `getImageBuild` only, and only when the
2057
+ * service reported it.
2058
+ */
2059
+ memorySnapshotSizeInBytes?: number
2060
+ /** `snapshotBuild.codeInstallSizeInBytes`, from `getImageBuild` only. */
2061
+ codeInstallSizeInBytes?: number
2062
+ /** `snapshotBuild.diskSnapshotSizeInBytes`, from `getImageBuild` only. */
2063
+ diskSnapshotSizeInBytes?: number
2064
+ }
2065
+
2066
+ /** One `ListMicrovmImages` item: an image's ARN, name and state. */
2067
+ export interface ImageSummary {
2068
+ imageArn: string
2069
+ name: string
2070
+ /** As the service spells it, such as `"CREATING"` or `"CREATED"`. */
2071
+ state: string
2072
+ }
2073
+
2074
+ /**
2075
+ * One image version as `ListMicrovmImageVersions` or `UpdateMicrovmImageVersion` reads it
2076
+ * back: its build state, whether `RunMicrovm` launches it, and what it was built with.
2077
+ */
2078
+ export interface ImageVersion {
2079
+ imageArn: string
2080
+ imageVersion: string
2081
+ /** The version's build state, as the service spells it. */
2082
+ state: string
2083
+ /**
2084
+ * `"ACTIVE"` (`RunMicrovm` launches it) or `"INACTIVE"` (it refuses; running VMs keep
2085
+ * running).
2086
+ */
2087
+ status: string
2088
+ /** Whether `RunMicrovm` launches this version. */
2089
+ isActive: boolean
2090
+ /**
2091
+ * Why the version is in this state, when the service said. A failed build's reason is on
2092
+ * its build (`listImageBuilds`), and this one is usually absent.
2093
+ */
2094
+ stateReason?: string
2095
+ /** Unix seconds. */
2096
+ createdAt: number
2097
+ /** Unix seconds, when the service reported it. */
2098
+ updatedAt?: number
2099
+ baseImageArn: string
2100
+ /**
2101
+ * The base version the build used, as the service spells it (`"1.0"` where the managed
2102
+ * base lists `"1"`). A record of the build, not a value to pass back as a pin.
2103
+ */
2104
+ baseImageVersion?: string
2105
+ buildRoleArn: string
2106
+ /** `codeArtifact.uri`: the artifact the version was built from. */
2107
+ codeArtifactUri: string
2108
+ description?: string
2109
+ /**
2110
+ * `resources[0].minimumMemoryInMiB`, the list's one member: the size class the version
2111
+ * was built for, and the only place a built image reports it.
2112
+ */
2113
+ minimumMemoryMib?: number
2114
+ egressNetworkConnectors?: Array<string>
2115
+ additionalOsCapabilities?: Array<string>
2116
+ environmentVariables?: Record<string, string>
2117
+ tags?: Record<string, string>
2118
+ }
2119
+
1440
2120
  /**
1441
2121
  * Installs Bedrock access for `agents` into a running VM over `session`.
1442
2122
  *
@@ -1455,6 +2135,18 @@ export declare function installAgentAccess(session: Session, agents: Array<Agent
1455
2135
  */
1456
2136
  export declare function installedAgents(session: Session): Promise<Array<AgentSpec>>
1457
2137
 
2138
+ /**
2139
+ * Whether retrying the identical call could plausibly succeed, for an error this library raised.
2140
+ *
2141
+ * The TypeScript spelling of Python's `.retryable`, read off the chain every error here
2142
+ * carries: `err.cause.message` is the `ERR_*` code, and core answers for its kind. A
2143
+ * transient condition (a refused connection, a mint failure, a daemon not yet bootstrapped)
2144
+ * is `true`; a full disk, a credential, or a refused argument is `false`. Anything that
2145
+ * isn't a library error (no cause, or a cause whose message is no `ERR_*` code) is `false`,
2146
+ * because nothing says a retry would land differently.
2147
+ */
2148
+ export declare function isRetryable(error: unknown): boolean
2149
+
1458
2150
  /** The options bag for `keepAwake`. */
1459
2151
  export interface KeepAwakeOptions {
1460
2152
  /** Seconds between polls. Default: a third of the idle window, at most 20. */
@@ -1468,6 +2160,11 @@ export interface KeepAwakeOptions {
1468
2160
  * platform minimum of 60 is assumed. The interval may be at most half of it.
1469
2161
  */
1470
2162
  idleWindowSec?: number
2163
+ /**
2164
+ * How many retryable poll failures in a row are retried, a second apart, before the
2165
+ * keepalive ends with the error. Default: the core's `DEFAULT_TOLERATED_ERRORS`.
2166
+ */
2167
+ toleratedErrors?: number
1471
2168
  }
1472
2169
 
1473
2170
  /** What a finished keepalive did. */
@@ -1488,6 +2185,45 @@ export interface ListMicrovmsOptions {
1488
2185
  imageVersion?: string
1489
2186
  }
1490
2187
 
2188
+ /**
2189
+ * The three guarded values a build takes, as separate parameters rather than fields.
2190
+ *
2191
+ * # Why they are not in [`BuildImageOptions`]
2192
+ *
2193
+ * Measured, not preferred. A `#[napi(object)]` field holding a class instance must be a
2194
+ * `ClassInstance<'a, T>`, which carries raw `napi_value`/`napi_env` pointers and is therefore
2195
+ * **not `Send`** — and napi's async path requires `Future: Send`. So an options object with a
2196
+ * `size: SizeClass` field cannot be a parameter of an `async fn`, which
2197
+ * `Sandbox.buildImage` has to be. The compiler said so in as many words:
2198
+ * `future created by async block is not Send ... has type BuildImageOptions<'_> which is not
2199
+ * Send`.
2200
+ *
2201
+ * A *reference* parameter — `Option<&SizeClass>` — has no such problem, because napi
2202
+ * dereferences it before the future is built. So the guarded types move out of the bag and
2203
+ * into the signature, which loses the keyword-argument look and keeps every closure:
2204
+ *
2205
+ * * `size` still refuses an off-table baseline, because the only way to have a `SizeClass` is
2206
+ * `SizeClass.fromBaselineMib` or `SizeClass.defaultClass` (TRAP-10).
2207
+ * * `runHookTimeout` and `buildHookTimeout` are still two distinct classes, so they still
2208
+ * cannot be transposed — which was the whole reason they are types (BIND-2).
2209
+ *
2210
+ * A caller writes `sandbox.buildImage(opts, size, runTimeout, buildTimeout)` with the last
2211
+ * three optional.
2212
+ * One version of a managed base image, from `ListManagedMicrovmImageVersions`.
2213
+ */
2214
+ export interface ManagedBaseVersion {
2215
+ imageArn: string
2216
+ /**
2217
+ * A bare integer for a managed base (`"0"`, `"1"`), where a custom image's versions read
2218
+ * `"1.0"`: the value `buildImage`'s pin takes, not one to compare with a build's readback.
2219
+ */
2220
+ imageVersion: string
2221
+ /** Unix seconds. */
2222
+ createdAt: number
2223
+ /** Unix seconds, when the service reported it. */
2224
+ updatedAt?: number
2225
+ }
2226
+
1491
2227
  /** A MicroVM as `GetMicrovm` last described it. */
1492
2228
  export interface Microvm {
1493
2229
  id: string
@@ -1581,10 +2317,70 @@ export interface PlanUsageOptions {
1581
2317
  imageRetainedSeconds?: number
1582
2318
  suspendResumeCycles?: number
1583
2319
  snapshotGb?: number
2320
+ /**
2321
+ * Whether the plan launches, which reads a snapshot. Left out, the core infers it: running
2322
+ * time, or an image of non-zero size, so suspended time alone reads no launch snapshot.
2323
+ */
1584
2324
  launched?: boolean
2325
+ /**
2326
+ * What the report is of. Left out, `"estimate"`: the core's label, the one
2327
+ * `microvm cost --estimate` uses for the same plan (#255).
2328
+ */
1585
2329
  label?: string
1586
2330
  }
1587
2331
 
2332
+ /** What a stopped port-forward did. */
2333
+ export interface PortForwardReport {
2334
+ /** Connections accepted. */
2335
+ served: number
2336
+ /** Exchanges the endpoint proxy refused, a 403 or a 502 among them. */
2337
+ refused: number
2338
+ /** Exchanges that upgraded, a WebSocket among them. */
2339
+ upgrades: number
2340
+ /** Proxy tokens the session minted by the time the forward stopped. */
2341
+ proxyTokenMints: number
2342
+ /** Why it stopped: `"stopped"`, `"limit"`, or `"listener-failed: <why>"`. */
2343
+ stopped: string
2344
+ /** Each connection that didn't end clean, in the order they ended. */
2345
+ ended: Array<ConnectionEnd>
2346
+ }
2347
+
2348
+ /**
2349
+ * Whether a harness can launch in `region` (default: `$AWS_REGION`, `$AWS_DEFAULT_REGION`,
2350
+ * then us-east-1), checked before it queues work.
2351
+ *
2352
+ * Three checks: the region resolves (advisory when `Region.unlisted`), the credential chain
2353
+ * resolves credentials (no AWS call), and one `ListManagedMicrovmImages` page answers in that
2354
+ * region, the only AWS operation, free and read-only. A check after a failure is reported
2355
+ * with `ran: false` and makes no call. Nothing billable, nothing mutating. It does not check
2356
+ * roles, the artifact bucket, quotas, or VPC connectors. Never rejects; read `report.ok`.
2357
+ */
2358
+ export declare function preflight(region?: Region | undefined | null): Promise<PreflightReport>
2359
+
2360
+ /** One line of a preflight report. */
2361
+ export interface PreflightCheck {
2362
+ /** `"region"`, `"credentials"`, or `"service"`. */
2363
+ name: string
2364
+ ok: boolean
2365
+ /** Whether a failure decides the report's `ok`. An unlisted region's line is advisory. */
2366
+ fatal: boolean
2367
+ /** False when an earlier check's failure kept this one from running (and calling AWS). */
2368
+ ran: boolean
2369
+ detail: string
2370
+ /** What to do about a failure; empty on a pass. */
2371
+ remedy: string
2372
+ }
2373
+
2374
+ /** What `preflight` found: three checks and whether a launch could proceed. */
2375
+ export interface PreflightReport {
2376
+ /** True exactly when no fatal check failed or was skipped. */
2377
+ ok: boolean
2378
+ /** The region checked, absent when none resolved. */
2379
+ region?: string
2380
+ /** `region`, `credentials`, and `service`, in that order. */
2381
+ checks: Array<PreflightCheck>
2382
+ }
2383
+
1588
2384
  /**
1589
2385
  * What `wait()` resolves to.
1590
2386
  *
@@ -1657,9 +2453,67 @@ export interface PromptOptions {
1657
2453
  reapGroupOnExit?: boolean
1658
2454
  }
1659
2455
 
2456
+ /**
2457
+ * The `agentd` daemon binary for `options.version` (default: this client's own).
2458
+ *
2459
+ * Answered from `options.binary` or `$MICROVM_AGENTD` when either names a file, else the
2460
+ * version's cache entry, else the GitHub release asset, verified in-process against the
2461
+ * release workflow's Sigstore attestation or, only when GitHub can't be reached for one, the
2462
+ * release's `SHA256SUMS`. A fetch that cannot be verified rejects with `ERR_PRECONDITION`
2463
+ * (on `err.cause.message`), and so does any binary that is not an aarch64 ELF. Neither
2464
+ * `gh` nor `curl` is needed.
2465
+ */
2466
+ export declare function provisionAgentd(options?: ProvisionOptions | undefined | null): Promise<Buffer>
2467
+
2468
+ /** `provisionAgentd`, answering with the bytes and how they got here. */
2469
+ export declare function provisionAgentdReport(options?: ProvisionOptions | undefined | null): Promise<ProvisionedAgentd>
2470
+
2471
+ /** A provisioned `agentd` binary and how it got here: `provisionAgentdReport()`'s answer. */
2472
+ export interface ProvisionedAgentd {
2473
+ /** The binary itself, an aarch64 ELF. */
2474
+ data: Buffer
2475
+ /** Where the binary is on disk: the cache entry, or the caller's own path. */
2476
+ path: string
2477
+ /** `"caller-supplied"`, `"cache"`, or `"fetched"`. */
2478
+ source: string
2479
+ /**
2480
+ * For a caller-supplied binary, `"argument"` (the `binary` option) or `"env"`
2481
+ * (`$MICROVM_AGENTD`).
2482
+ */
2483
+ suppliedBy?: string
2484
+ /**
2485
+ * `"attestation"` (the release workflow's Sigstore attestation, provenance) or
2486
+ * `"checksum"` (the release's `SHA256SUMS`, integrity), when fetched or when the cache
2487
+ * entry was installed. Absent for a caller-supplied binary.
2488
+ */
2489
+ verification?: string
2490
+ /** The release version provisioned for, without a leading `v`. */
2491
+ version: string
2492
+ /** The lowercase hex SHA-256 of `data`. */
2493
+ sha256: string
2494
+ }
2495
+
2496
+ /** What to provision. Every field is optional. */
2497
+ export interface ProvisionOptions {
2498
+ /** The release version, with or without a leading `v`. Defaults to `coreVersion()`. */
2499
+ version?: string
2500
+ /**
2501
+ * The state directory the cache lives under. Defaults to the CLI's
2502
+ * (`$MICROVM_STATE_DIR`, else `~/.microvm/runs`), so every surface shares one cache.
2503
+ */
2504
+ stateDir?: string
2505
+ /** A binary the caller manages. Outranks `$MICROVM_AGENTD`; must be an aarch64 ELF. */
2506
+ binary?: string
2507
+ }
2508
+
1660
2509
  /** Everything a launch needs. */
1661
2510
  export interface RunOptions {
1662
- /** The image to launch, or omitted for the one `buildImage` built. */
2511
+ /**
2512
+ * The image to launch, as an ARN or a bare image name, or omitted for the one
2513
+ * `buildImage` built. The core resolves a name to its ARN with one `ListMicrovmImages`
2514
+ * read, and a name no image carries is refused with `ERR_PRECONDITION` before anything
2515
+ * launches.
2516
+ */
1663
2517
  imageIdentifier?: string
1664
2518
  /**
1665
2519
  * `imageVersion`, or omitted for the image's own latest active version.
@@ -1692,6 +2546,12 @@ export interface RunOptions {
1692
2546
  * payload before the launch, naming the byte count.
1693
2547
  */
1694
2548
  launchEnv?: Record<string, string>
2549
+ /**
2550
+ * Generate a tunnel identity and deliver the VM's half with the launch, so
2551
+ * `session.tunnel(port, {}, await sandbox.tunnelIdentity())` can prove the far end is
2552
+ * this VM's daemon.
2553
+ */
2554
+ identity?: boolean
1695
2555
  /** Request the managed INTERNET_EGRESS connector. Omission does not block egress. */
1696
2556
  egress?: boolean
1697
2557
  /**
@@ -1714,13 +2574,17 @@ export interface RunOptions {
1714
2574
  suspendedSec?: number
1715
2575
  autoResume?: boolean
1716
2576
  maxDurationSec?: number
1717
- /** How long to wait for RUNNING. */
2577
+ /**
2578
+ * How long to wait for RUNNING. The wait for the daemon after it is the core's
2579
+ * `defaultReadyTimeoutSeconds`.
2580
+ */
1718
2581
  readyTimeout?: number
1719
2582
  /** A label for the run token. Never the token. */
1720
2583
  tokenScope?: string
1721
2584
  /**
1722
- * Whether `run` waits for RUNNING (default `true`). `false` resolves once the launch
1723
- * is accepted, with the lifecycle PENDING; `waitUntilRunning` finishes it.
2585
+ * Whether `run` waits for RUNNING and for the daemon to answer (default `true`).
2586
+ * `false` resolves once the launch is accepted, with the lifecycle PENDING;
2587
+ * `waitUntilRunning` finishes both waits.
1724
2588
  */
1725
2589
  wait?: boolean
1726
2590
  /** Per-VM CloudWatch log group. Omitted keeps the service's default destination. */
@@ -1775,11 +2639,27 @@ export interface RunUsageOptions {
1775
2639
  suspendResumeCycles?: number
1776
2640
  /** The suspend snapshot's size. Defaults to the baseline memory footprint. */
1777
2641
  snapshotGb?: number
1778
- /** Whether a launch happened. A launch reads a snapshot. */
2642
+ /**
2643
+ * Whether a launch happened. A launch reads a snapshot. Left out, the core infers it:
2644
+ * running time, or an image of non-zero size.
2645
+ */
1779
2646
  launched?: boolean
2647
+ /** What the report is of. Left out, `"run"`: the core's label, the one `microvm cost` uses. */
1780
2648
  label?: string
1781
2649
  }
1782
2650
 
2651
+ /** Where a tunnel or a port-forward listens, and when it stops on its own. */
2652
+ export interface ServeOptions {
2653
+ /**
2654
+ * A `host:port` to listen on. Default: loopback, on a port the OS picks; the handle's
2655
+ * `localAddress` says which. Bind beyond loopback only on a network you trust: whoever
2656
+ * connects reaches the VM with this session's credentials.
2657
+ */
2658
+ bind?: string
2659
+ /** Stop accepting after this many connections. Default: serve until stopped. */
2660
+ maxConnections?: number
2661
+ }
2662
+
1783
2663
  /**
1784
2664
  * The daemon's protocol constants, as a JSON string, for a caller asserting against the
1785
2665
  * wire contract.
@@ -1894,6 +2774,30 @@ export interface StreamOptionsInput {
1894
2774
  idleTimeout?: number
1895
2775
  }
1896
2776
 
2777
+ /** How `syncDir` should behave. */
2778
+ export interface SyncDirOptions {
2779
+ /** Ignore the manifest the last sync left in the VM and upload everything. */
2780
+ full?: boolean
2781
+ /** The in-VM removal's deadline, in seconds. Default: core's, 60. */
2782
+ deleteTimeout?: number
2783
+ }
2784
+
2785
+ /** What one `syncDir` did. */
2786
+ export interface SyncReport {
2787
+ /** The uploaded archive's size, 0 when nothing travelled. */
2788
+ uploadedBytes: number
2789
+ /** How many members the upload carried: the changed ones, or every one when `full`. */
2790
+ uploadedMembers: number
2791
+ /** How many paths gone locally were removed in the VM. */
2792
+ deleted: number
2793
+ /** Deletions the VM's manifest ordered that weren't plain relative paths, so weren't run. */
2794
+ refusedDeletions: number
2795
+ /** No manifest was read (`full: true`, or none in the VM), so the whole tree travelled. */
2796
+ full: boolean
2797
+ /** The VM already held the tree as it is, so nothing travelled. */
2798
+ unchanged: boolean
2799
+ }
2800
+
1897
2801
  /**
1898
2802
  * What a teardown should delete beyond the VM itself.
1899
2803
  *
@@ -1914,9 +2818,10 @@ export interface TeardownOptions {
1914
2818
  /**
1915
2819
  * `false` by default: the caller is on the way out, and a teardown that blocked five
1916
2820
  * minutes on a state nobody reads is five minutes of a CI job. The report then honestly
1917
- * ends in `"TERMINATING"`.
2821
+ * ends in `"TERMINATING"`. `true` waits for TERMINATED up to the core's lifecycle default;
2822
+ * a number of seconds waits up to that instead.
1918
2823
  */
1919
- waitForTerminated?: boolean
2824
+ waitForTerminated?: boolean | number
1920
2825
  }
1921
2826
 
1922
2827
  /** What a teardown did, and what it left behind. */
@@ -1952,6 +2857,30 @@ export interface TeardownReport {
1952
2857
  leaked: boolean
1953
2858
  }
1954
2859
 
2860
+ /** What a stopped tunnel did. */
2861
+ export interface TunnelReport {
2862
+ /** Connections accepted. */
2863
+ served: number
2864
+ /** Connections the daemon refused, or that failed with an error. */
2865
+ refused: number
2866
+ /**
2867
+ * Verified connections that ended without the daemon's end of stream, so their stream
2868
+ * may have been cut short.
2869
+ */
2870
+ truncated: number
2871
+ /**
2872
+ * Verified connections into a daemon from before the end of stream, whose end nothing
2873
+ * proved.
2874
+ */
2875
+ unproven: number
2876
+ /** Proxy tokens the session minted by the time the tunnel stopped. */
2877
+ proxyTokenMints: number
2878
+ /** Why it stopped: `"stopped"`, `"limit"`, or `"listener-failed: <why>"`. */
2879
+ stopped: string
2880
+ /** Each connection that didn't end clean, in the order they ended. */
2881
+ ended: Array<ConnectionEnd>
2882
+ }
2883
+
1955
2884
  /** How `waitForState` polls. */
1956
2885
  export interface WaitForStateOptions {
1957
2886
  /** States that reject with `stateReason` instead of being waited through. */
@@ -1964,3 +2893,28 @@ export interface WaitForStateOptions {
1964
2893
 
1965
2894
  /** Every daemon-status class, as `err.cause.cause.message` names them. */
1966
2895
  export declare function wireKinds(): Array<string>
2896
+
2897
+ /**
2898
+ * A task Dockerfile with the agentd stanza appended, ready for `buildImage`.
2899
+ *
2900
+ * The result is the task text, a newline if it lacked one, `USER root` when the task's last
2901
+ * `USER` is anyone else, then the stanza the default Dockerfile uses: `COPY agentd /agentd`,
2902
+ * the chmod, `ENV AGENTD_PORT`, `EXPOSE`, `ENTRYPOINT []` and `CMD ["/agentd"]`. Pass the
2903
+ * result to `buildImage` with `baseImage: baseImageFromDockerfile(result)`.
2904
+ *
2905
+ * Throws `ERR_INVALID_ARG` for a task with no `FROM`, one that ends inside a line
2906
+ * continuation or an unterminated heredoc (either would swallow the stanza), a keepalive the
2907
+ * client cannot tolerate, a port of 0, a workdir that is not one absolute path, or
2908
+ * `inheritWorkdir` with nothing to inherit.
2909
+ */
2910
+ export declare function wrapDockerfile(taskDockerfile: string, options?: WrapDockerfileOptions | undefined | null): string
2911
+
2912
+ /** What `wrapDockerfile` takes besides the task text. Every field is optional. */
2913
+ export interface WrapDockerfileOptions {
2914
+ /** The agent port the stanza names, 9000 by default. It must match the sandbox's. */
2915
+ port?: number
2916
+ /** A working directory for the stanza to create and set, as the default Dockerfile does. */
2917
+ workdir?: string
2918
+ /** Refuse a result with no `WORKDIR` anywhere, because the exec would inherit `/`. */
2919
+ inheritWorkdir?: boolean
2920
+ }