@theagenticguy/microvms 0.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +35 -0
  2. package/index.d.ts +1075 -0
  3. package/index.js +729 -0
  4. package/package.json +61 -0
package/index.d.ts ADDED
@@ -0,0 +1,1075 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+ /**
4
+ * What a line item's cost can be: an estimate, or unpriced.
5
+ *
6
+ * `kind` is the stable tag, and exactly one of `usd`/`unpriced` is non-null — so a reader
7
+ * who checks either has handled both.
8
+ */
9
+ export declare class Amount {
10
+ /** `"estimated-usd"` or `"unpriced"`. */
11
+ get kind(): string
12
+ /**
13
+ * The estimate, or `null` when there is no published rate.
14
+ *
15
+ * `null` rather than a zero — the one arithmetic this module refuses to enable.
16
+ */
17
+ get usd(): EstimatedUsd | null
18
+ /** The unpriced half, or `null` when the line was priced. */
19
+ get unpriced(): Unpriced | null
20
+ toString(): string
21
+ }
22
+
23
+ /** A timeout for the `ready` or `validate` image-build hook: 1..=3600 seconds. */
24
+ export declare class BuildHookTimeout {
25
+ /** A build-family timeout, or a refusal naming both ceilings. */
26
+ constructor(seconds: number)
27
+ /** The service ceiling for this family: 3600. */
28
+ get maxSecs(): number
29
+ get seconds(): number
30
+ toString(): string
31
+ }
32
+
33
+ /** Per-phase attribution for one sandbox, measured or projected. */
34
+ export declare class CostReport {
35
+ get label(): string
36
+ get size(): SizeClass
37
+ get rates(): RateTable
38
+ get items(): Array<LineItem>
39
+ /** The line items with a published rate. */
40
+ get priced(): Array<LineItem>
41
+ /** The line items with no published rate. */
42
+ get unpriced(): Array<LineItem>
43
+ /** The total, which is a lower bound whenever anything is unpriced. */
44
+ get total(): Total
45
+ /** False whenever any phase has no published rate. */
46
+ get complete(): boolean
47
+ /** True only if every duration was timed. An estimate is never this. */
48
+ get fullyMeasured(): boolean
49
+ /** The staleness warning the table carried when this was computed. */
50
+ get staleness(): string | null
51
+ /**
52
+ * The line items belonging to one phase.
53
+ *
54
+ * The string is judged by the core's own [`CostPhase::from_str`], which is where the
55
+ * closed set lives. This file used to carry its own seven-element table for it, as did
56
+ * `microvms-py/src/cost.rs` — two parallel lists over one enum, which would have gone
57
+ * stale the first time a phase was added and would have disagreed with each other in
58
+ * whichever direction was edited first.
59
+ */
60
+ byPhase(phase: string): Array<LineItem>
61
+ /** Plain text, leading with what the dollars are rather than with the dollars. */
62
+ render(): string
63
+ /**
64
+ * The `cli.py:688 report_to_dict` shape as a JSON **string**.
65
+ *
66
+ * A string for the same reason [`LineItem::to_json`] is: the unpriced line item omits
67
+ * its `usd` key, which no typed return shape can express.
68
+ */
69
+ toJson(): string
70
+ }
71
+
72
+ /**
73
+ * Seconds, plus how we know them.
74
+ *
75
+ * No constructor: `Duration.measured(s)` and `Duration.projected(s)` are the only doors,
76
+ * so a provenance cannot be omitted. See the module docs.
77
+ */
78
+ export declare class Duration {
79
+ /**
80
+ * A timed phase: a clock ran and this is what it read.
81
+ *
82
+ * Fallible because the float is — a negative or non-finite figure has no reading as a
83
+ * duration, and the refusal is the core's, message and all.
84
+ */
85
+ static measured(seconds: number): Duration
86
+ /** A hypothetical phase: an estimate's input, or a documented minimum nobody timed. */
87
+ static projected(seconds: number): Duration
88
+ /** The span in seconds, without its label. */
89
+ get seconds(): number
90
+ /** `"measured"` or `"projected"`. */
91
+ get provenance(): string
92
+ /** True only for a timed span. What `CostReport.fullyMeasured` reads. */
93
+ get isMeasured(): boolean
94
+ /** `Ns (provenance)` — the label travels with the figure. */
95
+ toString(): string
96
+ }
97
+
98
+ /**
99
+ * Dollars derived from published rates. Not the bill.
100
+ *
101
+ * # There is no way to get a number out of this
102
+ *
103
+ * No `valueOf`, no `toJSON`, no `Symbol.toPrimitive`, no `add`, and no constructor. So
104
+ * `Number(usd)` is `NaN`, `usd * 2` is `NaN`, `+usd` is `NaN`, and `JSON.stringify(usd)`
105
+ * answers `{}`. The figure comes out through [`Self::amount`], a **string** — one visible
106
+ * step that keeps the type name at the call site, which is a decision a reviewer can see.
107
+ */
108
+ export declare class EstimatedUsd {
109
+ /**
110
+ * The figure as an exact decimal **string**.
111
+ *
112
+ * A string and not a number: a JS double cannot hold `0.0000276944` summed a few
113
+ * thousand times without drifting in the direction of a bill nobody can reproduce.
114
+ */
115
+ get amount(): string
116
+ /** The figure at display precision: two places at a dollar or more, six below. */
117
+ get displayAmount(): string
118
+ /** `~$X (estimated)`. */
119
+ toString(): string
120
+ }
121
+
122
+ /**
123
+ * One exec, addressed by its caller-minted id.
124
+ *
125
+ * The id is the idempotency key, so a handle survives a process restart: rebuild it through
126
+ * `Session.exec(execId)` and every method still addresses the same server-side exec.
127
+ */
128
+ export declare class ExecHandle {
129
+ get execId(): string
130
+ /** Reads current status and output. Read-only server-side; safe to spin on. */
131
+ poll(): Promise<ExecResult>
132
+ /**
133
+ * Polls until the exec is done, or rejects with `ERR_TIMEOUT`.
134
+ *
135
+ * A timeout has not touched the exec — polling is read-only and output lives until it
136
+ * is acked — so a caller that gives up can come back and poll again.
137
+ */
138
+ wait(timeout?: number | undefined | null): Promise<ExecResult>
139
+ /**
140
+ * An async iterator over output as it arrives, reconnecting at the last good offset.
141
+ *
142
+ * `for await (const event of handle.stream())`.
143
+ */
144
+ stream(options?: StreamOptionsInput | undefined | null): ExecStream
145
+ /**
146
+ * Writes to the child's stdin. Requires the exec to have been started with
147
+ * `stdin: true`, or the daemon answers 409.
148
+ *
149
+ * `eof` in the same call is the common case for feeding a prompt: two round trips would
150
+ * leave a window where the child has the bytes but not the EOF that says the input is
151
+ * complete.
152
+ */
153
+ writeStdin(data: Uint8Array, eof?: boolean | undefined | null): Promise<StdinAck>
154
+ /**
155
+ * Sends EOF. Nothing else closes stdin: the daemon's copy of the pipe outlives the
156
+ * child's wait, so a child blocked reading stdin hangs until its timeout otherwise.
157
+ */
158
+ closeStdin(): Promise<StdinAck>
159
+ /** Releases the buffered output and starts the TTL clock. */
160
+ ack(): Promise<ExecResult>
161
+ /**
162
+ * Signals the whole process group. `false` means nothing was signalled because the
163
+ * child had already been reaped — which is the outcome a kill wanted.
164
+ */
165
+ kill(): Promise<boolean>
166
+ /**
167
+ * Wait, then ack, returning the result that carries the output.
168
+ *
169
+ * Which result comes back matters: the ack response carries the released output and a
170
+ * poll issued after the ack reports `acked` with none, so returning the wrong one is a
171
+ * silent empty-output bug. The core sequences it.
172
+ */
173
+ waitAndAck(timeout?: number | undefined | null): Promise<ExecResult>
174
+ }
175
+
176
+ /**
177
+ * A JS async iterator over an exec's output.
178
+ *
179
+ * See the module docs for why this is a task and a bounded channel. The receiver is behind
180
+ * a tokio `Mutex` because `AsyncGenerator::next` must answer a `Send + 'static` future, so
181
+ * the guard is taken *inside* that future rather than borrowed from `&mut self`.
182
+ *
183
+ * This type implements JavaScript's async iterable protocol.
184
+ * It can be used with `for await...of` loops.
185
+ *
186
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols
187
+ */
188
+ export declare class ExecStream {
189
+
190
+ }
191
+
192
+ /** One phase's one billing line: what was consumed, and what that costs. */
193
+ export declare class LineItem {
194
+ get phase(): string
195
+ /**
196
+ * The AWS billing line, or `null` for a phase with no published rate to attribute it
197
+ * to.
198
+ */
199
+ get line(): string | null
200
+ /**
201
+ * The consumed quantity, exact, as a string.
202
+ *
203
+ * Exact so a reader can check the arithmetic against the rate table, which is the only
204
+ * defence against a rate that drifts without anyone noticing.
205
+ */
206
+ get quantity(): string
207
+ /** The quantity at display precision, for a column a human scans. */
208
+ get displayQuantity(): string
209
+ get unit(): string
210
+ get amount(): Amount
211
+ get duration(): Duration | null
212
+ get note(): string
213
+ /**
214
+ * The `cli.py` `_line_to_dict` shape as a JSON **string**.
215
+ *
216
+ * A string rather than an object because the unpriced case must **omit** the `usd` key
217
+ * entirely, and a `#[napi(object)]` return type cannot express an absent key — an
218
+ * `Option` field serializes as `null`, which is the one value that gets summed as zero
219
+ * by anything permissive. A caller does `JSON.parse`, which is one visible step.
220
+ */
221
+ toJson(): string
222
+ toString(): string
223
+ }
224
+
225
+ /** The pinned rate table, and everything it says about itself. */
226
+ export declare class RateTable {
227
+ /**
228
+ * us-east-1, read 2026-08-07, as recorded in `docs/PLATFORM.md`.
229
+ *
230
+ * There is deliberately no constructor taking rates. The core's table has private rate
231
+ * fields and exactly two doors — this one and `from_catalog`, which refuses a catalog
232
+ * whose ARM compute line is missing rather than substituting the x86 one, 17.9% higher
233
+ * (COST-9). A constructor taking five numbers would reopen precisely that.
234
+ */
235
+ static pinned(): RateTable
236
+ get region(): string
237
+ get sourceUrl(): string
238
+ /** ISO 8601, matching the Python's `retrieved.isoformat()`. */
239
+ get retrieved(): string
240
+ get vcpuSecond(): string
241
+ get gbSecond(): string
242
+ /**
243
+ * Per GB-month. The one derived figure: the API quotes per GB-hour, and this is that
244
+ * times 730.
245
+ */
246
+ get storageGbMonth(): string
247
+ get snapshotReadGb(): string
248
+ get snapshotWriteGb(): string
249
+ /** Snapshot storage bills at least this long however briefly the snapshot exists. */
250
+ get minimumRetentionSeconds(): number
251
+ /** Zero: MicroVMs bills per second with no per-request charge. */
252
+ get perRequest(): string
253
+ /** True: vCPU and memory are two line items, as the pricing page prices them. */
254
+ get billsVcpuAndMemorySeparately(): boolean
255
+ /** False: no published MicroVMs free tier. The Lambda one is Functions-only. */
256
+ get freeTier(): boolean
257
+ /**
258
+ * `null` means **not published**, not one second. Nothing rounds a duration up, because
259
+ * inventing an increment would overcharge every short exec.
260
+ */
261
+ get minimumBillingIncrementSec(): number | null
262
+ /** How many days ago these rates were read, against today UTC. */
263
+ ageDays(): number
264
+ /** The staleness warning, or `null` when the table is fresh. */
265
+ staleness(): string | null
266
+ }
267
+
268
+ /** An AWS region, closed over the five that run MicroVMs plus a named escape hatch. */
269
+ export declare class Region {
270
+ static usEast1(): Region
271
+ static usEast2(): Region
272
+ static usWest2(): Region
273
+ static euWest1(): Region
274
+ static apNortheast1(): Region
275
+ /**
276
+ * One of the five, or a refusal naming the null-message trap.
277
+ *
278
+ * The boundary a region name arrives at from an environment variable or a config file,
279
+ * where it is still a string. The refusal is the core's `FromStr`, message and all —
280
+ * this is a call, not a check written here.
281
+ */
282
+ static parse(name: string): Region
283
+ /**
284
+ * Opts into a region this client has not seen carry MicroVMs.
285
+ *
286
+ * **This costs you the diagnostic.** If the region does not run MicroVMs, the first
287
+ * control-plane call answers `AccessDeniedException` with a null message, and you will
288
+ * spend the next hour reading an IAM policy that is correct. Named rather than a flag so
289
+ * a reader of the call site can see the opt-in.
290
+ *
291
+ * A supported name handed here comes back as its proper region, so
292
+ * `Region.unlisted("us-east-1")` equals `Region.usEast1()`.
293
+ */
294
+ static unlisted(name: string): Region
295
+ /** Every region this client has seen carry MicroVMs. */
296
+ static supported(): Array<Region>
297
+ /** The wire spelling, which is also the endpoint's middle segment. */
298
+ get name(): string
299
+ /** Whether this is one of the five rather than an opted-into unlisted name. */
300
+ get isSupported(): boolean
301
+ toString(): string
302
+ /**
303
+ * Whether two regions are the same one.
304
+ *
305
+ * A method and not `===`: JS compares class instances by reference, so two
306
+ * `Region.usEast1()` calls are different objects. Named `equals` because that is what a
307
+ * JS reader expects to reach for.
308
+ */
309
+ equals(other: Region): boolean
310
+ }
311
+
312
+ /** Running versus suspended for the same VM over the same wall time. */
313
+ export declare class ResidencyComparison {
314
+ get size(): SizeClass
315
+ /**
316
+ * The wall time both sides cover. Always projected: a comparison is a hypothetical
317
+ * about a hold nobody has taken yet.
318
+ */
319
+ get hold(): Duration
320
+ get cycles(): number
321
+ get running(): CostReport
322
+ get suspended(): CostReport
323
+ /** How many times more the running VM costs, as an exact decimal string. */
324
+ get ratio(): string
325
+ /**
326
+ * One suspend/resume: a snapshot write plus a read, per GB.
327
+ *
328
+ * Without it the honest conclusion inverts — "suspend constantly" reads as free.
329
+ */
330
+ perCycle(): EstimatedUsd
331
+ /**
332
+ * How long a VM must stay suspended for the cycle to pay for itself, exact, as a
333
+ * string. The number a pool scheduler needs, and the one a "100x cheaper" headline
334
+ * hides.
335
+ */
336
+ breakEvenSeconds(): string
337
+ /**
338
+ * The break-even hold as a number. **Lossy, and named so.**
339
+ *
340
+ * Seconds, not dollars: no money figure has a numeric accessor anywhere in this file.
341
+ */
342
+ breakEvenSecondsNumber(): number
343
+ render(): string
344
+ }
345
+
346
+ /**
347
+ * A timeout for the `run`, `resume`, `suspend`, or `terminate` hook: 1..=60 seconds.
348
+ *
349
+ * A distinct class from [`BuildHookTimeout`] and deliberately not interchangeable with it.
350
+ */
351
+ export declare class RunHookTimeout {
352
+ /** A run-family timeout, or a refusal naming **both** ceilings. */
353
+ constructor(seconds: number)
354
+ /** The service ceiling for this family: 60. */
355
+ get maxSecs(): number
356
+ get seconds(): number
357
+ toString(): string
358
+ }
359
+
360
+ /**
361
+ * One MicroVM's whole life.
362
+ *
363
+ * The five transitions are `buildImage`, `run`, `suspend`, `resume`, and `terminate`, and
364
+ * every state guard lives in the core — see the module docs.
365
+ */
366
+ export declare class Sandbox {
367
+ /**
368
+ * Resolves credentials for `region` and returns a sandbox with nothing launched.
369
+ *
370
+ * A factory rather than a constructor because credential resolution is async, and a
371
+ * `#[napi(constructor)]` cannot be. `region` is a [`Region`] instance and not a string,
372
+ * which is TRAP-6 at this boundary.
373
+ */
374
+ static create(region: Region): Promise<Sandbox>
375
+ /**
376
+ * The lifecycle state: `"PENDING"`, `"RUNNING"`, `"SUSPENDING"`, `"SUSPENDED"`,
377
+ * `"TERMINATING"`, or `"TERMINATED"`.
378
+ *
379
+ * Spelled as the service spells it, because a reader compares it against a `GetMicrovm`
380
+ * response and `Suspended` beside `SUSPENDED` reads like two facts.
381
+ */
382
+ lifecycle(): Promise<string>
383
+ /**
384
+ * Whether the agent token has been installed (STATE-2).
385
+ *
386
+ * Set by the platform reporting RUNNING, not by the launch call: the run hook is what
387
+ * delivers the token, and a launch that died during startup delivered nothing.
388
+ */
389
+ tokenInstalled(): Promise<boolean>
390
+ /** Whether an image is recorded as existing (STATE-1). */
391
+ imageExists(): Promise<boolean>
392
+ /** Whether this VM was ever terminated (STATE-11). */
393
+ wasTerminated(): Promise<boolean>
394
+ /** How many times the token has been installed. Never above one (STATE-3). */
395
+ bootstrapCount(): Promise<number>
396
+ /** The VM id, once launched. */
397
+ microvmId(): Promise<string | null>
398
+ /** The proxy endpoint, once launched. */
399
+ endpoint(): Promise<string | null>
400
+ /**
401
+ * Why the VM is in its current state, when the service said.
402
+ *
403
+ * The absence is information: TRAP-8's message distinguishes "no stateReason" from an
404
+ * empty one.
405
+ */
406
+ stateReason(): Promise<string | null>
407
+ /** The image, once built. */
408
+ image(): Promise<Image | null>
409
+ /**
410
+ * The suspended window this sandbox asked for at launch, in seconds.
411
+ *
412
+ * `null` before a launch, and for a sandbox that did not send the launch — this client is
413
+ * the only party that can name the number, because `suspendedDurationSeconds` exists only
414
+ * in the `RunMicrovm` request.
415
+ */
416
+ suspendedWindowSecondsAsync(): Promise<number | null>
417
+ /**
418
+ * The session, once launched.
419
+ *
420
+ * A new wrapper each call, all reaching the same session under the same lock. There is no
421
+ * cached instance: caching one would mean a session object that outlives the VM it
422
+ * addresses, and the indirection exists precisely so a post-terminate call reports the
423
+ * lifecycle rather than a dangling handle.
424
+ */
425
+ session(): Promise<Session | null>
426
+ /**
427
+ * Builds an image and waits for it to become usable.
428
+ *
429
+ * Every local guard runs **before** the call, which matters because the create happens
430
+ * after the caller's artifact upload: a rejection AWS raises costs the upload first.
431
+ */
432
+ buildImage(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<Image>
433
+ /**
434
+ * The artifact bytes to upload to `codeArtifactUri`.
435
+ *
436
+ * The upload is the caller's: S3 is not in the core's dependency set. Takes the same
437
+ * options as [`Self::build_image`] so the bytes a caller puts in the bucket are the bytes
438
+ * the build will receive.
439
+ */
440
+ buildArtifact(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<Buffer>
441
+ /**
442
+ * Launches a MicroVM, waits for RUNNING, and resolves with its session.
443
+ *
444
+ * # What the core refuses here, and this file does not
445
+ *
446
+ * A second `run` on one sandbox, with **zero** control-plane calls: the agent token is
447
+ * installed at most once per VM lifetime (STATE-3), and a second VM needs a second
448
+ * `Sandbox`. A run with no image at all, before any call. Neither check is in this file.
449
+ */
450
+ run(options?: RunOptions | undefined | null): Promise<Session>
451
+ /**
452
+ * Freezes the VM and waits for the platform to report it.
453
+ *
454
+ * A freeze and restore rather than a stop and start: the guest keeps its memory, so the
455
+ * token, the filesystem, and every exec record survive. The one thing that does not is
456
+ * the guest's view of time — it observes the whole suspension as a single jump, so any
457
+ * timeout, lease, or TLS session a running command holds expires at once on resume.
458
+ *
459
+ * A suspend from anything but RUNNING is refused by the core with zero control-plane
460
+ * calls (STATE-5). Resolves with the state reached, which may be `"TERMINATED"`: a VM
461
+ * that dies while suspending is a state to report rather than an error thrown out of the
462
+ * middle of a teardown.
463
+ */
464
+ suspend(): Promise<string>
465
+ /**
466
+ * Thaws the VM and resolves with a usable session.
467
+ *
468
+ * # What the core refuses, before any wire call
469
+ *
470
+ * A resume after `terminate` (STATE-11) — a terminated VM never returns to RUNNING, and
471
+ * even a call the service accepted would hand back a different machine. A resume from
472
+ * anything but SUSPENDED (STATE-7). And a resume past the launch-time suspended window
473
+ * (STATE-12), which is the one worth knowing about: the `idlePolicy` terminates a
474
+ * suspended VM once that window passes, so there is nothing left to resume, and calling
475
+ * would cost the full poll timeout to learn something worse.
476
+ *
477
+ * Nothing is re-delivered: no run-hook payload, no token, no bootstrap. The in-memory
478
+ * token survived the freeze, and re-delivering it would hit the daemon's one-shot
479
+ * bootstrap and be refused — a 409 that reads like a broken VM.
480
+ */
481
+ resume(): Promise<Session>
482
+ /**
483
+ * Tears down, best-effort, **never rejecting**.
484
+ *
485
+ * Order: VM, then image, then the log group last, because the service can recreate a
486
+ * group deleted before its image.
487
+ */
488
+ terminate(options?: TeardownOptions | undefined | null): Promise<TeardownReport>
489
+ }
490
+
491
+ /** One running MicroVM's control API, with the proxy auth handled for you. */
492
+ export declare class Session {
493
+ /**
494
+ * A session against a daemon reached **directly**, with no proxy headers.
495
+ *
496
+ * The shape for a local binary, a test server, or a VM reached over a tunnel. There is
497
+ * deliberately no constructor that takes a proxy token: minting one is the control
498
+ * plane's job and it happens inside every request (TRAP-9), so a caller handing a token
499
+ * in would be handing in one that expires.
500
+ */
501
+ static direct(endpoint: string, agentToken: string): Session
502
+ /** The endpoint this session addresses. */
503
+ endpoint(): Promise<string>
504
+ /** The port the proxy token is scoped to. */
505
+ port(): Promise<number>
506
+ /** Unauthenticated liveness. */
507
+ health(): Promise<Health>
508
+ /**
509
+ * Polls health until the daemon reports bootstrapped.
510
+ *
511
+ * Connection errors on the way are expected rather than exceptional: a VM that has just
512
+ * reached RUNNING commonly refuses a connection or two before the proxy path is wired
513
+ * up. A *fatal* error ends the wait at once, because retrying a 401 until the deadline
514
+ * is the mistake the retryable split exists to prevent.
515
+ */
516
+ waitUntilReady(timeout?: number | undefined | null): Promise<Health>
517
+ /** Starts a command and returns its handle. Does not wait. */
518
+ run(command: string | Array<string>, options?: ExecOptions | undefined | null): Promise<ExecHandle>
519
+ /**
520
+ * A handle for an exec started earlier, possibly by another process.
521
+ *
522
+ * The reattach path. Nothing is checked against the daemon here — the handle is an id
523
+ * plus a transport, and a poll is what discovers whether the exec exists.
524
+ */
525
+ exec(execId: string): Promise<ExecHandle>
526
+ /** Start, wait, ack. The one-shot shape, for when output is all you want. */
527
+ runSync(command: string | Array<string>, options?: ExecOptions | undefined | null): Promise<ExecResult>
528
+ /** Signals an exec's whole process group. Returns whether anything was signalled. */
529
+ kill(execId: string): Promise<boolean>
530
+ /**
531
+ * Writes one file, creating parents. `mode` is an **octal string** (`"0755"`), which is
532
+ * the daemon's shape — a number here would be ambiguous between 0o755 and 755.
533
+ */
534
+ uploadFile(path: string, data: Uint8Array, mode?: string | undefined | null): Promise<void>
535
+ /** Reads one file. */
536
+ downloadFile(path: string): Promise<Buffer>
537
+ /** Whether a path exists, distinguishing absence from every other refusal. */
538
+ fileExists(path: string): Promise<boolean>
539
+ /**
540
+ * Extracts pre-built tar bytes under `remote`.
541
+ *
542
+ * Bytes rather than a local path: packing a directory is the caller's, because the
543
+ * symlink and permission decisions in a pack belong to whoever knows what the tree
544
+ * means.
545
+ */
546
+ uploadTar(remote: string, archive: Uint8Array): Promise<void>
547
+ /** The raw tar bytes of a remote tree. */
548
+ downloadTar(remote: string): Promise<Buffer>
549
+ /**
550
+ * How many proxy tokens this session has minted, or `null` for a direct session.
551
+ *
552
+ * Exposed because it is the only observable that distinguishes a client which re-minted
553
+ * after a resume from one that kept a stale token (STATE-8). The **token itself** is not
554
+ * exposed and cannot be: the core's `ProxyToken` has no `Display`, no `as_str`, and no
555
+ * `Deref`, so "treat `authToken` as a string" is as inexpressible here as it is there
556
+ * (TRAP-7).
557
+ */
558
+ proxyMintCount(): Promise<number | null>
559
+ }
560
+
561
+ /**
562
+ * One of the five documented size classes.
563
+ *
564
+ * `minimumMemoryInMiB` selects a class; it does not size a VM. Both numbers are on the
565
+ * class or neither.
566
+ */
567
+ export declare class SizeClass {
568
+ /**
569
+ * The class `minimumMemoryInMiB = mib` selects, or a refusal (TRAP-10).
570
+ *
571
+ * Off-table figures are refused rather than snapped to a neighbour: the two plausible
572
+ * readings differ in both memory and rate, and neither has been measured.
573
+ */
574
+ static fromBaselineMib(mib: number): SizeClass
575
+ /**
576
+ * The platform's default, 2048 MiB. Not the smallest — a 0.5 GB baseline hands someone
577
+ * a sandbox that OOM-kills a real test suite, and the guest has no swap.
578
+ */
579
+ static defaultClass(): SizeClass
580
+ /** Every class, smallest first. */
581
+ static all(): Array<SizeClass>
582
+ get baselineMib(): number
583
+ get baselineVcpu(): number
584
+ get peakMib(): number
585
+ get peakVcpu(): number
586
+ /** The figure a GB-second rate multiplies. Always the baseline, never the peak. */
587
+ get baselineGb(): number
588
+ /** The peak in GB, which is what the guest reports as `MemTotal`. */
589
+ get peakGb(): number
590
+ /** One line naming both numbers. */
591
+ describe(): string
592
+ }
593
+
594
+ /**
595
+ * A report's total, which is a lower bound whenever anything is unpriced.
596
+ *
597
+ * The floor is under a name that says what it is — never `total`. A caller reading a field
598
+ * called `total` would have no reason to check `isLowerBound`.
599
+ */
600
+ export declare class Total {
601
+ /** Everything that could be priced. For a lower bound this is **not** the total. */
602
+ get floor(): EstimatedUsd
603
+ /** True when line items with no published rate are missing from the floor. */
604
+ get isLowerBound(): boolean
605
+ /** Why each unpriced line could not be priced, in report order. */
606
+ get unpricedReasons(): Array<string>
607
+ /** `at least ~$X (estimated), plus N unpriced (...)`. */
608
+ toString(): string
609
+ }
610
+
611
+ /**
612
+ * A quantity we can measure but cannot price, because no rate is published.
613
+ *
614
+ * A distinct class from [`EstimatedUsd`], not `EstimatedUsd("0")`: zero is a claim about
615
+ * the bill, unpriced is a claim about the documentation.
616
+ */
617
+ export declare class Unpriced {
618
+ get reason(): string
619
+ toString(): string
620
+ }
621
+
622
+ /**
623
+ * The platform's managed base image, paired with the Dockerfile `FROM` it goes with.
624
+ *
625
+ * One value rather than two loose strings, because the two **must** agree and used to be able
626
+ * to disagree: the Python client's default named the managed base for `baseImageArn` while
627
+ * its Dockerfile hardcoded an unrelated registry literal in its `FROM`, so changing either
628
+ * left the other pointing somewhere else.
629
+ *
630
+ * `#[napi(object)]` is acceptable here where it is not for a guarded type: the pairing is the
631
+ * point and both halves are required fields, so a structurally-valid object is a valid
632
+ * pairing. `workingDir` is what `docker inspect` reports for `WorkingDir`, and empty means
633
+ * the image declares none — a field because a caller with a purpose-built image is the only
634
+ * one who can say what theirs declares.
635
+ */
636
+ export interface BaseImageInput {
637
+ name: string
638
+ dockerRef: string
639
+ workingDir?: string
640
+ }
641
+
642
+ /**
643
+ * Everything `CreateMicrovmImage` needs.
644
+ *
645
+ * # What is deliberately not a field
646
+ *
647
+ * A `clientToken`. There is no such field on the core's request type and none here: a
648
+ * digest-derived token replays the original create and wedges an image in `CREATING` for
649
+ * fifteen hours with no error at all (TRAP-1). `tokenScope` is a CloudTrail **label** folded
650
+ * in beside a fresh nonce and cannot become the token.
651
+ *
652
+ * A `capabilities` list. `repairGuestIdentity` is a boolean and the request injects `["ALL"]`
653
+ * itself, so `["CAP_SYS_ADMIN"]` — the request AWS rejects after the artifact upload — is not
654
+ * something a caller can write (TRAP-3).
655
+ *
656
+ * An `architecture`. The model's enum has exactly one value, so the only thing a field could
657
+ * express is a rejected request.
658
+ */
659
+ export interface BuildImageOptions {
660
+ name: string
661
+ /** The daemon binary's bytes, zipped into the artifact. */
662
+ binary: Uint8Array
663
+ /**
664
+ * Where the artifact is uploaded to. This client does not upload — S3 is not in the
665
+ * core's dependency set — so the caller puts the bytes there and passes the URI.
666
+ */
667
+ codeArtifactUri: string
668
+ /** The build role, which must grant logs on `/aws/lambda-microvms/*`. */
669
+ buildRoleArn: string
670
+ baseImage?: BaseImageInput
671
+ /** A caller-supplied Dockerfile, checked against the base image's `FROM`. */
672
+ dockerfile?: string
673
+ /** Whether to repair guest identity. A boolean, not a capability list — see above. */
674
+ repairGuestIdentity?: boolean
675
+ /**
676
+ * Whether the daemon should inherit the image's `WORKDIR`. Refused when nothing declares
677
+ * one, because the inheritance would silently resolve to `/`.
678
+ */
679
+ inheritWorkdir?: boolean
680
+ tags?: Record<string, string>
681
+ /** A CloudTrail-readability **label**, defaulting to the image name. Not the token. */
682
+ tokenScope?: string
683
+ }
684
+
685
+ /** Why the image build has no price, as the reason that lands on the line item. */
686
+ export declare function buildUnpricedReason(): string
687
+
688
+ /** The warm-pool argument, with its own counter-argument attached. */
689
+ export declare function compareResidency(size: SizeClass, holdSeconds: number, cycles?: number | undefined | null, rates?: RateTable | undefined | null): ResidencyComparison
690
+
691
+ /**
692
+ * The core crate's version, for a `doctor` or `manifest` command to report.
693
+ *
694
+ * The **core's** version and not this crate's: what a caller needs to know is which client
695
+ * they are talking through, and a binding version that drifted from it would be a second
696
+ * number nobody can act on.
697
+ */
698
+ export declare function coreVersion(): string
699
+
700
+ /**
701
+ * The documented cost constants, as a JSON string a caller can assert against.
702
+ *
703
+ * A JSON string rather than a typed object because it is a transcription of published
704
+ * facts whose shape may grow, and a `#[napi(object)]` would make every addition a
705
+ * signature change.
706
+ */
707
+ export declare function costConstants(): string
708
+
709
+ /** The managed base every `docs/PLATFORM.md` measurement from 2026-08-06 onward used. */
710
+ export declare function defaultBaseImage(): BaseImageInput
711
+
712
+ /**
713
+ * Every `ERR_*` code this library can raise, for a caller building an exhaustive switch.
714
+ *
715
+ * Enumerated from the core's own `ErrorKind::ALL` rather than transcribed, so a kind added
716
+ * there appears here without an edit — a hand-written list would agree with a typo.
717
+ */
718
+ export declare function errorCodes(): Array<string>
719
+
720
+ /**
721
+ * What a plan will cost, before spending anything (COST-10).
722
+ *
723
+ * Takes plain seconds and marks every one projected. That is the difference from
724
+ * [`run_report`]: not the arithmetic, which is shared, but what the durations admit about
725
+ * themselves.
726
+ */
727
+ export declare function estimateRun(size: SizeClass, options?: PlanUsageOptions | undefined | null, rates?: RateTable | undefined | null): CostReport
728
+
729
+ /** How an exec should be started. Every field optional; the defaults are the daemon's. */
730
+ export interface ExecOptions {
731
+ /** A single script string rather than an argv. Requires `shell: true`. */
732
+ shell?: boolean
733
+ cwd?: string
734
+ env?: Record<string, string>
735
+ user?: number
736
+ group?: number
737
+ /** The daemon's own kill deadline for the child, distinct from a client-side `wait`. */
738
+ timeoutSec?: number
739
+ /** Whether to open a stdin pipe. Writing without this is a 409. */
740
+ stdin?: boolean
741
+ /**
742
+ * The idempotency key. Omitted, one is minted; supplied, the daemon returns success for
743
+ * a known id without spawning a second child — so a caller whose retry must be safe
744
+ * across its own restart passes a stable one.
745
+ */
746
+ execId?: string
747
+ /** The client-side deadline for `runSync` only. */
748
+ timeout?: number
749
+ }
750
+
751
+ /**
752
+ * An exec's phase and, once it has one, its outcome.
753
+ *
754
+ * `#[napi(object)]` is right for this one: it is a pure result with no closure to protect
755
+ * — there is no `ExecResult` a caller can construct wrongly, because no function takes one
756
+ * — so a plain JS object with named fields is the friendlier shape and gives up nothing.
757
+ */
758
+ export interface ExecResult {
759
+ execId: string
760
+ /** `"running"`, `"exited"`, or `"acked"`. */
761
+ phase: string
762
+ /** `null` when the child died to a signal rather than exiting. */
763
+ exitCode?: number
764
+ /** The signal that killed the child, when one did. */
765
+ signal?: number
766
+ stdout: string
767
+ stderr: string
768
+ /**
769
+ * Set when either stream hit the output cap and was cut. A flag rather than a sentinel
770
+ * inside the bytes, which would be indistinguishable from output containing it.
771
+ */
772
+ truncated: boolean
773
+ /**
774
+ * Set when the post-exit linger deadline expired with the pipes still open: some
775
+ * grandchild is alive and may write more that nobody will see.
776
+ */
777
+ writersMayBeAlive: boolean
778
+ /** Whether the exec has finished, whichever way. */
779
+ done: boolean
780
+ /**
781
+ * Whether the command exited zero. False for a signal death and for a still-running
782
+ * exec, since neither is a success.
783
+ */
784
+ ok: boolean
785
+ }
786
+
787
+ /** The daemon's liveness answer. `bootstrapped` is the useful field. */
788
+ export interface Health {
789
+ /** The daemon's own version, distinct from the protocol version. */
790
+ version: string
791
+ /** Whether the run hook has landed and the control API is open. */
792
+ bootstrapped: boolean
793
+ /**
794
+ * Bytes available to an unprivileged writer, or `null` when free space could not be
795
+ * measured.
796
+ *
797
+ * `null` is deliberately distinct from zero: unmeasurable is not full, and a monitor
798
+ * that conflated them would page on a missing `statvfs`.
799
+ */
800
+ availableBytes?: number
801
+ /** Bytes that must stay free before a write is refused. Zero means the guard is off. */
802
+ reserveBytes?: number
803
+ /**
804
+ * Whether a write would be refused right now. Precomputed by the daemon so every
805
+ * consumer applies the same comparison the write path does.
806
+ */
807
+ underPressure?: boolean
808
+ /**
809
+ * Whether any startup identity repair step failed — a duplicate machine-id or boot_id
810
+ * still in place from the shared image.
811
+ */
812
+ identityDegraded: boolean
813
+ /**
814
+ * False when identity repair was switched off by config. Separate from `degraded` so a
815
+ * monitor can tell "opted out" from "nothing to do".
816
+ */
817
+ identityRepaired: boolean
818
+ }
819
+
820
+ /** A built image, and the log group the service created alongside it. */
821
+ export interface Image {
822
+ /** The image ARN, which is what `imageIdentifier` takes. */
823
+ identifier: string
824
+ name: string
825
+ version: string
826
+ state: string
827
+ /**
828
+ * The baseline MiB of the class the request selected.
829
+ *
830
+ * Carried because billing follows the baseline requested at *create* time, and by the
831
+ * time anyone asks what a run cost the request is gone.
832
+ */
833
+ baselineMib: number
834
+ /**
835
+ * `/aws/lambda-microvms/<image-name>`.
836
+ *
837
+ * The service creates this itself, so no Terraform stack owns it and `terraform destroy`
838
+ * leaves it behind — "the stack destroyed cleanly" is not "the account is clean". Six
839
+ * accumulated before anyone noticed.
840
+ */
841
+ buildLogGroup: string
842
+ }
843
+
844
+ /**
845
+ * A plan's phases, in plain seconds, before anything is spent.
846
+ *
847
+ * Separate from [`RunUsageOptions`] on purpose (COST-10): every field is a number, so there
848
+ * is no field an accidentally-measured duration could be written into. The wrapping into
849
+ * projected durations happens in the core, in one place.
850
+ */
851
+ export interface PlanUsageOptions {
852
+ runningSeconds?: number
853
+ suspendedSeconds?: number
854
+ imageGb?: number
855
+ imageRetainedSeconds?: number
856
+ suspendResumeCycles?: number
857
+ snapshotGb?: number
858
+ launched?: boolean
859
+ label?: string
860
+ }
861
+
862
+ /** Everything a launch needs. */
863
+ export interface RunOptions {
864
+ /** The image to launch, or omitted for the one `buildImage` built. */
865
+ imageIdentifier?: string
866
+ /** The execution role. Optional in the model; every real launch needs one. */
867
+ executionRoleArn?: string
868
+ /**
869
+ * The bearer token the daemon will accept, or omitted to mint one.
870
+ *
871
+ * Optional because the common case is a per-VM secret nobody needs to see; a caller who
872
+ * has one already — a harness minting its own, or a retry that must reuse the first
873
+ * attempt's — passes it. It rides in `runHookPayload`, which is what keeps it out of the
874
+ * shared image snapshot.
875
+ */
876
+ agentToken?: string
877
+ /** Whether to request the egress connector. Off means no outbound network. */
878
+ egress?: boolean
879
+ maxIdleSec?: number
880
+ /**
881
+ * The window a resume is refused past (STATE-12). Exists **only** in the launch request:
882
+ * `GetMicrovm` does not return it, so this client is the only party that can name it.
883
+ */
884
+ suspendedSec?: number
885
+ autoResume?: boolean
886
+ maxDurationSec?: number
887
+ /** How long to wait for RUNNING. */
888
+ readyTimeout?: number
889
+ /** A label for the run token. Never the token. */
890
+ tokenScope?: string
891
+ }
892
+
893
+ /**
894
+ * Per-phase attribution for one sandbox's lifecycle.
895
+ *
896
+ * Every duration is a [`Duration`] class and not a number, which is what keeps the
897
+ * provenance label attached: taking seconds here would need this function to pick a
898
+ * provenance, and the one it would pick is the stronger claim.
899
+ */
900
+ export declare function runReport(size: SizeClass, options?: RunUsageOptions | undefined | null, rates?: RateTable | undefined | null): CostReport
901
+
902
+ /**
903
+ * Everything a measured report attributes cost to.
904
+ *
905
+ * `#[napi(object)]` **is** right here, unlike for the guarded types: this is an options bag
906
+ * a caller writes as a literal, and every field that carries a closure is a
907
+ * `ClassInstance<Duration>` rather than a number — so the object shape still cannot express
908
+ * an unlabelled duration. `ClassInstance` is what makes that hold: it extracts only from a
909
+ * real `Duration` instance, so `{ running: 3600 }` and `{ running: { seconds: 3600 } }` are
910
+ * both rejected by napi's conversion before any Rust runs. What the object buys is optional
911
+ * fields with JS's own `undefined`, which is how "this phase did not happen" is said.
912
+ */
913
+ export interface RunUsageOptions {
914
+ /**
915
+ * Wall-clock time in RUNNING. Bills at baseline whether or not anything is executing —
916
+ * there is no free I/O wait, which is why suspension rather than idleness is the lever.
917
+ */
918
+ running?: Duration
919
+ /** Time held suspended. Pays storage only: a suspended VM is frozen. */
920
+ suspended?: Duration
921
+ /** How long the image build took, if it was timed. Always unpriced. */
922
+ imageBuild?: Duration
923
+ /**
924
+ * The image's size. Passing this adds both an image-storage line *and* the unpriced
925
+ * build line, so a create-and-destroy report is never complete.
926
+ */
927
+ imageGb?: number
928
+ /**
929
+ * How long the image was retained. Defaults to the documented one-week minimum, marked
930
+ * projected — nobody timed that week either.
931
+ */
932
+ imageRetained?: Duration
933
+ /** Each cycle pays a snapshot write plus a read. */
934
+ suspendResumeCycles?: number
935
+ /** The suspend snapshot's size. Defaults to the baseline memory footprint. */
936
+ snapshotGb?: number
937
+ /** Whether a launch happened. A launch reads a snapshot. */
938
+ launched?: boolean
939
+ label?: string
940
+ }
941
+
942
+ /**
943
+ * The daemon's protocol constants, as a JSON string, for a caller asserting against the
944
+ * wire contract.
945
+ */
946
+ export declare function sessionConstants(): string
947
+
948
+ /** What a stdin write accomplished. */
949
+ export interface StdinAck {
950
+ execId: string
951
+ written: number
952
+ eof: boolean
953
+ }
954
+
955
+ /**
956
+ * One event off an exec's output stream.
957
+ *
958
+ * One object with a `kind` discriminant rather than three classes, because JS has no
959
+ * `instanceof` over a union a caller can `switch` on cleanly and the TypeScript idiom is a
960
+ * tagged union. `kind` is `"output"`, `"gap"`, or `"exit"`, and the fields for the other
961
+ * two shapes are `null` — which keeps [`Self::exit_code`] distinguishable from an output
962
+ * chunk that happens to be last. The absence of an `exit` event is what tells a cut
963
+ * connection from a finished command; the byte sequences are otherwise identical.
964
+ */
965
+ export interface StreamEvent {
966
+ /** `"output"`, `"gap"`, or `"exit"`. */
967
+ kind: string
968
+ /**
969
+ * `"stdout"` or `"stderr"`, for an output event. Both share one offset space, so a
970
+ * caller holds one cursor rather than two that can disagree about ordering.
971
+ */
972
+ stream?: string
973
+ /** Where an output chunk starts, or where a gap starts. */
974
+ offset?: number
975
+ /**
976
+ * One past an output chunk's last byte, or a gap's exclusive end — either way, where a
977
+ * cursor resumes. `null` on an exit event, whose offset is a *total* rather than a
978
+ * position, so resuming from it would ask the daemon to replay from the end.
979
+ */
980
+ end?: number
981
+ /** The bytes, for an output event. */
982
+ data?: Buffer
983
+ /** The bytes as text, replacing anything undecodable. `data` is the lossless form. */
984
+ text?: string
985
+ /** Total bytes published, on an exit event. */
986
+ totalOffset?: number
987
+ exitCode?: number
988
+ signal?: number
989
+ truncated?: boolean
990
+ writersMayBeAlive?: boolean
991
+ }
992
+
993
+ /** How a stream should behave. */
994
+ export interface StreamOptionsInput {
995
+ /** The byte to start at. Non-zero resumes a stream a previous process was reading. */
996
+ offset?: number
997
+ /**
998
+ * Whether to reconnect after a cut. `false` ends the stream at the cut instead, which
999
+ * is what a caller doing its own reconnection wants.
1000
+ */
1001
+ reconnect?: boolean
1002
+ /**
1003
+ * How many reconnects before giving up. A bound rather than forever, because a stream
1004
+ * that drops every time is a condition a caller needs reported.
1005
+ */
1006
+ maxReconnects?: number
1007
+ /**
1008
+ * Turns a gap into a rejection instead of an event. What a caller that must have
1009
+ * complete output wants.
1010
+ */
1011
+ errorOnGap?: boolean
1012
+ /** How long the body may be silent before the connection is treated as dead. */
1013
+ idleTimeout?: number
1014
+ }
1015
+
1016
+ /**
1017
+ * What a teardown should delete beyond the VM itself.
1018
+ *
1019
+ * Both deletions are opt-in, because both destroy something a caller may still want: the
1020
+ * image is reusable across runs, and the log group is where a failed build's only evidence
1021
+ * lives.
1022
+ */
1023
+ export interface TeardownOptions {
1024
+ deleteImage?: boolean
1025
+ /**
1026
+ * **Names** the group in `report.undeleted` rather than deleting it — CloudWatch is not
1027
+ * in the core's dependency set, and reporting a leak beats reporting a clean teardown
1028
+ * over one.
1029
+ */
1030
+ deleteLogGroup?: boolean
1031
+ deleteAttempts?: number
1032
+ deleteBackoff?: number
1033
+ /**
1034
+ * `false` by default: the caller is on the way out, and a teardown that blocked five
1035
+ * minutes on a state nobody reads is five minutes of a CI job. The report then honestly
1036
+ * ends in `"TERMINATING"`.
1037
+ */
1038
+ waitForTerminated?: boolean
1039
+ }
1040
+
1041
+ /** What a teardown did, and what it left behind. */
1042
+ export interface TeardownReport {
1043
+ /**
1044
+ * Identifiers of everything a caller asked to have deleted that still exists.
1045
+ *
1046
+ * Identifiers rather than a boolean, because a leak nobody can name is a leak nobody can
1047
+ * clean up. Two things land here: a delete that was attempted and failed, and the build
1048
+ * **log group**, which this client cannot delete at all.
1049
+ */
1050
+ undeleted: Array<string>
1051
+ /** Whether the terminate call was accepted. */
1052
+ terminateAccepted: boolean
1053
+ /** Whether the image was deleted, or `null` when deletion was not asked for. */
1054
+ imageDeleted?: boolean
1055
+ /**
1056
+ * The lifecycle state the sandbox ended in.
1057
+ *
1058
+ * Commonly `"TERMINATING"` rather than `"TERMINATED"`: the default teardown does not
1059
+ * wait, so claiming TERMINATED would claim an observation nobody made. Pass
1060
+ * `waitForTerminated: true` to observe it.
1061
+ */
1062
+ lifecycle?: string
1063
+ /**
1064
+ * Every failure the teardown swallowed, in the order it hit them.
1065
+ *
1066
+ * Kept because a teardown that never throws is a teardown whose failures are invisible
1067
+ * otherwise, and the first one is usually the cause of the rest.
1068
+ */
1069
+ failures: Array<string>
1070
+ /** Whether anything a caller asked for was left behind. */
1071
+ leaked: boolean
1072
+ }
1073
+
1074
+ /** Every daemon-status class, as `err.cause.cause.message` names them. */
1075
+ export declare function wireKinds(): Array<string>