microvms 0.0.0-stage → 1.0.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/README.md +159 -2
- package/index.d.ts +2933 -0
- package/index.js +756 -0
- package/microvms.darwin-arm64.node +0 -0
- package/microvms.linux-arm64-gnu.node +0 -0
- package/microvms.linux-x64-gnu.node +0 -0
- package/microvms.win32-x64-msvc.node +0 -0
- package/package.json +57 -4
package/index.d.ts
ADDED
|
@@ -0,0 +1,2933 @@
|
|
|
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. */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
declare global {
|
|
5
|
+
interface __NapiRsAsyncGenerator<TOwner, T, TReturn, TNext> {
|
|
6
|
+
next(...[value]: [] | [TNext]): globalThis.Promise<globalThis.IteratorResult<T, TReturn | undefined>>
|
|
7
|
+
return(...[value]: [] | [TReturn]): globalThis.Promise<globalThis.IteratorResult<T, TReturn | undefined>>
|
|
8
|
+
throw(exception?: unknown): globalThis.Promise<globalThis.IteratorResult<T, TReturn | undefined>>
|
|
9
|
+
[globalThis.Symbol.asyncIterator](): this
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* One VM with coding agents in it: the sandbox plus the specs it is built for.
|
|
15
|
+
*
|
|
16
|
+
* The sequence is the CLI's `agent-up` and `agent-prompt`, one method per step: `findImage`
|
|
17
|
+
* or `buildArtifact` + your upload + `buildImage`; `launch`; `installAccess`; `prompt` or
|
|
18
|
+
* `promptSync`; `terminate`. `sandbox()` and `session()` reach the same VM for suspend,
|
|
19
|
+
* resume, file transfer, and any other exec.
|
|
20
|
+
*/
|
|
21
|
+
export declare class AgentVm {
|
|
22
|
+
/**
|
|
23
|
+
* Resolves credentials for `region` and returns a VM with nothing built or launched.
|
|
24
|
+
*
|
|
25
|
+
* `agents` defaults to Claude Code alone. An empty list or a repeated agent is refused by
|
|
26
|
+
* the core before any AWS call.
|
|
27
|
+
*/
|
|
28
|
+
static create(region: Region, agents?: Array<AgentSpecInput> | undefined | null): Promise<AgentVm>
|
|
29
|
+
/** Adopts the agent VM registered as `name` in `registry`; see `Sandbox.fromName`. */
|
|
30
|
+
static fromName(region: Region, name: string, registry: NameRegistry, agents?: Array<AgentSpecInput> | undefined | null, port?: number | undefined | null): Promise<AgentVm>
|
|
31
|
+
/**
|
|
32
|
+
* An agent VM for a VM another process launched; see `Sandbox.adopt`.
|
|
33
|
+
*
|
|
34
|
+
* `agents` states what the VM carries and defaults to Claude Code alone; read
|
|
35
|
+
* `installedAgents(session)` first when the adopting process does not know.
|
|
36
|
+
*/
|
|
37
|
+
static adopt(region: Region, microvmId: string, endpoint: string, agentToken: string, agents?: Array<AgentSpecInput> | undefined | null, port?: number | undefined | null): Promise<AgentVm>
|
|
38
|
+
/** The specs this VM carries, resolved, in profile order. */
|
|
39
|
+
agents(): Array<AgentSpec>
|
|
40
|
+
region(): Region
|
|
41
|
+
/**
|
|
42
|
+
* The sandbox this VM drives, for suspend, resume, and the lifecycle getters. The same
|
|
43
|
+
* lock: a call here and a call there cannot interleave.
|
|
44
|
+
*/
|
|
45
|
+
sandbox(): Sandbox
|
|
46
|
+
/** The session, once `launch` has resolved. */
|
|
47
|
+
session(): Promise<Session | null>
|
|
48
|
+
/**
|
|
49
|
+
* The Dockerfile `buildImage` will send: the client's agentd stanza plus the agent
|
|
50
|
+
* layers. Nothing in it is a secret.
|
|
51
|
+
*/
|
|
52
|
+
dockerfile(): Promise<string>
|
|
53
|
+
/**
|
|
54
|
+
* The image name for these specs and this daemon binary: `agent-vm-<agents>-<hash12>`.
|
|
55
|
+
* Content-addressed, so an unchanged binary, spec set and size name the image a previous
|
|
56
|
+
* run built; `findImage` looks it up, and `ensureImage` builds or reuses it.
|
|
57
|
+
*/
|
|
58
|
+
imageName(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<string>
|
|
59
|
+
/** The ARN of an existing image named per `imageName`, or `null` when there is none. */
|
|
60
|
+
findImage(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<string | null>
|
|
61
|
+
/**
|
|
62
|
+
* Builds or reuses this VM's image, named per `imageName`: resolved at once when ready,
|
|
63
|
+
* waited on while building, deleted and rebuilt when failed, and uploaded to
|
|
64
|
+
* `s3://<s3Bucket>/<s3KeyPrefix>/<name>/artifact.zip` only when a build is needed.
|
|
65
|
+
*/
|
|
66
|
+
ensureImage(options: AgentEnsureOptions, size?: SizeClass | undefined | null): Promise<EnsuredImage>
|
|
67
|
+
/** The artifact bytes to upload to `s3://<bucket>/<imageName>.zip` before `buildImage`. */
|
|
68
|
+
buildArtifact(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<Buffer>
|
|
69
|
+
/**
|
|
70
|
+
* Builds the image and waits for it to become usable. `codeArtifactUri` is where you
|
|
71
|
+
* uploaded `buildArtifact`'s bytes. Several minutes, server-side.
|
|
72
|
+
*/
|
|
73
|
+
buildImage(options: AgentImageOptions, size?: SizeClass | undefined | null): Promise<Image>
|
|
74
|
+
/**
|
|
75
|
+
* Hands the VM off to another process; see `Sandbox.detach`. The adopter passes the
|
|
76
|
+
* same agents to `AgentVm.adopt`.
|
|
77
|
+
*/
|
|
78
|
+
detach(): Promise<Detached>
|
|
79
|
+
/**
|
|
80
|
+
* Launches with egress and waits for the daemon to answer.
|
|
81
|
+
*
|
|
82
|
+
* Egress is not optional: neither agent reaches Bedrock without it. The managed internet
|
|
83
|
+
* connector is the default; `egressNetworkConnectors` replaces it with customer-managed
|
|
84
|
+
* VPC connectors, whose VPC must route to Bedrock. The idle knobs default to the core's
|
|
85
|
+
* figures (ten-minute idle and suspended windows, a one-hour ceiling).
|
|
86
|
+
*/
|
|
87
|
+
launch(options: AgentLaunchOptions): Promise<Session>
|
|
88
|
+
/**
|
|
89
|
+
* Mints a token (or takes yours) and installs Bedrock access for this VM's agents.
|
|
90
|
+
*
|
|
91
|
+
* Resolves with the token used, so `expiresAt` says when to call this again. Re-runnable
|
|
92
|
+
* on a running VM: that call is the credential refresh.
|
|
93
|
+
*/
|
|
94
|
+
installAccess(token?: BearerToken | undefined | null, ttlSeconds?: number | undefined | null): Promise<BearerToken>
|
|
95
|
+
/** Starts one task for `agent` and resolves with its handle. Does not wait. */
|
|
96
|
+
prompt(agent: string, task: string, options?: PromptOptions | undefined | null): Promise<ExecHandle>
|
|
97
|
+
/**
|
|
98
|
+
* Start, wait, ack: one task's whole result. `timeoutSec` defaults to 900 seconds,
|
|
99
|
+
* because agent tasks run minutes, and is also the daemon-side budget.
|
|
100
|
+
*/
|
|
101
|
+
promptSync(agent: string, task: string, options?: PromptOptions | undefined | null): Promise<ExecResult>
|
|
102
|
+
/** Tears down, best-effort, never rejecting; see `Sandbox.terminate`. */
|
|
103
|
+
terminate(options?: TeardownOptions | undefined | null): Promise<TeardownReport>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* What a line item's cost can be: an estimate, or unpriced.
|
|
108
|
+
*
|
|
109
|
+
* `kind` is the stable tag, and exactly one of `usd`/`unpriced` is non-null — so a reader
|
|
110
|
+
* who checks either has handled both.
|
|
111
|
+
*/
|
|
112
|
+
export declare class Amount {
|
|
113
|
+
/** `"estimated-usd"` or `"unpriced"`. */
|
|
114
|
+
get kind(): string
|
|
115
|
+
/**
|
|
116
|
+
* The estimate, or `null` when there is no published rate.
|
|
117
|
+
*
|
|
118
|
+
* `null` rather than a zero — the one arithmetic this module refuses to enable.
|
|
119
|
+
*/
|
|
120
|
+
get usd(): EstimatedUsd | null
|
|
121
|
+
/** The unpriced half, or `null` when the line was priced. */
|
|
122
|
+
get unpriced(): Unpriced | null
|
|
123
|
+
toString(): string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* A Bedrock bearer token, the region it was minted for, and when it stops working.
|
|
128
|
+
*
|
|
129
|
+
* A class rather than an object because it carries a secret: `JSON.stringify` gives `{}` and
|
|
130
|
+
* only `expose()` returns the text.
|
|
131
|
+
*/
|
|
132
|
+
export declare class BearerToken {
|
|
133
|
+
/** The token text, for a caller writing it into an environment themselves. */
|
|
134
|
+
expose(): string
|
|
135
|
+
/**
|
|
136
|
+
* Effective Unix expiry, capped at the known signing credential expiry.
|
|
137
|
+
* With missing credential expiry metadata this is only an upper bound.
|
|
138
|
+
*/
|
|
139
|
+
get expiresAt(): number
|
|
140
|
+
/** The region the token was minted for. */
|
|
141
|
+
get region(): Region
|
|
142
|
+
/** The length of the token, never the token. */
|
|
143
|
+
toString(): string
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* A report's total judged against a budget: core's `Budget::check`, the verdict
|
|
148
|
+
* `microvm cost --max-cost` renders.
|
|
149
|
+
*/
|
|
150
|
+
export declare class BudgetVerdict {
|
|
151
|
+
/** The ceiling, as the caller wrote it. */
|
|
152
|
+
get maxUsd(): EstimatedUsd
|
|
153
|
+
/** `"warn"` or `"abort"`: what the caller said a breach does. */
|
|
154
|
+
get onBreach(): string
|
|
155
|
+
/** The total's floor: the whole estimate unless `isLowerBound`. */
|
|
156
|
+
get floor(): EstimatedUsd
|
|
157
|
+
/** Whether the floor is a lower bound, because a line is unpriced. */
|
|
158
|
+
get isLowerBound(): boolean
|
|
159
|
+
/** `"exact"` or `"lower-bound"`. */
|
|
160
|
+
get basis(): string
|
|
161
|
+
/** The phases whose lines are unpriced, sorted. */
|
|
162
|
+
get unpricedPhases(): Array<string>
|
|
163
|
+
/** Whether the floor is over the ceiling. At the ceiling is within it. */
|
|
164
|
+
get breached(): boolean
|
|
165
|
+
/** Whether the caller's judgement refuses the report: breached, under `"abort"`. */
|
|
166
|
+
get aborts(): boolean
|
|
167
|
+
/**
|
|
168
|
+
* How far over the ceiling the floor is, when breached; at least that much for a lower
|
|
169
|
+
* bound.
|
|
170
|
+
*/
|
|
171
|
+
get overage(): EstimatedUsd | null
|
|
172
|
+
/** One line for a human, the one `microvm cost --max-cost` prints. */
|
|
173
|
+
render(): string
|
|
174
|
+
/**
|
|
175
|
+
* Core's JSON shape for the verdict, as a JSON **string**: `maxUsd`, `onBreach`, `basis`,
|
|
176
|
+
* `breached`, `overageAtLeastUsd`.
|
|
177
|
+
*/
|
|
178
|
+
toJson(): string
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** A timeout for the `ready` or `validate` image-build hook: 1..=3600 seconds. */
|
|
182
|
+
export declare class BuildHookTimeout {
|
|
183
|
+
/** A build-family timeout, or a refusal naming both ceilings. */
|
|
184
|
+
constructor(seconds: number)
|
|
185
|
+
/** The service ceiling for this family: 3600. */
|
|
186
|
+
get maxSecs(): 3600
|
|
187
|
+
get seconds(): number
|
|
188
|
+
toString(): string
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* MicroVM lifecycle by ID (get, list, suspend, resume, terminate, and wait) and image
|
|
193
|
+
* administration (list, delete, versions and their status, builds).
|
|
194
|
+
*
|
|
195
|
+
* Holds no lifecycle state, so it checks nothing a `Sandbox` would (STATE-5, STATE-7,
|
|
196
|
+
* STATE-12). Use it when a process has only an identifier.
|
|
197
|
+
*/
|
|
198
|
+
export declare class ControlPlane {
|
|
199
|
+
/**
|
|
200
|
+
* Resolves credentials for `region` from the default chain. A factory because
|
|
201
|
+
* credential resolution is async.
|
|
202
|
+
*/
|
|
203
|
+
static create(region: Region): Promise<ControlPlane>
|
|
204
|
+
/** `GetMicrovm`. */
|
|
205
|
+
get(microvmId: string): Promise<Microvm>
|
|
206
|
+
/** `ListMicrovms`, every page, optionally narrowed to one image and version. */
|
|
207
|
+
list(options?: ListMicrovmsOptions | undefined | null): Promise<Array<MicrovmSummary>>
|
|
208
|
+
/** `SuspendMicrovm`. Resolves once accepted; `waitForState` for SUSPENDED. */
|
|
209
|
+
suspend(microvmId: string): Promise<void>
|
|
210
|
+
/** `ResumeMicrovm`. Resolves once accepted; `waitForState` for RUNNING. */
|
|
211
|
+
resume(microvmId: string): Promise<void>
|
|
212
|
+
/** `TerminateMicrovm`. Resolves once accepted; `waitForState` for TERMINATED. */
|
|
213
|
+
terminate(microvmId: string): Promise<void>
|
|
214
|
+
/**
|
|
215
|
+
* Polls `GetMicrovm` until the state is one of `wanted`.
|
|
216
|
+
*
|
|
217
|
+
* Reaching one of `failOn` first rejects naming the state and `stateReason`; running
|
|
218
|
+
* past `timeout` rejects with a timeout.
|
|
219
|
+
*/
|
|
220
|
+
waitForState(microvmId: string, wanted: Array<string>, options?: WaitForStateOptions | undefined | null): Promise<Microvm>
|
|
221
|
+
/** `ListMicrovmImages`, every page: every image in the account and region. */
|
|
222
|
+
listImages(): Promise<Array<ImageSummary>>
|
|
223
|
+
/**
|
|
224
|
+
* Deletes the image, its extra versions first, retrying while it refuses (an image still
|
|
225
|
+
* `CREATING`, or one a terminating VM holds).
|
|
226
|
+
*
|
|
227
|
+
* Resolves `true` once the service took the deletion and `false` when every attempt
|
|
228
|
+
* failed or `identifier` is not one the service accepts. It doesn't reject, as a
|
|
229
|
+
* teardown's delete shouldn't.
|
|
230
|
+
*/
|
|
231
|
+
deleteImage(identifier: string, options?: DeleteImageOptions | undefined | null): Promise<boolean>
|
|
232
|
+
/**
|
|
233
|
+
* `ListMicrovmImageVersions`, every page: each version, its status, and its build
|
|
234
|
+
* configuration.
|
|
235
|
+
*/
|
|
236
|
+
listImageVersions(identifier: string): Promise<Array<ImageVersion>>
|
|
237
|
+
/**
|
|
238
|
+
* `UpdateMicrovmImageVersion`: `status` is `"ACTIVE"` or `"INACTIVE"`.
|
|
239
|
+
*
|
|
240
|
+
* `INACTIVE` is the non-destructive retire: `RunMicrovm` refuses the version, running VMs
|
|
241
|
+
* keep running, and the version's readback stays. Resolves with the readback, and rejects
|
|
242
|
+
* when it doesn't carry the status asked for, so a 200 that didn't take isn't a rollback.
|
|
243
|
+
*/
|
|
244
|
+
setImageVersionStatus(identifier: string, version: string, status: string): Promise<ImageVersion>
|
|
245
|
+
/**
|
|
246
|
+
* `ListMicrovmImageBuilds` for one version, every page: one build per Graviton
|
|
247
|
+
* generation. Each `buildId` is what `getImageBuild` takes.
|
|
248
|
+
*/
|
|
249
|
+
listImageBuilds(identifier: string, version: string): Promise<Array<ImageBuild>>
|
|
250
|
+
/** `GetMicrovmImageBuild`: one build, with the snapshot sizes the listing doesn't carry. */
|
|
251
|
+
getImageBuild(identifier: string, version: string, buildId: string): Promise<ImageBuild>
|
|
252
|
+
/** The region this plane addresses. */
|
|
253
|
+
get region(): string
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Per-phase attribution for one sandbox, measured or projected. */
|
|
257
|
+
export declare class CostReport {
|
|
258
|
+
get label(): string
|
|
259
|
+
get size(): SizeClass
|
|
260
|
+
get rates(): RateTable
|
|
261
|
+
get items(): Array<LineItem>
|
|
262
|
+
/** The line items with a published rate. */
|
|
263
|
+
get priced(): Array<LineItem>
|
|
264
|
+
/** The line items with no published rate. */
|
|
265
|
+
get unpriced(): Array<LineItem>
|
|
266
|
+
/** The total, which is a lower bound whenever anything is unpriced. */
|
|
267
|
+
get total(): Total
|
|
268
|
+
/** False whenever any phase has no published rate. */
|
|
269
|
+
get complete(): boolean
|
|
270
|
+
/** True only if every duration was timed. An estimate is never this. */
|
|
271
|
+
get fullyMeasured(): boolean
|
|
272
|
+
/** The staleness warning the table carried when this was computed. */
|
|
273
|
+
get staleness(): string | null
|
|
274
|
+
/**
|
|
275
|
+
* The line items belonging to one phase.
|
|
276
|
+
*
|
|
277
|
+
* The string is judged by the core's own [`CostPhase::from_str`], which is where the
|
|
278
|
+
* closed set lives. This file used to carry its own seven-element table for it, as did
|
|
279
|
+
* `bindings/microvms-py/src/cost.rs` — two parallel lists over one enum, which would have gone
|
|
280
|
+
* stale the first time a phase was added and would have disagreed with each other in
|
|
281
|
+
* whichever direction was edited first.
|
|
282
|
+
*/
|
|
283
|
+
byPhase(phase: string): Array<LineItem>
|
|
284
|
+
/** Plain text, leading with what the dollars are rather than with the dollars. */
|
|
285
|
+
render(): string
|
|
286
|
+
/**
|
|
287
|
+
* Core's JSON shape for a report, as a JSON **string**: the one `microvm cost --json`
|
|
288
|
+
* and Python's `to_dict` emit (#255).
|
|
289
|
+
*
|
|
290
|
+
* A string for the same reason [`LineItem::to_json`] is: the unpriced line item omits
|
|
291
|
+
* its `usd` key, which no typed return shape can express.
|
|
292
|
+
*/
|
|
293
|
+
toJson(): string
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* What another process needs to adopt a VM handed off by `sandbox.detach()`.
|
|
298
|
+
*
|
|
299
|
+
* Pass the fields to `Sandbox.adopt(region, microvmId, endpoint, agentToken, port)`. The
|
|
300
|
+
* token is a method rather than a getter so it is never read by accident, and it is absent
|
|
301
|
+
* from `toString()`; `JSON.stringify` of the instance carries nothing.
|
|
302
|
+
*/
|
|
303
|
+
export declare class Detached {
|
|
304
|
+
get microvmId(): string
|
|
305
|
+
get endpoint(): string
|
|
306
|
+
/** The region the VM runs in, ready to pass to `Sandbox.adopt`. */
|
|
307
|
+
get region(): Region
|
|
308
|
+
/** The daemon port the endpoint's proxy tokens are minted for. */
|
|
309
|
+
get port(): number
|
|
310
|
+
/** The VM's bearer credential; store it only privately. */
|
|
311
|
+
agentToken(): string
|
|
312
|
+
/** Every field, token included, for a private encrypted store. */
|
|
313
|
+
toObject(): DetachedObject
|
|
314
|
+
/** The record without its secret. */
|
|
315
|
+
toString(): string
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Seconds, plus how we know them.
|
|
320
|
+
*
|
|
321
|
+
* No constructor: `Duration.measured(s)` and `Duration.projected(s)` are the only doors,
|
|
322
|
+
* so a provenance cannot be omitted. See the module docs.
|
|
323
|
+
*/
|
|
324
|
+
export declare class Duration {
|
|
325
|
+
/**
|
|
326
|
+
* A timed phase: a clock ran and this is what it read.
|
|
327
|
+
*
|
|
328
|
+
* Fallible because the float is — a negative or non-finite figure has no reading as a
|
|
329
|
+
* duration, and the refusal is the core's, message and all.
|
|
330
|
+
*/
|
|
331
|
+
static measured(seconds: number): Duration
|
|
332
|
+
/** A hypothetical phase: an estimate's input, or a documented minimum nobody timed. */
|
|
333
|
+
static projected(seconds: number): Duration
|
|
334
|
+
/** The span in seconds, without its label. */
|
|
335
|
+
get seconds(): number
|
|
336
|
+
/** `"measured"` or `"projected"`. */
|
|
337
|
+
get provenance(): string
|
|
338
|
+
/** True only for a timed span. What `CostReport.fullyMeasured` reads. */
|
|
339
|
+
get isMeasured(): boolean
|
|
340
|
+
/** `Ns (provenance)` — the label travels with the figure. */
|
|
341
|
+
toString(): string
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Dollars derived from published rates. Not the bill.
|
|
346
|
+
*
|
|
347
|
+
* # There is no way to get a number out of this
|
|
348
|
+
*
|
|
349
|
+
* No `valueOf`, no `toJSON`, no `Symbol.toPrimitive`, no `add`, and no constructor. So
|
|
350
|
+
* `Number(usd)` is `NaN`, `usd * 2` is `NaN`, `+usd` is `NaN`, and `JSON.stringify(usd)`
|
|
351
|
+
* answers `{}`. The figure comes out through [`Self::amount`], a **string** — one visible
|
|
352
|
+
* step that keeps the type name at the call site, which is a decision a reviewer can see.
|
|
353
|
+
*/
|
|
354
|
+
export declare class EstimatedUsd {
|
|
355
|
+
/**
|
|
356
|
+
* The figure as an exact decimal **string**.
|
|
357
|
+
*
|
|
358
|
+
* A string and not a number: a JS double cannot hold `0.0000276944` summed a few
|
|
359
|
+
* thousand times without drifting in the direction of a bill nobody can reproduce.
|
|
360
|
+
*/
|
|
361
|
+
get amount(): string
|
|
362
|
+
/** The figure at display precision: two places at a dollar or more, six below. */
|
|
363
|
+
get displayAmount(): string
|
|
364
|
+
/** `~$X (estimated)`. */
|
|
365
|
+
toString(): string
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* One exec, addressed by its caller-minted id.
|
|
370
|
+
*
|
|
371
|
+
* The id is the idempotency key, so a handle survives a process restart: rebuild it through
|
|
372
|
+
* `Session.exec(execId)` and every method still addresses the same server-side exec.
|
|
373
|
+
*/
|
|
374
|
+
export declare class ExecHandle {
|
|
375
|
+
get execId(): string
|
|
376
|
+
/** Reads current status and output. Read-only server-side; safe to spin on. */
|
|
377
|
+
poll(): Promise<ExecResult>
|
|
378
|
+
/**
|
|
379
|
+
* Polls until the exec is done, or rejects with `ERR_TIMEOUT`.
|
|
380
|
+
*
|
|
381
|
+
* A timeout has not touched the exec — polling is read-only and output lives until it
|
|
382
|
+
* is acked — so a caller that gives up can come back and poll again.
|
|
383
|
+
*/
|
|
384
|
+
wait(timeout?: number | undefined | null): Promise<ExecResult>
|
|
385
|
+
/**
|
|
386
|
+
* An async iterator over output as it arrives, reconnecting at the last good offset.
|
|
387
|
+
*
|
|
388
|
+
* `for await (const event of handle.stream())`.
|
|
389
|
+
*/
|
|
390
|
+
stream(options?: StreamOptionsInput | undefined | null): ExecStream
|
|
391
|
+
/**
|
|
392
|
+
* Writes to the child's stdin. Requires the exec to have been started with
|
|
393
|
+
* `stdin: true`, or the daemon answers 409.
|
|
394
|
+
*
|
|
395
|
+
* `eof` in the same call is the common case for feeding a prompt: two round trips would
|
|
396
|
+
* leave a window where the child has the bytes but not the EOF that says the input is
|
|
397
|
+
* complete.
|
|
398
|
+
*/
|
|
399
|
+
writeStdin(data: Uint8Array, eof?: boolean | undefined | null): Promise<StdinAck>
|
|
400
|
+
/**
|
|
401
|
+
* Sends EOF. Nothing else closes stdin: the daemon's copy of the pipe outlives the
|
|
402
|
+
* child's wait, so a child blocked reading stdin hangs until its timeout otherwise.
|
|
403
|
+
*/
|
|
404
|
+
closeStdin(): Promise<StdinAck>
|
|
405
|
+
/** Releases the buffered output and starts the TTL clock. */
|
|
406
|
+
ack(): Promise<ExecResult>
|
|
407
|
+
/**
|
|
408
|
+
* Signals the whole process group. `false` means nothing was signalled because the
|
|
409
|
+
* child had already been reaped — which is the outcome a kill wanted.
|
|
410
|
+
*/
|
|
411
|
+
kill(): Promise<boolean>
|
|
412
|
+
/**
|
|
413
|
+
* Wait, then ack, returning the result that carries the output.
|
|
414
|
+
*
|
|
415
|
+
* Which result comes back matters: the ack response carries the released output and a
|
|
416
|
+
* poll issued after the ack reports `acked` with none, so returning the wrong one is a
|
|
417
|
+
* silent empty-output bug. The core sequences it.
|
|
418
|
+
*/
|
|
419
|
+
waitAndAck(timeout?: number | undefined | null): Promise<ExecResult>
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* A long-running exec as the AI SDK's `SandboxProcess` shape.
|
|
424
|
+
*
|
|
425
|
+
* See the module docs. Built by `Session.spawn`, never by a constructor: a process object
|
|
426
|
+
* with no exec behind it is one whose every method fails in a way that looks like a dead VM.
|
|
427
|
+
*/
|
|
428
|
+
export declare class ExecProcess {
|
|
429
|
+
/**
|
|
430
|
+
* The exec id, which is the idempotency key.
|
|
431
|
+
*
|
|
432
|
+
* Read it back to reattach from another process: `session.exec(id)` addresses the same
|
|
433
|
+
* server-side exec, and `session.spawn` with the same id does not start a second child.
|
|
434
|
+
*/
|
|
435
|
+
get execId(): string
|
|
436
|
+
/**
|
|
437
|
+
* The process id, if the sandbox exposes one.
|
|
438
|
+
*
|
|
439
|
+
* **Always `null`**, and that is a true answer rather than a stub. The daemon signals a
|
|
440
|
+
* whole process group and addresses an exec by its caller-minted id; it publishes no pid,
|
|
441
|
+
* because a pid inside a MicroVM is not meaningful outside it and would invite a caller to
|
|
442
|
+
* signal it directly through a channel that does not exist. The harness contract marks
|
|
443
|
+
* `pid` optional for exactly this case.
|
|
444
|
+
*/
|
|
445
|
+
get pid(): number | null
|
|
446
|
+
/**
|
|
447
|
+
* The child's standard output as a stream of bytes.
|
|
448
|
+
*
|
|
449
|
+
* One stream per process: reading this twice hands back the same object, because two
|
|
450
|
+
* readers over one channel would split the bytes between them.
|
|
451
|
+
*/
|
|
452
|
+
get stdout(): ReadableStream<Uint8Array>
|
|
453
|
+
/**
|
|
454
|
+
* The child's standard error as a stream of bytes.
|
|
455
|
+
*
|
|
456
|
+
* Independent of [`Self::stdout`]: order is preserved within each and is not recoverable
|
|
457
|
+
* between them, which is what the wire supports (one shared offset space) and what the
|
|
458
|
+
* harness shape promises.
|
|
459
|
+
*/
|
|
460
|
+
get stderr(): ReadableStream<Uint8Array>
|
|
461
|
+
/**
|
|
462
|
+
* Every byte range the daemon could not replay, under `gapPolicy: 'event'`.
|
|
463
|
+
*
|
|
464
|
+
* Empty under the default policy, where a gap errors the streams instead — see the module
|
|
465
|
+
* docs for why the ignorable form is not the default.
|
|
466
|
+
*/
|
|
467
|
+
get gaps(): Array<OutputGap>
|
|
468
|
+
/**
|
|
469
|
+
* Resolves when the process exits.
|
|
470
|
+
*
|
|
471
|
+
* **From the daemon's exec record, not from the streams ending**, and that is the whole
|
|
472
|
+
* reason a suspend/resume does not look like a clean exit here: a stream that stopped
|
|
473
|
+
* carrying bytes is a stream that stopped, which is the identical observation for a cut
|
|
474
|
+
* connection and a finished command. Only the daemon's record distinguishes them.
|
|
475
|
+
*
|
|
476
|
+
* Rejects with `ERR_TIMEOUT` past `timeoutSeconds` (300 by default). A timeout has not
|
|
477
|
+
* touched the exec — polling is read-only and the output lives until it is acked — so a
|
|
478
|
+
* caller that gives up can call this again.
|
|
479
|
+
*/
|
|
480
|
+
wait(timeoutSeconds?: number | undefined | null): Promise<ProcessExit>
|
|
481
|
+
/**
|
|
482
|
+
* Terminates the process. Idempotent.
|
|
483
|
+
*
|
|
484
|
+
* Signals the whole process group rather than the direct child, so a shell's children go
|
|
485
|
+
* with it. Idempotent because the daemon answers 200 either way: a group that had already
|
|
486
|
+
* been reaped reports nothing signalled, which is the outcome a kill wanted — so a second
|
|
487
|
+
* call is a success and not a 404. That is what lets a harness call this in a `finally`
|
|
488
|
+
* without guarding it.
|
|
489
|
+
*/
|
|
490
|
+
kill(): Promise<void>
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* A JS async iterator over an exec's output.
|
|
495
|
+
*
|
|
496
|
+
* Loop over the stream itself: `for await (const event of handle.stream())`. The object
|
|
497
|
+
* `[Symbol.asyncIterator]()` returns has `next`, `return` and `throw` and no
|
|
498
|
+
* `[Symbol.asyncIterator]()` of its own, though its generated type, `__NapiRsAsyncGenerator`,
|
|
499
|
+
* declares one. So `for await` over that object type-checks, then throws a `TypeError`
|
|
500
|
+
* because it isn't async iterable (#262).
|
|
501
|
+
*
|
|
502
|
+
* See the module docs for why this is a task and a bounded channel. The receiver is behind
|
|
503
|
+
* a tokio `Mutex` because `AsyncGenerator::next` must answer a `Send + 'static` future, so
|
|
504
|
+
* the guard is taken *inside* that future rather than borrowed from `&mut self`.
|
|
505
|
+
*
|
|
506
|
+
* This type implements JavaScript's async iterable protocol.
|
|
507
|
+
* It can be used with `for await...of` loops.
|
|
508
|
+
*
|
|
509
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols
|
|
510
|
+
*/
|
|
511
|
+
export declare class ExecStream {
|
|
512
|
+
|
|
513
|
+
[globalThis.Symbol.asyncIterator](): globalThis.__NapiRsAsyncGenerator<ExecStream, StreamEvent, void, undefined>
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* A running keepalive. Call `stop()` when the work is done; `done()` resolves when it
|
|
518
|
+
* ends on its own. A garbage-collected handle stops the keepalive.
|
|
519
|
+
*/
|
|
520
|
+
export declare class KeepAwake {
|
|
521
|
+
/** Whether the keepalive is still polling. */
|
|
522
|
+
get running(): boolean
|
|
523
|
+
/** Stops polling and resolves with the report; rejects with the error that ended it. */
|
|
524
|
+
stop(): Promise<KeepAwakeReport>
|
|
525
|
+
/** Resolves when the keepalive ends (`whileBusy`, `maxDurationSec`, or `stop()`). */
|
|
526
|
+
done(): Promise<KeepAwakeReport>
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/** One phase's one billing line: what was consumed, and what that costs. */
|
|
530
|
+
export declare class LineItem {
|
|
531
|
+
get phase(): string
|
|
532
|
+
/**
|
|
533
|
+
* The AWS billing line, or `null` for a phase with no published rate to attribute it
|
|
534
|
+
* to.
|
|
535
|
+
*/
|
|
536
|
+
get line(): string | null
|
|
537
|
+
/**
|
|
538
|
+
* The consumed quantity, exact, as a string.
|
|
539
|
+
*
|
|
540
|
+
* Exact so a reader can check the arithmetic against the rate table, which is the only
|
|
541
|
+
* defence against a rate that drifts without anyone noticing.
|
|
542
|
+
*/
|
|
543
|
+
get quantity(): string
|
|
544
|
+
/** The quantity at display precision, for a column a human scans. */
|
|
545
|
+
get displayQuantity(): string
|
|
546
|
+
get unit(): string
|
|
547
|
+
get amount(): Amount
|
|
548
|
+
get duration(): Duration | null
|
|
549
|
+
get note(): string
|
|
550
|
+
/**
|
|
551
|
+
* Core's JSON shape for a line item, as a JSON **string**.
|
|
552
|
+
*
|
|
553
|
+
* A string rather than an object because the unpriced case must **omit** the `usd` key
|
|
554
|
+
* entirely, and a `#[napi(object)]` return type cannot express an absent key — an
|
|
555
|
+
* `Option` field serializes as `null`, which is the one value that gets summed as zero
|
|
556
|
+
* by anything permissive. A caller does `JSON.parse`, which is one visible step.
|
|
557
|
+
*/
|
|
558
|
+
toJson(): string
|
|
559
|
+
toString(): string
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/** One named VM: everything `Sandbox.adopt` needs, under a name. */
|
|
563
|
+
export declare class NameRecord {
|
|
564
|
+
/**
|
|
565
|
+
* A record for a VM this process can already address. Refuses an illegal name or an
|
|
566
|
+
* empty id, endpoint, or token.
|
|
567
|
+
*/
|
|
568
|
+
constructor(name: string, microvmId: string, endpoint: string, agentToken: string, region: Region)
|
|
569
|
+
/** A record naming the VM `sandbox` addresses — launched or adopted. */
|
|
570
|
+
static forSandbox(name: string, sandbox: Sandbox): Promise<NameRecord>
|
|
571
|
+
/** A record from `toObject()` output (or a CLI registry file's JSON), checked. */
|
|
572
|
+
static fromObject(object: NameRecordObject): NameRecord
|
|
573
|
+
/**
|
|
574
|
+
* The record as a plain object, **agent token included** — the form to store privately
|
|
575
|
+
* and read back with `fromObject`.
|
|
576
|
+
*/
|
|
577
|
+
toObject(): NameRecordObject
|
|
578
|
+
get name(): string
|
|
579
|
+
get microvmId(): string
|
|
580
|
+
get endpoint(): string
|
|
581
|
+
/**
|
|
582
|
+
* The VM's bearer credential. A method rather than a getter, so it is never read by
|
|
583
|
+
* accident; store it only privately.
|
|
584
|
+
*/
|
|
585
|
+
agentToken(): string
|
|
586
|
+
get region(): string
|
|
587
|
+
/** Seconds since the epoch when the name was registered. */
|
|
588
|
+
get at(): number
|
|
589
|
+
get egressPosture(): string | null
|
|
590
|
+
/**
|
|
591
|
+
* The VM's tunnel identity, when it was launched with `identity: true`; `null` otherwise.
|
|
592
|
+
*
|
|
593
|
+
* Throws when the record carries one half of the pair, or a half that doesn't decode: the
|
|
594
|
+
* record claims a verifiable VM, and reading it as unverifiable would hide that it's
|
|
595
|
+
* broken. A method, like `agentToken()`, because it holds the host's secret half.
|
|
596
|
+
*/
|
|
597
|
+
tunnelIdentity(): TunnelIdentity | null
|
|
598
|
+
/** The record without its secrets. */
|
|
599
|
+
toString(): string
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* The CLI's name registry: one owner-only JSON file per name under `<stateDir>/names/`.
|
|
604
|
+
*
|
|
605
|
+
* `stateDir` defaults to the CLI's — `$MICROVM_STATE_DIR`, else `~/.microvm/runs` — so a
|
|
606
|
+
* name registered here resolves in `microvm exec --name` and the reverse.
|
|
607
|
+
*/
|
|
608
|
+
export declare class NameRegistry {
|
|
609
|
+
constructor(stateDir?: string | undefined | null)
|
|
610
|
+
/** The directory holding the name files. */
|
|
611
|
+
get directory(): string
|
|
612
|
+
/**
|
|
613
|
+
* The record registered as `name`, or `null`. A file that exists but does not parse
|
|
614
|
+
* throws rather than reading as free.
|
|
615
|
+
*/
|
|
616
|
+
get(name: string): NameRecord | null
|
|
617
|
+
/** Writes `record` under its name, replacing any earlier record, owner-only on Unix. */
|
|
618
|
+
put(record: NameRecord): void
|
|
619
|
+
/** Names the VM `sandbox` addresses and writes the record; resolves with it. */
|
|
620
|
+
register(name: string, sandbox: Sandbox): Promise<NameRecord>
|
|
621
|
+
/** Removes `name`, answering whether a record was there. */
|
|
622
|
+
delete(name: string): boolean
|
|
623
|
+
/** Every readable record, sorted by name. */
|
|
624
|
+
list(): Array<NameRecord>
|
|
625
|
+
/**
|
|
626
|
+
* Removes every name registered to `microvmId` and returns them — the step after a
|
|
627
|
+
* terminate, so no name outlives its VM.
|
|
628
|
+
*/
|
|
629
|
+
releaseByVm(microvmId: string): Array<string>
|
|
630
|
+
/**
|
|
631
|
+
* Registers a record this registry didn't write, once the VM has answered one
|
|
632
|
+
* authenticated request with the record's token; resolves with whether it refreshed a
|
|
633
|
+
* record of the same VM.
|
|
634
|
+
*
|
|
635
|
+
* `session` must be attached with the record's endpoint and token (`Session.attach` from
|
|
636
|
+
* its fields). A name held by another VM, or by an unreadable file, is refused before any
|
|
637
|
+
* request, and a probe the daemon refuses writes nothing. Core's `names::import`, the rule
|
|
638
|
+
* `microvm attach` applies.
|
|
639
|
+
*/
|
|
640
|
+
importRecord(record: NameRecord, session: Session): Promise<boolean>
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* A running port-forward. Call `stop()` when done; a garbage-collected handle stops the
|
|
645
|
+
* forward and cuts its open connections.
|
|
646
|
+
*/
|
|
647
|
+
export declare class PortForward {
|
|
648
|
+
/** The local address to connect to, `host:port`, with the port the OS picked. */
|
|
649
|
+
get localAddress(): string
|
|
650
|
+
/** Whether the forward is still serving. */
|
|
651
|
+
get running(): boolean
|
|
652
|
+
/**
|
|
653
|
+
* Stops accepting, waits for the connections still open to end, and resolves with the
|
|
654
|
+
* report.
|
|
655
|
+
*
|
|
656
|
+
* With `timeout` (seconds), connections still open after it are cut and listed as
|
|
657
|
+
* `"failed"`. Without it, a client that keeps its connection open keeps this waiting.
|
|
658
|
+
* Callable again, with the same report.
|
|
659
|
+
*/
|
|
660
|
+
stop(timeout?: number | undefined | null): Promise<PortForwardReport>
|
|
661
|
+
/** The handle without its credentials. */
|
|
662
|
+
toString(): string
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/** The pinned rate table, and everything it says about itself. */
|
|
666
|
+
export declare class RateTable {
|
|
667
|
+
/**
|
|
668
|
+
* us-east-1, read 2026-08-07, as recorded in `docs/PLATFORM.md`.
|
|
669
|
+
*
|
|
670
|
+
* There is deliberately no constructor taking rates. The core's table has private rate
|
|
671
|
+
* fields and exactly two doors — this one and `from_catalog`, which refuses a catalog
|
|
672
|
+
* whose ARM compute line is missing rather than substituting the x86 one, 17.9% higher
|
|
673
|
+
* (COST-9). A constructor taking five numbers would reopen precisely that.
|
|
674
|
+
*/
|
|
675
|
+
static pinned(): RateTable
|
|
676
|
+
get region(): string
|
|
677
|
+
get sourceUrl(): string
|
|
678
|
+
/** ISO 8601, matching the Python's `retrieved.isoformat()`. */
|
|
679
|
+
get retrieved(): string
|
|
680
|
+
get vcpuSecond(): string
|
|
681
|
+
get gbSecond(): string
|
|
682
|
+
/**
|
|
683
|
+
* Per GB-month. The one derived figure: the API quotes per GB-hour, and this is that
|
|
684
|
+
* times 730.
|
|
685
|
+
*/
|
|
686
|
+
get storageGbMonth(): string
|
|
687
|
+
get snapshotReadGb(): string
|
|
688
|
+
get snapshotWriteGb(): string
|
|
689
|
+
/** Snapshot storage bills at least this long however briefly the snapshot exists. */
|
|
690
|
+
get minimumRetentionSeconds(): number
|
|
691
|
+
/** Zero: MicroVMs bills per second with no per-request charge. */
|
|
692
|
+
get perRequest(): string
|
|
693
|
+
/** True: vCPU and memory are two line items, as the pricing page prices them. */
|
|
694
|
+
get billsVcpuAndMemorySeparately(): boolean
|
|
695
|
+
/** False: no published MicroVMs free tier. The Lambda one is Functions-only. */
|
|
696
|
+
get freeTier(): boolean
|
|
697
|
+
/**
|
|
698
|
+
* `null` means **not published**, not one second. Nothing rounds a duration up, because
|
|
699
|
+
* inventing an increment would overcharge every short exec.
|
|
700
|
+
*/
|
|
701
|
+
get minimumBillingIncrementSec(): number | null
|
|
702
|
+
/** How many days ago these rates were read, against today UTC. */
|
|
703
|
+
ageDays(): number
|
|
704
|
+
/** The staleness warning, or `null` when the table is fresh. */
|
|
705
|
+
staleness(): string | null
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/** An AWS region, closed over the five that run MicroVMs plus a named escape hatch. */
|
|
709
|
+
export declare class Region {
|
|
710
|
+
static usEast1(): Region
|
|
711
|
+
static usEast2(): Region
|
|
712
|
+
static usWest2(): Region
|
|
713
|
+
static euWest1(): Region
|
|
714
|
+
static apNortheast1(): Region
|
|
715
|
+
/**
|
|
716
|
+
* One of the five, or a refusal naming the null-message trap.
|
|
717
|
+
*
|
|
718
|
+
* The boundary a region name arrives at from an environment variable or a config file,
|
|
719
|
+
* where it is still a string. The refusal is the core's `FromStr`, message and all —
|
|
720
|
+
* this is a call, not a check written here.
|
|
721
|
+
*/
|
|
722
|
+
static parse(name: string): Region
|
|
723
|
+
/**
|
|
724
|
+
* Opts into a region this client has not seen carry MicroVMs.
|
|
725
|
+
*
|
|
726
|
+
* **This costs you the diagnostic.** If the region does not run MicroVMs, the first
|
|
727
|
+
* control-plane call answers `AccessDeniedException` with a null message, and you will
|
|
728
|
+
* spend the next hour reading an IAM policy that is correct. Named rather than a flag so
|
|
729
|
+
* a reader of the call site can see the opt-in.
|
|
730
|
+
*
|
|
731
|
+
* A supported name handed here comes back as its proper region, so
|
|
732
|
+
* `Region.unlisted("us-east-1")` equals `Region.usEast1()`.
|
|
733
|
+
*/
|
|
734
|
+
static unlisted(name: string): Region
|
|
735
|
+
/** Every region this client has seen carry MicroVMs. */
|
|
736
|
+
static supported(): Array<Region>
|
|
737
|
+
/** The wire spelling, which is also the endpoint's middle segment. */
|
|
738
|
+
get name(): string
|
|
739
|
+
/** Whether this is one of the five rather than an opted-into unlisted name. */
|
|
740
|
+
get isSupported(): boolean
|
|
741
|
+
toString(): string
|
|
742
|
+
/**
|
|
743
|
+
* Whether two regions are the same one.
|
|
744
|
+
*
|
|
745
|
+
* A method and not `===`: JS compares class instances by reference, so two
|
|
746
|
+
* `Region.usEast1()` calls are different objects. Named `equals` because that is what a
|
|
747
|
+
* JS reader expects to reach for.
|
|
748
|
+
*/
|
|
749
|
+
equals(other: Region): boolean
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/** Running versus suspended for the same VM over the same wall time. */
|
|
753
|
+
export declare class ResidencyComparison {
|
|
754
|
+
get size(): SizeClass
|
|
755
|
+
/**
|
|
756
|
+
* The wall time both sides cover. Always projected: a comparison is a hypothetical
|
|
757
|
+
* about a hold nobody has taken yet.
|
|
758
|
+
*/
|
|
759
|
+
get hold(): Duration
|
|
760
|
+
get cycles(): number
|
|
761
|
+
get running(): CostReport
|
|
762
|
+
get suspended(): CostReport
|
|
763
|
+
/** How many times more the running VM costs, as an exact decimal string. */
|
|
764
|
+
get ratio(): string
|
|
765
|
+
/**
|
|
766
|
+
* One suspend/resume: a snapshot write plus a read, per GB.
|
|
767
|
+
*
|
|
768
|
+
* Without it the honest conclusion inverts — "suspend constantly" reads as free.
|
|
769
|
+
*/
|
|
770
|
+
perCycle(): EstimatedUsd
|
|
771
|
+
/**
|
|
772
|
+
* How long a VM must stay suspended for the cycle to pay for itself, exact, as a
|
|
773
|
+
* string. The number a pool scheduler needs, and the one a "100x cheaper" headline
|
|
774
|
+
* hides.
|
|
775
|
+
*/
|
|
776
|
+
breakEvenSeconds(): string
|
|
777
|
+
/**
|
|
778
|
+
* The break-even hold as a number. **Lossy, and named so.**
|
|
779
|
+
*
|
|
780
|
+
* Seconds, not dollars: no money figure has a numeric accessor anywhere in this file.
|
|
781
|
+
*/
|
|
782
|
+
breakEvenSecondsNumber(): number
|
|
783
|
+
render(): string
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* A timeout for the `run`, `resume`, `suspend`, or `terminate` hook: 1..=60 seconds.
|
|
788
|
+
*
|
|
789
|
+
* A distinct class from [`BuildHookTimeout`] and deliberately not interchangeable with it.
|
|
790
|
+
*/
|
|
791
|
+
export declare class RunHookTimeout {
|
|
792
|
+
/** A run-family timeout, or a refusal naming **both** ceilings. */
|
|
793
|
+
constructor(seconds: number)
|
|
794
|
+
/** The service ceiling for this family: 60. */
|
|
795
|
+
get maxSecs(): 60
|
|
796
|
+
get seconds(): number
|
|
797
|
+
toString(): string
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* One MicroVM's whole life.
|
|
802
|
+
*
|
|
803
|
+
* The five transitions are `buildImage`, `run`, `suspend`, `resume`, and `terminate`, and
|
|
804
|
+
* every state guard lives in the core — see the module docs.
|
|
805
|
+
*/
|
|
806
|
+
export declare class Sandbox {
|
|
807
|
+
/**
|
|
808
|
+
* Resolves credentials for `region` and returns a sandbox with nothing launched.
|
|
809
|
+
*
|
|
810
|
+
* A factory rather than a constructor because credential resolution is async, and a
|
|
811
|
+
* `#[napi(constructor)]` cannot be. `region` is a [`Region`] instance and not a string,
|
|
812
|
+
* which is TRAP-6 at this boundary.
|
|
813
|
+
*/
|
|
814
|
+
static create(region: Region): Promise<Sandbox>
|
|
815
|
+
/**
|
|
816
|
+
* The lifecycle state: `"PENDING"`, `"RUNNING"`, `"SUSPENDING"`, `"SUSPENDED"`,
|
|
817
|
+
* `"TERMINATING"`, or `"TERMINATED"`.
|
|
818
|
+
*
|
|
819
|
+
* Spelled as the service spells it, because a reader compares it against a `GetMicrovm`
|
|
820
|
+
* response and `Suspended` beside `SUSPENDED` reads like two facts.
|
|
821
|
+
*/
|
|
822
|
+
lifecycle(): Promise<string>
|
|
823
|
+
/**
|
|
824
|
+
* Whether the agent token has been installed (STATE-2).
|
|
825
|
+
*
|
|
826
|
+
* Set by the platform reporting RUNNING, not by the launch call: the run hook is what
|
|
827
|
+
* delivers the token, and a launch that died during startup delivered nothing.
|
|
828
|
+
*/
|
|
829
|
+
tokenInstalled(): Promise<boolean>
|
|
830
|
+
/** Whether an image is recorded as existing (STATE-1). */
|
|
831
|
+
imageExists(): Promise<boolean>
|
|
832
|
+
/** Whether this VM was ever terminated (STATE-11). */
|
|
833
|
+
wasTerminated(): Promise<boolean>
|
|
834
|
+
/** How many times the token has been installed. Never above one (STATE-3). */
|
|
835
|
+
bootstrapCount(): Promise<number>
|
|
836
|
+
/**
|
|
837
|
+
* A sandbox for a VM another process launched, from its private record.
|
|
838
|
+
*
|
|
839
|
+
* The lifecycle is read from `GetMicrovm`, so suspend, resume, and terminate start from
|
|
840
|
+
* the service's state and keep every guard. The VM was bootstrapped by its own launch,
|
|
841
|
+
* so `run` is refused and no run-hook payload is ever sent. Never publish or log
|
|
842
|
+
* `agentToken`; it appears in no error.
|
|
843
|
+
*/
|
|
844
|
+
static adopt(region: Region, microvmId: string, endpoint: string, agentToken: string, port?: number | undefined | null): Promise<Sandbox>
|
|
845
|
+
/**
|
|
846
|
+
* Adopts the VM registered as `name` in `registry`; see `Sandbox.adopt`.
|
|
847
|
+
*
|
|
848
|
+
* `region` must match the record's: an id from another region addresses nothing here.
|
|
849
|
+
*/
|
|
850
|
+
static fromName(region: Region, name: string, registry: NameRegistry, port?: number | undefined | null): Promise<Sandbox>
|
|
851
|
+
/** Whether this sandbox was built by `adopt` rather than by its own launch. */
|
|
852
|
+
adopted(): Promise<boolean>
|
|
853
|
+
/**
|
|
854
|
+
* Hands the VM off to another process and resolves with what that process adopts it
|
|
855
|
+
* with.
|
|
856
|
+
*
|
|
857
|
+
* For a workflow whose steps run in different processes: the launching step calls this
|
|
858
|
+
* instead of dropping the sandbox (which warns that a live VM was abandoned), persists
|
|
859
|
+
* the record privately, and a later step calls `Sandbox.adopt` with it. The VM keeps
|
|
860
|
+
* running and no AWS call is made. Afterwards this sandbox is inert: `run`,
|
|
861
|
+
* `waitUntilRunning`, `suspend`, `resume`, and `terminate` are refused. Rejects with
|
|
862
|
+
* `ERR_PRECONDITION` without a live VM or when already detached.
|
|
863
|
+
*/
|
|
864
|
+
detach(): Promise<Detached>
|
|
865
|
+
/** Whether `detach()` handed this sandbox's VM to another process. */
|
|
866
|
+
isDetached(): Promise<boolean>
|
|
867
|
+
/** The VM id, once launched. */
|
|
868
|
+
microvmId(): Promise<string | null>
|
|
869
|
+
/** The proxy endpoint, once launched. */
|
|
870
|
+
endpoint(): Promise<string | null>
|
|
871
|
+
/**
|
|
872
|
+
* The image ARN `run` sent in `RunMicrovm`: the caller's identifier with a bare name
|
|
873
|
+
* resolved, or the built image's.
|
|
874
|
+
*
|
|
875
|
+
* Recorded before the call, so a launch the service refused still names the image it
|
|
876
|
+
* asked for. `null` until `run` has resolved an image, and on an adopted sandbox.
|
|
877
|
+
*/
|
|
878
|
+
launchImageArn(): Promise<string | null>
|
|
879
|
+
/**
|
|
880
|
+
* Why the VM is in its current state, when the service said.
|
|
881
|
+
*
|
|
882
|
+
* The absence is information: TRAP-8's message distinguishes "no stateReason" from an
|
|
883
|
+
* empty one.
|
|
884
|
+
*/
|
|
885
|
+
stateReason(): Promise<string | null>
|
|
886
|
+
/** The image, once built. */
|
|
887
|
+
image(): Promise<Image | null>
|
|
888
|
+
/**
|
|
889
|
+
* The suspended window this sandbox asked for at launch, in seconds.
|
|
890
|
+
*
|
|
891
|
+
* `null` before this sandbox launches a VM. This accessor reports the requested
|
|
892
|
+
* window; `GetMicrovm` also returns the service's idle policy.
|
|
893
|
+
*/
|
|
894
|
+
suspendedWindowSecondsAsync(): Promise<number | null>
|
|
895
|
+
/**
|
|
896
|
+
* The tunnel identity a launch with `identity: true` generated, or that an adopted record
|
|
897
|
+
* carried; `null` otherwise.
|
|
898
|
+
*
|
|
899
|
+
* Holds the host's secret half: pass it to `session.tunnel(...)`, and store it only
|
|
900
|
+
* where the agent token goes.
|
|
901
|
+
*/
|
|
902
|
+
tunnelIdentity(): Promise<TunnelIdentity | null>
|
|
903
|
+
/**
|
|
904
|
+
* The session, once launched.
|
|
905
|
+
*
|
|
906
|
+
* A new wrapper each call, all reaching the same session under the same lock. There is no
|
|
907
|
+
* cached instance: caching one would mean a session object that outlives the VM it
|
|
908
|
+
* addresses, and the indirection exists precisely so a post-terminate call reports the
|
|
909
|
+
* lifecycle rather than a dangling handle.
|
|
910
|
+
*/
|
|
911
|
+
session(): Promise<Session | null>
|
|
912
|
+
/**
|
|
913
|
+
* Builds an image and waits for it to become usable.
|
|
914
|
+
*
|
|
915
|
+
* Every local guard runs **before** the call, which matters because the create happens
|
|
916
|
+
* after the caller's artifact upload: a rejection AWS raises costs the upload first.
|
|
917
|
+
*/
|
|
918
|
+
buildImage(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<Image>
|
|
919
|
+
/**
|
|
920
|
+
* Builds or reuses the content-addressed image for a task: one call from build inputs
|
|
921
|
+
* to a ready image.
|
|
922
|
+
*
|
|
923
|
+
* The name is `<namePrefix>-<hash12>` over the daemon, the Dockerfile, the build
|
|
924
|
+
* context, the base image and the size class. A ready image is returned with
|
|
925
|
+
* `reused: true` and no upload; a running build is waited out; a failed image — or any
|
|
926
|
+
* image under `force` — is deleted and rebuilt; an absent one is uploaded to
|
|
927
|
+
* `s3://<s3Bucket>/<s3KeyPrefix>/<name>/artifact.zip`, created, and waited for. When a
|
|
928
|
+
* concurrent caller creates the name first, this call waits for that build and returns
|
|
929
|
+
* it with `reused: true`. Every local check runs before the first AWS call.
|
|
930
|
+
*/
|
|
931
|
+
ensureImage(options: EnsureImageOptions, size?: SizeClass | undefined | null): Promise<EnsuredImage>
|
|
932
|
+
/**
|
|
933
|
+
* The artifact bytes to upload to `codeArtifactUri`.
|
|
934
|
+
*
|
|
935
|
+
* The upload is the caller's on this path (`ensureImage` uploads for itself). Takes the same
|
|
936
|
+
* options as [`Self::build_image`] so the bytes a caller puts in the bucket are the bytes
|
|
937
|
+
* the build will receive.
|
|
938
|
+
*/
|
|
939
|
+
buildArtifact(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<Buffer>
|
|
940
|
+
/**
|
|
941
|
+
* Every local guard `buildImage` runs, with zero calls: rejects with the refusal
|
|
942
|
+
* `buildImage` would, so a caller who uploads its own artifact checks the request before
|
|
943
|
+
* paying for the upload. Takes `buildImage`'s arguments.
|
|
944
|
+
*/
|
|
945
|
+
preflight(options: BuildImageOptions, size?: SizeClass | undefined | null, runHookTimeout?: RunHookTimeout | undefined | null, buildHookTimeout?: BuildHookTimeout | undefined | null): Promise<void>
|
|
946
|
+
/**
|
|
947
|
+
* `ListManagedMicrovmImageVersions`, every page: the versions of a managed base, the
|
|
948
|
+
* values `buildImage`'s base-version pin takes.
|
|
949
|
+
*
|
|
950
|
+
* `baseImageArn` is the base's full ARN, such as
|
|
951
|
+
* `arn:aws:lambda:us-east-1:aws:microvm-image:al2023-1`; a bare name is refused.
|
|
952
|
+
*/
|
|
953
|
+
managedBaseVersions(baseImageArn: string): Promise<Array<ManagedBaseVersion>>
|
|
954
|
+
/**
|
|
955
|
+
* Launches a MicroVM and resolves with its session. By default it waits for RUNNING
|
|
956
|
+
* and for the daemon to answer; `wait: false` skips those readiness waits.
|
|
957
|
+
*
|
|
958
|
+
* `readyTimeout` bounds the wait for RUNNING; the wait for the daemon after it is
|
|
959
|
+
* `sessionConstants().defaultReadyTimeoutSeconds`, and a daemon that never answers
|
|
960
|
+
* rejects with `ERR_TIMEOUT` with the VM left RUNNING.
|
|
961
|
+
*
|
|
962
|
+
* # What the core refuses here, and this file does not
|
|
963
|
+
*
|
|
964
|
+
* A second `run` on one sandbox, with **zero** control-plane calls: the agent token is
|
|
965
|
+
* installed at most once per VM lifetime (STATE-3), and a second VM needs a second
|
|
966
|
+
* `Sandbox`. A run with no image at all, before any call. Neither check is in this file.
|
|
967
|
+
*/
|
|
968
|
+
run(options?: RunOptions | undefined | null): Promise<Session>
|
|
969
|
+
/**
|
|
970
|
+
* Finishes a `run({ wait: false })`: waits for RUNNING and for the daemon to answer, and
|
|
971
|
+
* resolves with the session. `timeout` bounds the wait for RUNNING, as `readyTimeout`
|
|
972
|
+
* does.
|
|
973
|
+
*
|
|
974
|
+
* A launch whose `clientToken` adopted an existing, idle-suspended VM resumes it; a
|
|
975
|
+
* fresh launch that reaches a terminal state first rejects with the service's
|
|
976
|
+
* `stateReason`. Refused unless the launch is still PENDING.
|
|
977
|
+
*/
|
|
978
|
+
waitUntilRunning(timeout?: number | undefined | null): Promise<Session>
|
|
979
|
+
/**
|
|
980
|
+
* Freezes the VM and waits for the platform to report it.
|
|
981
|
+
*
|
|
982
|
+
* A freeze and restore rather than a stop and start: the guest keeps its memory, so the
|
|
983
|
+
* token, the filesystem, and every exec record survive. The one thing that does not is
|
|
984
|
+
* the guest's view of time — it observes the whole suspension as a single jump, so any
|
|
985
|
+
* timeout, lease, or TLS session a running command holds expires at once on resume.
|
|
986
|
+
*
|
|
987
|
+
* A suspend from anything but RUNNING is refused by the core with zero control-plane
|
|
988
|
+
* calls (STATE-5). Resolves with the state reached, which may be `"TERMINATED"`: a VM
|
|
989
|
+
* that dies while suspending is a state to report rather than an error thrown out of the
|
|
990
|
+
* middle of a teardown.
|
|
991
|
+
*/
|
|
992
|
+
suspend(): Promise<string>
|
|
993
|
+
/**
|
|
994
|
+
* Thaws the VM and resolves with a usable session.
|
|
995
|
+
*
|
|
996
|
+
* # What the core refuses, before any wire call
|
|
997
|
+
*
|
|
998
|
+
* A resume after `terminate` (STATE-11) — a terminated VM never returns to RUNNING, and
|
|
999
|
+
* even a call the service accepted would hand back a different machine. A resume from
|
|
1000
|
+
* anything but SUSPENDED (STATE-7). And a resume past the launch-time suspended window
|
|
1001
|
+
* (STATE-12), which is the one worth knowing about: the `idlePolicy` terminates a
|
|
1002
|
+
* suspended VM once that window passes, so there is nothing left to resume, and calling
|
|
1003
|
+
* would cost the full poll timeout to learn something worse.
|
|
1004
|
+
*
|
|
1005
|
+
* Nothing is re-delivered: no run-hook payload, no token, no bootstrap. The in-memory
|
|
1006
|
+
* token survived the freeze, and re-delivering it would hit the daemon's one-shot
|
|
1007
|
+
* bootstrap and be refused — a 409 that reads like a broken VM.
|
|
1008
|
+
*/
|
|
1009
|
+
resume(): Promise<Session>
|
|
1010
|
+
/**
|
|
1011
|
+
* Tears down, best-effort, **never rejecting**.
|
|
1012
|
+
*
|
|
1013
|
+
* Order: VM, then image, then the log group last, because the service can recreate a
|
|
1014
|
+
* group deleted before its image.
|
|
1015
|
+
*/
|
|
1016
|
+
terminate(options?: TeardownOptions | undefined | null): Promise<TeardownReport>
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/** One running MicroVM's control API, with the proxy auth handled for you. */
|
|
1020
|
+
export declare class Session {
|
|
1021
|
+
/**
|
|
1022
|
+
* A session against a daemon reached **directly**, with no proxy headers.
|
|
1023
|
+
*
|
|
1024
|
+
* The shape for a local binary, a test server, or a VM reached over a tunnel. There is
|
|
1025
|
+
* deliberately no constructor that takes a proxy token: minting one is the control
|
|
1026
|
+
* plane's job and it happens inside every request (TRAP-9), so a caller handing a token
|
|
1027
|
+
* in would be handing in one that expires.
|
|
1028
|
+
*/
|
|
1029
|
+
static direct(endpoint: string, agentToken: string): Session
|
|
1030
|
+
/**
|
|
1031
|
+
* Reattach using a private control record, without bootstrapping again.
|
|
1032
|
+
* Owns its transport independently of sandbox locks; use a separate attach with
|
|
1033
|
+
* a short requestTimeout for keepalives. Never publish or log agentToken.
|
|
1034
|
+
*/
|
|
1035
|
+
static attach(region: Region, microvmId: string, endpoint: string, agentToken: string, port?: number | undefined | null, requestTimeout?: number | undefined | null): Promise<Session>
|
|
1036
|
+
/** The guest bearer credential. Store only in a private encrypted control record. */
|
|
1037
|
+
agentToken(): Promise<string>
|
|
1038
|
+
/** The endpoint this session addresses. */
|
|
1039
|
+
endpoint(): Promise<string>
|
|
1040
|
+
/**
|
|
1041
|
+
* The launch's egress posture: `"open"`, `"unsealed"`, `"best-effort"`, or `"sealed"`.
|
|
1042
|
+
*
|
|
1043
|
+
* The value the CLI envelope's `egressPosture` reports for the same launch options, and
|
|
1044
|
+
* what `egressPostureFor` answers before the launch. A session that does not hold its
|
|
1045
|
+
* launch options (`Session.direct`, `Session.attach`, an adopted sandbox) reports
|
|
1046
|
+
* `"unsealed"`. Advertise network isolation only for `"sealed"`. Async like `endpoint()`,
|
|
1047
|
+
* because a sandbox-held session is read under the sandbox's lock.
|
|
1048
|
+
*/
|
|
1049
|
+
egressPosture(): Promise<string>
|
|
1050
|
+
/** The port the proxy token is scoped to. */
|
|
1051
|
+
port(): Promise<number>
|
|
1052
|
+
/** Unauthenticated liveness. */
|
|
1053
|
+
health(): Promise<Health>
|
|
1054
|
+
/**
|
|
1055
|
+
* Keeps the VM awake by polling health from this process until stopped.
|
|
1056
|
+
*
|
|
1057
|
+
* The platform counts only inbound requests as activity, so an exec working with no
|
|
1058
|
+
* client traffic is suspended once `maxIdleDurationSeconds` passes. Resolves at once
|
|
1059
|
+
* with a running handle. On a sandbox-held session a suspend or terminate through the
|
|
1060
|
+
* sandbox ends the keepalive before its next poll; stop it before suspending through
|
|
1061
|
+
* anything else, or the next poll auto-resumes the VM.
|
|
1062
|
+
*/
|
|
1063
|
+
keepAwake(options?: KeepAwakeOptions | undefined | null): Promise<KeepAwake>
|
|
1064
|
+
/**
|
|
1065
|
+
* Polls health until the daemon reports bootstrapped.
|
|
1066
|
+
*
|
|
1067
|
+
* Connection errors on the way are expected rather than exceptional: a VM that has just
|
|
1068
|
+
* reached RUNNING commonly refuses a connection or two before the proxy path is wired
|
|
1069
|
+
* up. A *fatal* error ends the wait at once, because retrying a 401 until the deadline
|
|
1070
|
+
* is the mistake the retryable split exists to prevent.
|
|
1071
|
+
*/
|
|
1072
|
+
waitUntilReady(timeout?: number | undefined | null): Promise<Health>
|
|
1073
|
+
/** Starts a command and returns its handle. Does not wait. */
|
|
1074
|
+
run(command: string | Array<string>, options?: ExecOptions | undefined | null): Promise<ExecHandle>
|
|
1075
|
+
/**
|
|
1076
|
+
* Starts a command and returns it as two byte streams, a `wait()`, and a `kill()`.
|
|
1077
|
+
*
|
|
1078
|
+
* The **process** shape, as against [`Self::run`]'s handle shape. Same start request and
|
|
1079
|
+
* the same `ExecOptions` (`cwd`, `env`, `user`, `group`, `shell`, `execId`, `timeoutSec`
|
|
1080
|
+
* all apply), so this is a different view of one exec rather than a different exec:
|
|
1081
|
+
* `spawn` and `run` with the same `execId` address the same server-side child, and the
|
|
1082
|
+
* daemon starts one.
|
|
1083
|
+
*
|
|
1084
|
+
* `stdout` and `stderr` come out as independent `ReadableStream<Uint8Array>`, which is
|
|
1085
|
+
* deliberately the AI SDK harness's `SandboxProcess` shape — see [`crate::process`] for
|
|
1086
|
+
* what that compatibility is and is not, for how one interleaved SSE channel becomes two
|
|
1087
|
+
* streams, and for why an evicted byte range errors the streams by default instead of
|
|
1088
|
+
* being reported out-of-band.
|
|
1089
|
+
*
|
|
1090
|
+
* The reconnect-at-cursor behaviour is unchanged from `stream()`: a stream cut by a
|
|
1091
|
+
* suspend/resume rejoins at the byte offset rather than ending, so a suspend does not look
|
|
1092
|
+
* like a clean exit.
|
|
1093
|
+
*/
|
|
1094
|
+
spawn(command: string | Array<string>, options?: SpawnOptions | undefined | null): Promise<ExecProcess>
|
|
1095
|
+
/**
|
|
1096
|
+
* A handle for an exec started earlier, possibly by another process.
|
|
1097
|
+
*
|
|
1098
|
+
* The reattach path. Nothing is checked against the daemon here — the handle is an id
|
|
1099
|
+
* plus a transport, and a poll is what discovers whether the exec exists.
|
|
1100
|
+
*/
|
|
1101
|
+
exec(execId: string): Promise<ExecHandle>
|
|
1102
|
+
/** Start, wait, ack. The one-shot shape, for when output is all you want. */
|
|
1103
|
+
runSync(command: string | Array<string>, options?: ExecOptions | undefined | null): Promise<ExecResult>
|
|
1104
|
+
/**
|
|
1105
|
+
* Start, stream, and collect one command: exactly one `ExecResult` back (BIND-6..10).
|
|
1106
|
+
*
|
|
1107
|
+
* With `onOutput`, each output chunk (a `StreamEvent` of kind `"output"`) is handed to it
|
|
1108
|
+
* as it arrives. The result then comes from the ack that follows the terminal `exit`
|
|
1109
|
+
* event, or, when the stream ends without one, from a wait and ack. When `timeoutSec +
|
|
1110
|
+
* clientGraceSec` passes first (or, with no `timeoutSec`, the VM's maximum lifetime), the
|
|
1111
|
+
* process group is killed and the exec waited for and acked within `clientGraceSec` once
|
|
1112
|
+
* more; if that fails too the result is synthesized with `posixExitCode` 124.
|
|
1113
|
+
*
|
|
1114
|
+
* A throwing `onOutput` stops delivery; the exec is still waited for and acked so nothing
|
|
1115
|
+
* is left behind, and then the promise rejects with the callback's message. `shell: true`
|
|
1116
|
+
* runs `/bin/sh -c`; for bash semantics pass `shell: "bash"` with a script string, or
|
|
1117
|
+
* `["bash", "-c", script]` for a daemon that predates named shells.
|
|
1118
|
+
*/
|
|
1119
|
+
runToCompletion(command: string | string[], options?: CompletionRequest | undefined | null, onOutput?: ((chunk: StreamEvent) => unknown) | undefined | null): Promise<ExecResult>
|
|
1120
|
+
/** Signals an exec's whole process group. Returns whether anything was signalled. */
|
|
1121
|
+
kill(execId: string): Promise<boolean>
|
|
1122
|
+
/**
|
|
1123
|
+
* Process accounting: every registered exec with its group's live pids.
|
|
1124
|
+
*
|
|
1125
|
+
* The daemon reads `/proc` itself, so this needs no `ps` in the guest. A `ProcGroup` with
|
|
1126
|
+
* `childExited` and a non-empty `pids` is a command that finished while something it
|
|
1127
|
+
* backgrounded did not; pass its `execId` to `kill`.
|
|
1128
|
+
*/
|
|
1129
|
+
procs(): Promise<Array<ProcGroup>>
|
|
1130
|
+
/**
|
|
1131
|
+
* Writes one file, creating parents. `mode` is an **octal string** (`"0755"`), which is
|
|
1132
|
+
* the daemon's shape — a number here would be ambiguous between 0o755 and 755.
|
|
1133
|
+
*/
|
|
1134
|
+
uploadFile(path: string, data: Uint8Array, mode?: string | undefined | null): Promise<void>
|
|
1135
|
+
/**
|
|
1136
|
+
* Reads one file, or lines `startLine` through `endLine` of it.
|
|
1137
|
+
*
|
|
1138
|
+
* The range is 1-based and inclusive, and the daemon slices the file, so reading lines 40
|
|
1139
|
+
* to 60 of a large log reads those lines alone. Either bound may be left out (line 1,
|
|
1140
|
+
* through EOF), and an `endLine` past the last line reads through EOF. Line 0 and an end
|
|
1141
|
+
* before the start reject with `ERR_INVALID_ARG` before any request.
|
|
1142
|
+
*/
|
|
1143
|
+
downloadFile(path: string, options?: DownloadFileOptions | undefined | null): Promise<Buffer>
|
|
1144
|
+
/**
|
|
1145
|
+
* Brings the files of a directory in the VM back under `localDir`: the regular files
|
|
1146
|
+
* `globs` select, and nothing else.
|
|
1147
|
+
*
|
|
1148
|
+
* The daemon packs `remote`, and the archive describes the VM's filesystem, where
|
|
1149
|
+
* untrusted work runs, so core writes only regular-file members that match a glob, never
|
|
1150
|
+
* under `.git` whatever the globs say, and never outside `localDir`. A symlink, a special
|
|
1151
|
+
* file or a `../` member is skipped, not refused. `['**']` brings every regular file back.
|
|
1152
|
+
* Resolves to what was written; a local directory that can't be written to rejects with
|
|
1153
|
+
* `ERR_INVALID_ARG`.
|
|
1154
|
+
*/
|
|
1155
|
+
downloadDir(remote: string, localDir: string, globs: Array<string>): Promise<Array<DownloadedFile>>
|
|
1156
|
+
/**
|
|
1157
|
+
* Syncs `localDir` into the VM's `/workspace` once, uploading only what changed.
|
|
1158
|
+
*
|
|
1159
|
+
* Core's one pass, `microvm sync`'s: the local tree is hashed and diffed against the
|
|
1160
|
+
* manifest the last sync left in the VM, the changed members travel as one archive, the
|
|
1161
|
+
* paths gone locally are removed in the VM with one `rm` whose deadline is
|
|
1162
|
+
* `deleteTimeout` seconds (core's default when omitted), and the manifest is rewritten.
|
|
1163
|
+
* `full: true` ignores the manifest and uploads everything. `.git`, `target`,
|
|
1164
|
+
* `node_modules` and `.venv` never travel. A tree over the daemon's budgets rejects with
|
|
1165
|
+
* `ERR_INVALID_ARG` before anything is sent.
|
|
1166
|
+
*/
|
|
1167
|
+
syncDir(localDir: string, options?: SyncDirOptions | undefined | null): Promise<SyncReport>
|
|
1168
|
+
/** Whether a path exists, distinguishing absence from every other refusal. */
|
|
1169
|
+
fileExists(path: string): Promise<boolean>
|
|
1170
|
+
/**
|
|
1171
|
+
* Extracts pre-built tar bytes under `remote`.
|
|
1172
|
+
*
|
|
1173
|
+
* Bytes rather than a local path: packing a directory is the caller's, because the
|
|
1174
|
+
* symlink and permission decisions in a pack belong to whoever knows what the tree
|
|
1175
|
+
* means.
|
|
1176
|
+
*/
|
|
1177
|
+
uploadTar(remote: string, archive: Uint8Array): Promise<void>
|
|
1178
|
+
/** The raw tar bytes of a remote tree. */
|
|
1179
|
+
downloadTar(remote: string): Promise<Buffer>
|
|
1180
|
+
/**
|
|
1181
|
+
* Both proxy headers for `port`, so a caller can open its **own** connection.
|
|
1182
|
+
*
|
|
1183
|
+
* The `{ url, headers }` shape a provider's `getPortEndpoint` answers with: pair these
|
|
1184
|
+
* with `endpoint()` and nothing outside this addon has to know how a proxy token is
|
|
1185
|
+
* minted or when it refreshes. Minted through the session's existing cache, so calling
|
|
1186
|
+
* this does not burn a second control-plane call and does not open a second TRAP-9
|
|
1187
|
+
* schedule.
|
|
1188
|
+
*
|
|
1189
|
+
* A plain `Record<string, string>` rather than a class, and that is the one place this
|
|
1190
|
+
* crate's own "never `#[napi(object)]` for anything carrying a closure" rule does not
|
|
1191
|
+
* apply: there is no closure here to protect. The value is a **bearer credential**, and
|
|
1192
|
+
* unlike the token itself it necessarily comes out as a string — a header a caller has to
|
|
1193
|
+
* put on a request cannot be opaque. What is still closed is the other direction: no
|
|
1194
|
+
* function in this addon *takes* a header map, so a caller cannot feed a forged or expired
|
|
1195
|
+
* one back in.
|
|
1196
|
+
*
|
|
1197
|
+
* **Empty for a direct session**, which is the true answer rather than a missing one: a
|
|
1198
|
+
* daemon reached directly takes no proxy headers, so an empty object is exactly what its
|
|
1199
|
+
* requests carry.
|
|
1200
|
+
*/
|
|
1201
|
+
connectHeaders(port: number): Promise<Record<string, string>>
|
|
1202
|
+
/**
|
|
1203
|
+
* The three WebSocket subprotocols for `port`, in the order a handshake offers them.
|
|
1204
|
+
*
|
|
1205
|
+
* `new WebSocket(url, await session.connectSubprotocols(port))` is the whole use. A
|
|
1206
|
+
* MicroVM endpoint takes the auth and the target port as `Sec-WebSocket-Protocol` values
|
|
1207
|
+
* rather than as headers, because the browser `WebSocket` constructor cannot set a header
|
|
1208
|
+
* — and the platform strips all three before forwarding, so a server inside the VM never
|
|
1209
|
+
* negotiates them and must not be written to expect them.
|
|
1210
|
+
*
|
|
1211
|
+
* `null` for a direct session, and deliberately not an empty array: the subprotocol form
|
|
1212
|
+
* exists only for a request through the endpoint proxy, so there is nothing for a
|
|
1213
|
+
* directly-reached daemon to offer. Answering `["lambda-microvms"]` with no token would
|
|
1214
|
+
* open a handshake refused for a reason naming neither the token nor the port.
|
|
1215
|
+
*
|
|
1216
|
+
* The middle string **contains the credential**. Same rule as `connectHeaders`.
|
|
1217
|
+
*/
|
|
1218
|
+
connectSubprotocols(port: number): Promise<Array<string> | null>
|
|
1219
|
+
/**
|
|
1220
|
+
* Serves a local TCP port as a tunnel to `guestPort` in the VM, on a background task, and
|
|
1221
|
+
* resolves at once with its handle: `microvm tunnel`'s loop.
|
|
1222
|
+
*
|
|
1223
|
+
* Each local connection gets a WebSocket of its own through the endpoint proxy, and a
|
|
1224
|
+
* connection the daemon refuses is listed in the report while the tunnel keeps serving.
|
|
1225
|
+
* With `verifyIdentity` (a `TunnelIdentity`, such as `sandbox.tunnelIdentity()`), each
|
|
1226
|
+
* connection first proves the far end is the daemon of the VM that identity was launched
|
|
1227
|
+
* with, and a connection that can't is refused. A separate parameter rather than an
|
|
1228
|
+
* option, for the reason `buildImage`'s guarded values are: a class in an options object
|
|
1229
|
+
* can't cross an async call.
|
|
1230
|
+
*/
|
|
1231
|
+
tunnel(guestPort: number, options?: ServeOptions | undefined | null, verifyIdentity?: TunnelIdentity | undefined | null): Promise<Tunnel>
|
|
1232
|
+
/**
|
|
1233
|
+
* Serves a local port as an HTTP and WebSocket forward to `guestPort` in the VM, on a
|
|
1234
|
+
* background task, and resolves at once with its handle: `microvm port-forward`'s loop.
|
|
1235
|
+
*
|
|
1236
|
+
* Connections are served at once rather than one after another, so a slow request
|
|
1237
|
+
* doesn't hold the next. A request the endpoint proxy refuses is listed in the report
|
|
1238
|
+
* with its status while the forward keeps serving.
|
|
1239
|
+
*/
|
|
1240
|
+
portForward(guestPort: number, options?: ServeOptions | undefined | null): Promise<PortForward>
|
|
1241
|
+
/**
|
|
1242
|
+
* How many proxy tokens this session has minted, or `null` for a direct session.
|
|
1243
|
+
*
|
|
1244
|
+
* Exposed because it is the only observable that distinguishes a client which re-minted
|
|
1245
|
+
* after a resume from one that kept a stale token (STATE-8). The **token itself** is not
|
|
1246
|
+
* exposed and cannot be: the core's `ProxyToken` has no `Display`, no `as_str`, and no
|
|
1247
|
+
* `Deref`, so "treat `authToken` as a string" is as inexpressible here as it is there
|
|
1248
|
+
* (TRAP-7).
|
|
1249
|
+
*/
|
|
1250
|
+
proxyMintCount(): Promise<number | null>
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* One of the five documented size classes.
|
|
1255
|
+
*
|
|
1256
|
+
* `minimumMemoryInMiB` selects a class; it does not size a VM. Both numbers are on the
|
|
1257
|
+
* class or neither.
|
|
1258
|
+
*/
|
|
1259
|
+
export declare class SizeClass {
|
|
1260
|
+
/**
|
|
1261
|
+
* The class `minimumMemoryInMiB = mib` selects, or a refusal (TRAP-10).
|
|
1262
|
+
*
|
|
1263
|
+
* Off-table figures are refused rather than snapped to a neighbour: the two plausible
|
|
1264
|
+
* readings differ in both memory and rate, and neither has been measured.
|
|
1265
|
+
*/
|
|
1266
|
+
static fromBaselineMib(mib: number): SizeClass
|
|
1267
|
+
/**
|
|
1268
|
+
* The smallest class whose baseline covers a resource request (BIND-14).
|
|
1269
|
+
*
|
|
1270
|
+
* `cpus` in vCPUs and `memoryMib` in MiB, each a request; `undefined` or zero is no
|
|
1271
|
+
* requirement on that axis, and with none on either the answer is `defaultClass()`.
|
|
1272
|
+
* Chosen by baseline, the billed and always-present figure. Throws `ERR_INVALID_ARG`
|
|
1273
|
+
* naming the largest class when no class covers the request, or for a CPU figure that is
|
|
1274
|
+
* not a finite non-negative number.
|
|
1275
|
+
*/
|
|
1276
|
+
static fromRequest(cpus?: number | undefined | null, memoryMib?: number | undefined | null): SizeClass
|
|
1277
|
+
/**
|
|
1278
|
+
* The platform's default, 2048 MiB. Not the smallest — a 0.5 GB baseline fixes the
|
|
1279
|
+
* guest's always-present ceiling at 2 GB, which OOM-kills a real test suite, and the
|
|
1280
|
+
* guest has no swap.
|
|
1281
|
+
*/
|
|
1282
|
+
static defaultClass(): SizeClass
|
|
1283
|
+
/** Every class, smallest first. */
|
|
1284
|
+
static all(): Array<SizeClass>
|
|
1285
|
+
get baselineMib(): number
|
|
1286
|
+
get baselineVcpu(): number
|
|
1287
|
+
get peakMib(): number
|
|
1288
|
+
get peakVcpu(): number
|
|
1289
|
+
/** The figure a GB-second rate multiplies. Always the baseline, never the peak. */
|
|
1290
|
+
get baselineGb(): number
|
|
1291
|
+
/** The peak in GB, which is what the guest reports as `MemTotal`. */
|
|
1292
|
+
get peakGb(): number
|
|
1293
|
+
/** One line naming both numbers. */
|
|
1294
|
+
describe(): string
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/**
|
|
1298
|
+
* A report's total, which is a lower bound whenever anything is unpriced.
|
|
1299
|
+
*
|
|
1300
|
+
* The floor is under a name that says what it is — never `total`. A caller reading a field
|
|
1301
|
+
* called `total` would have no reason to check `isLowerBound`.
|
|
1302
|
+
*/
|
|
1303
|
+
export declare class Total {
|
|
1304
|
+
/** Everything that could be priced. For a lower bound this is **not** the total. */
|
|
1305
|
+
get floor(): EstimatedUsd
|
|
1306
|
+
/** True when line items with no published rate are missing from the floor. */
|
|
1307
|
+
get isLowerBound(): boolean
|
|
1308
|
+
/** Why each unpriced line could not be priced, in report order. */
|
|
1309
|
+
get unpricedReasons(): Array<string>
|
|
1310
|
+
/** `at least ~$X (estimated), plus N unpriced (...)`. */
|
|
1311
|
+
toString(): string
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* A running tunnel. Call `stop()` when done; a garbage-collected handle stops the tunnel and
|
|
1316
|
+
* cuts its open connections.
|
|
1317
|
+
*/
|
|
1318
|
+
export declare class Tunnel {
|
|
1319
|
+
/** The local address to connect to, `host:port`, with the port the OS picked. */
|
|
1320
|
+
get localAddress(): string
|
|
1321
|
+
/** Whether the tunnel is still serving. */
|
|
1322
|
+
get running(): boolean
|
|
1323
|
+
/**
|
|
1324
|
+
* Stops accepting, waits for the connections still open to end, and resolves with the
|
|
1325
|
+
* report.
|
|
1326
|
+
*
|
|
1327
|
+
* With `timeout` (seconds), connections still open after it are cut and listed as
|
|
1328
|
+
* `"failed"`. Without it, a client that keeps its connection open keeps this waiting.
|
|
1329
|
+
* Callable again, with the same report.
|
|
1330
|
+
*/
|
|
1331
|
+
stop(timeout?: number | undefined | null): Promise<TunnelReport>
|
|
1332
|
+
/** The handle without its credentials. */
|
|
1333
|
+
toString(): string
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
/**
|
|
1337
|
+
* What a launcher keeps to verify its VM: the host's secret seed and the VM's public key,
|
|
1338
|
+
* both base64.
|
|
1339
|
+
*
|
|
1340
|
+
* From `sandbox.tunnelIdentity()` after a `run({ identity: true })`, from a `NameRecord`, or
|
|
1341
|
+
* built from the two values `microvm run --identity` prints. Holds a secret: `hostSeed()` is a
|
|
1342
|
+
* method rather than a getter so it's never read by accident, and `toString()` leaves it out.
|
|
1343
|
+
*/
|
|
1344
|
+
export declare class TunnelIdentity {
|
|
1345
|
+
/**
|
|
1346
|
+
* Rebuilds the pair from its base64 spellings. Refuses a value that doesn't decode, or a
|
|
1347
|
+
* seed or key of the wrong length.
|
|
1348
|
+
*/
|
|
1349
|
+
constructor(hostSeed: string, vmPublicKey: string)
|
|
1350
|
+
/** The host's secret half, base64. Store only privately. */
|
|
1351
|
+
hostSeed(): string
|
|
1352
|
+
/** The VM's public key, base64: the pin. Safe to print and compare. */
|
|
1353
|
+
get vmPublicKey(): string
|
|
1354
|
+
/** The pair without its secret. */
|
|
1355
|
+
toString(): string
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
/**
|
|
1359
|
+
* A quantity we can measure but cannot price, because no rate is published.
|
|
1360
|
+
*
|
|
1361
|
+
* A distinct class from [`EstimatedUsd`], not `EstimatedUsd("0")`: zero is a claim about
|
|
1362
|
+
* the bill, unpriced is a claim about the documentation.
|
|
1363
|
+
*/
|
|
1364
|
+
export declare class Unpriced {
|
|
1365
|
+
get reason(): string
|
|
1366
|
+
toString(): string
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
/** The layer's fixed values as JSON, for a caller that wants to reason about the guest. */
|
|
1370
|
+
export declare function agentConstants(): string
|
|
1371
|
+
|
|
1372
|
+
/**
|
|
1373
|
+
* What `ensureImage` builds or reuses from: the daemon binary, the build role, and where
|
|
1374
|
+
* the artifact goes.
|
|
1375
|
+
*/
|
|
1376
|
+
export interface AgentEnsureOptions {
|
|
1377
|
+
/** The daemon binary's bytes, zipped into the artifact. */
|
|
1378
|
+
binary: Uint8Array
|
|
1379
|
+
/** The build role, which must read the bucket and grant logs on `/aws/lambda-microvms/*`. */
|
|
1380
|
+
buildRoleArn: string
|
|
1381
|
+
/** The bucket the artifact is uploaded to, in the VM's region. */
|
|
1382
|
+
s3Bucket: string
|
|
1383
|
+
/** A key prefix inside the bucket, or absent for the bucket root. */
|
|
1384
|
+
s3KeyPrefix?: string
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
/** What an agent image is derived from: the daemon binary and the build role. */
|
|
1388
|
+
export interface AgentImageOptions {
|
|
1389
|
+
/** The daemon binary's bytes, zipped into the artifact. */
|
|
1390
|
+
binary: Uint8Array
|
|
1391
|
+
/** The build role, which must grant logs on `/aws/lambda-microvms/*`. */
|
|
1392
|
+
buildRoleArn: string
|
|
1393
|
+
/**
|
|
1394
|
+
* Where `buildArtifact`'s bytes were uploaded. Required by `buildImage`, ignored by the
|
|
1395
|
+
* name and artifact calls.
|
|
1396
|
+
*/
|
|
1397
|
+
codeArtifactUri?: string
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
/** Everything a launch takes beyond what the layer fixes (egress on, the image). */
|
|
1401
|
+
export interface AgentLaunchOptions {
|
|
1402
|
+
/**
|
|
1403
|
+
* The image ARN from `findImage` or `buildImage`, or a bare image name, which the core
|
|
1404
|
+
* resolves with one `ListMicrovmImages` read.
|
|
1405
|
+
*/
|
|
1406
|
+
imageIdentifier: string
|
|
1407
|
+
/** The execution role. Optional in the model; every real launch needs one. */
|
|
1408
|
+
executionRoleArn?: string
|
|
1409
|
+
/** Persist this secret privately before launch when recovery is needed. */
|
|
1410
|
+
agentToken?: string
|
|
1411
|
+
/** Persist once per intended launch and reuse with the identical request. */
|
|
1412
|
+
clientToken?: string
|
|
1413
|
+
maxIdleSec?: number
|
|
1414
|
+
suspendedSec?: number
|
|
1415
|
+
autoResume?: boolean
|
|
1416
|
+
maxDurationSec?: number
|
|
1417
|
+
/** Pins the launch to one image version rather than the latest active one. */
|
|
1418
|
+
imageVersion?: string
|
|
1419
|
+
/**
|
|
1420
|
+
* Customer-managed VPC egress connector ARNs. When given they replace the managed
|
|
1421
|
+
* internet connector, and the VPC must route to Bedrock.
|
|
1422
|
+
*/
|
|
1423
|
+
egressNetworkConnectors?: Array<string>
|
|
1424
|
+
/** Per-VM CloudWatch log group. Omitted keeps the service's default destination. */
|
|
1425
|
+
logGroup?: string
|
|
1426
|
+
/** An exact log stream inside `logGroup`. */
|
|
1427
|
+
logStream?: string
|
|
1428
|
+
/** Turns per-VM logging off. Cannot be combined with `logGroup` or `logStream`. */
|
|
1429
|
+
disableLogging?: boolean
|
|
1430
|
+
/** The base environment for every exec in the VM. See `RunOptions.launchEnv`. */
|
|
1431
|
+
launchEnv?: Record<string, string>
|
|
1432
|
+
/** Launch shell-capable. See `RunOptions.shell`. */
|
|
1433
|
+
shell?: boolean
|
|
1434
|
+
/**
|
|
1435
|
+
* How long to wait for RUNNING. The wait for the daemon after it is the core's
|
|
1436
|
+
* `defaultReadyTimeoutSeconds`.
|
|
1437
|
+
*/
|
|
1438
|
+
readyTimeout?: number
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
/** A resolved spec: the model it will use and the command `prompt` runs. */
|
|
1442
|
+
export interface AgentSpec {
|
|
1443
|
+
/** `"claude-code"` or `"codex"`. */
|
|
1444
|
+
agent: string
|
|
1445
|
+
/** The model this spec resolves to: the override, or the profile's default. */
|
|
1446
|
+
model: string
|
|
1447
|
+
/** The pinned CLI version, or `null` for the registry's latest at build time. */
|
|
1448
|
+
cliVersion?: string
|
|
1449
|
+
/** The exact command `prompt` runs, with `<TASK>` where the quoted task goes. */
|
|
1450
|
+
headlessCommand: string
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
/**
|
|
1454
|
+
* One agent to install: its name, and the two defaults a caller may override.
|
|
1455
|
+
*
|
|
1456
|
+
* `agent` is `"claude-code"` or `"codex"`; anything else is refused by the core with the
|
|
1457
|
+
* list. `model` defaults to the profile's row (an inference-profile id), `cliVersion` to the
|
|
1458
|
+
* registry's latest at build time; a pin changes the image name.
|
|
1459
|
+
*/
|
|
1460
|
+
export interface AgentSpecInput {
|
|
1461
|
+
agent: string
|
|
1462
|
+
model?: string
|
|
1463
|
+
cliVersion?: string
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
/**
|
|
1467
|
+
* The base a task Dockerfile pairs with: the managed base's `name`, so `baseImageArn` is
|
|
1468
|
+
* unchanged, and the Dockerfile's first `FROM` as `dockerRef`, digest pin included.
|
|
1469
|
+
*
|
|
1470
|
+
* `buildImage` refuses a Dockerfile whose first `FROM` is not the base's `dockerRef`; a base
|
|
1471
|
+
* derived from that Dockerfile passes by construction. Throws `ERR_INVALID_ARG` for a
|
|
1472
|
+
* Dockerfile with no `FROM`.
|
|
1473
|
+
*/
|
|
1474
|
+
export declare function baseImageFromDockerfile(dockerfile: string): BaseImageInput
|
|
1475
|
+
|
|
1476
|
+
/**
|
|
1477
|
+
* The platform's managed base image, paired with the Dockerfile `FROM` it goes with.
|
|
1478
|
+
*
|
|
1479
|
+
* One value rather than two loose strings, because the two **must** agree and used to be able
|
|
1480
|
+
* to disagree: the Python client's default named the managed base for `baseImageArn` while
|
|
1481
|
+
* its Dockerfile hardcoded an unrelated registry literal in its `FROM`, so changing either
|
|
1482
|
+
* left the other pointing somewhere else.
|
|
1483
|
+
*
|
|
1484
|
+
* `#[napi(object)]` is acceptable here where it is not for a guarded type: the pairing is the
|
|
1485
|
+
* point and both halves are required fields, so a structurally-valid object is a valid
|
|
1486
|
+
* pairing. `workingDir` is what `docker inspect` reports for `WorkingDir`, and empty means
|
|
1487
|
+
* the image declares none — a field because a caller with a purpose-built image is the only
|
|
1488
|
+
* one who can say what theirs declares.
|
|
1489
|
+
*/
|
|
1490
|
+
export interface BaseImageInput {
|
|
1491
|
+
name: string
|
|
1492
|
+
dockerRef: string
|
|
1493
|
+
workingDir?: string
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
/**
|
|
1497
|
+
* Everything `CreateMicrovmImage` needs.
|
|
1498
|
+
*
|
|
1499
|
+
* # What is deliberately not a field
|
|
1500
|
+
*
|
|
1501
|
+
* A `clientToken`. There is no such field on the core's request type and none here: a
|
|
1502
|
+
* digest-derived token replays the original create and wedges an image in `CREATING` for
|
|
1503
|
+
* fifteen hours with no error at all (TRAP-1). `tokenScope` is a CloudTrail **label** folded
|
|
1504
|
+
* in beside a fresh nonce and cannot become the token.
|
|
1505
|
+
*
|
|
1506
|
+
* A `capabilities` list. `repairGuestIdentity` is a boolean and the request injects `["ALL"]`
|
|
1507
|
+
* itself, so `["CAP_SYS_ADMIN"]` — the request AWS rejects after the artifact upload — is not
|
|
1508
|
+
* something a caller can write (TRAP-3).
|
|
1509
|
+
*
|
|
1510
|
+
* An `architecture`. The model's enum has exactly one value, so the only thing a field could
|
|
1511
|
+
* express is a rejected request.
|
|
1512
|
+
*/
|
|
1513
|
+
export interface BuildImageOptions {
|
|
1514
|
+
name: string
|
|
1515
|
+
/** The daemon binary's bytes, zipped into the artifact. */
|
|
1516
|
+
binary: Uint8Array
|
|
1517
|
+
/**
|
|
1518
|
+
* Where the artifact is uploaded to. `buildImage` does not upload: the caller puts the
|
|
1519
|
+
* bytes there and passes the URI. `ensureImage` is the path that uploads for itself.
|
|
1520
|
+
*/
|
|
1521
|
+
codeArtifactUri: string
|
|
1522
|
+
/** The build role, which must grant logs on `/aws/lambda-microvms/*`. */
|
|
1523
|
+
buildRoleArn: string
|
|
1524
|
+
baseImage?: BaseImageInput
|
|
1525
|
+
/** Pins the managed base to one version, a value `managedBaseVersions` lists. */
|
|
1526
|
+
baseImageVersion?: string
|
|
1527
|
+
/** A caller-supplied Dockerfile, checked against the base image's `FROM`. */
|
|
1528
|
+
dockerfile?: string
|
|
1529
|
+
/**
|
|
1530
|
+
* A directory whose one manifest+lockfile pair bakes an environment layer, by the rule
|
|
1531
|
+
* the CLI's `--project` uses. A directory without exactly one pair is refused before any
|
|
1532
|
+
* call.
|
|
1533
|
+
*/
|
|
1534
|
+
projectDir?: string
|
|
1535
|
+
/** Whether to repair guest identity. A boolean, not a capability list — see above. */
|
|
1536
|
+
repairGuestIdentity?: boolean
|
|
1537
|
+
/**
|
|
1538
|
+
* Whether the daemon should inherit the image's `WORKDIR`. Refused when nothing declares
|
|
1539
|
+
* one, because the inheritance would silently resolve to `/`.
|
|
1540
|
+
*/
|
|
1541
|
+
inheritWorkdir?: boolean
|
|
1542
|
+
tags?: Record<string, string>
|
|
1543
|
+
/**
|
|
1544
|
+
* `logging.cloudWatch.logGroup`, or absent for the service default (a service-created
|
|
1545
|
+
* group under `/aws/lambda-microvms/<image-name>` with random stream names). The
|
|
1546
|
+
* build role must grant logs on whatever this names.
|
|
1547
|
+
*/
|
|
1548
|
+
logGroup?: string
|
|
1549
|
+
/**
|
|
1550
|
+
* A log-stream name **prefix** inside `logGroup`, never the exact name: the platform
|
|
1551
|
+
* member is an exact stream name (prefixes unsupported) and one build is three VMs
|
|
1552
|
+
* writing three streams, so the client appends `/<16 hex>` per build attempt and the
|
|
1553
|
+
* resolved name comes back on `Image.logStream`. Requires `logGroup`.
|
|
1554
|
+
*/
|
|
1555
|
+
logStream?: string
|
|
1556
|
+
/** A CloudTrail-readability **label**, defaulting to the image name. Not the token. */
|
|
1557
|
+
tokenScope?: string
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
/** Why the image build has no price, as the reason that lands on the line item. */
|
|
1561
|
+
export declare function buildUnpricedReason(): string
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Judges `report`'s total against a ceiling of `maxUsd` (a decimal string, such as `"1.50"`),
|
|
1565
|
+
* with `onBreach` (`"warn"` or `"abort"`) saying what a breach does.
|
|
1566
|
+
*
|
|
1567
|
+
* `onBreach` has no default, because a breach of a lower-bound total has already been exceeded
|
|
1568
|
+
* by an unknown margin, and whether that warns or refuses is the caller's call. Core's
|
|
1569
|
+
* `Budget::check`, the gate `microvm cost --max-cost` applies.
|
|
1570
|
+
*/
|
|
1571
|
+
export declare function checkBudget(report: CostReport, maxUsd: string, onBreach: string): BudgetVerdict
|
|
1572
|
+
|
|
1573
|
+
/**
|
|
1574
|
+
* The warm-pool argument, with its own counter-argument attached.
|
|
1575
|
+
*
|
|
1576
|
+
* Leave `cycles` out and the comparison prices one suspend/resume cycle, the core's default
|
|
1577
|
+
* and the one `microvm cost --compare` applies: the per-cycle figure is what keeps the
|
|
1578
|
+
* argument honest. A report's `suspendResumeCycles` defaults to none instead.
|
|
1579
|
+
*/
|
|
1580
|
+
export declare function compareResidency(size: SizeClass, holdSeconds: number, cycles?: number | undefined | null, rates?: RateTable | undefined | null): ResidencyComparison
|
|
1581
|
+
|
|
1582
|
+
/**
|
|
1583
|
+
* How `runToCompletion` should start and collect a command.
|
|
1584
|
+
*
|
|
1585
|
+
* The `ExecOptions` a completed run can use (no `stdin`, which nothing would write, and no
|
|
1586
|
+
* `timeout`, which `clientGraceSec` replaces), plus the client grace.
|
|
1587
|
+
*/
|
|
1588
|
+
export interface CompletionRequest {
|
|
1589
|
+
/**
|
|
1590
|
+
* `true` runs a single script string under `/bin/sh -c`; a string such as `"bash"` runs
|
|
1591
|
+
* it under that shell, resolved by the daemon in the guest. See `ExecOptions.shell`.
|
|
1592
|
+
*/
|
|
1593
|
+
shell?: boolean | string
|
|
1594
|
+
cwd?: string
|
|
1595
|
+
env?: Record<string, string>
|
|
1596
|
+
/** A numeric uid, or a name the daemon resolves in the guest. See `ExecOptions.user`. */
|
|
1597
|
+
user?: number | string
|
|
1598
|
+
/** A numeric gid, or a name the daemon resolves in the guest. */
|
|
1599
|
+
group?: number | string
|
|
1600
|
+
/**
|
|
1601
|
+
* The daemon's own kill deadline for the child. The client deadline is this plus
|
|
1602
|
+
* `clientGraceSec`.
|
|
1603
|
+
*/
|
|
1604
|
+
timeoutSec?: number
|
|
1605
|
+
/** The idempotency key. Omitted, one is minted. */
|
|
1606
|
+
execId?: string
|
|
1607
|
+
/**
|
|
1608
|
+
* Signal the whole process group once the command's own child exits. See
|
|
1609
|
+
* `ExecOptions.reapGroupOnExit`.
|
|
1610
|
+
*/
|
|
1611
|
+
reapGroupOnExit?: boolean
|
|
1612
|
+
/** Start the child's environment from the image's `ENV`. See `ExecOptions.inheritImageEnv`. */
|
|
1613
|
+
inheritImageEnv?: boolean
|
|
1614
|
+
/**
|
|
1615
|
+
* How long past `timeoutSec` the client waits before it kills, and how long it then
|
|
1616
|
+
* waits for the killed exec's result. Defaults to the core's 60 seconds.
|
|
1617
|
+
*/
|
|
1618
|
+
clientGraceSec?: number
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
/** A connection that didn't end clean. */
|
|
1622
|
+
export interface ConnectionEnd {
|
|
1623
|
+
/** The local client's address, `host:port`. */
|
|
1624
|
+
peer: string
|
|
1625
|
+
/** `"refused"`, `"truncated"`, `"unproven"`, or `"failed"`. */
|
|
1626
|
+
kind: string
|
|
1627
|
+
/** The close code or the HTTP status, when the end carried one. */
|
|
1628
|
+
code?: number
|
|
1629
|
+
/** The daemon's reason, the forwarder's explanation, or the error. */
|
|
1630
|
+
detail: string
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
/**
|
|
1634
|
+
* The core crate's version, for a `doctor` or `manifest` command to report.
|
|
1635
|
+
*
|
|
1636
|
+
* The **core's** version and not this crate's: what a caller needs to know is which client
|
|
1637
|
+
* they are talking through, and a binding version that drifted from it would be a second
|
|
1638
|
+
* number nobody can act on.
|
|
1639
|
+
*/
|
|
1640
|
+
export declare function coreVersion(): string
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* The documented cost constants, as a JSON string a caller can assert against.
|
|
1644
|
+
*
|
|
1645
|
+
* A JSON string rather than a typed object because it is a transcription of published
|
|
1646
|
+
* facts whose shape may grow, and a `#[napi(object)]` would make every addition a
|
|
1647
|
+
* signature change.
|
|
1648
|
+
*/
|
|
1649
|
+
export declare function costConstants(): string
|
|
1650
|
+
|
|
1651
|
+
/** The managed base every `docs/PLATFORM.md` measurement from 2026-08-06 onward used. */
|
|
1652
|
+
export declare function defaultBaseImage(): BaseImageInput
|
|
1653
|
+
|
|
1654
|
+
/** How `deleteImage` retries while the image refuses. */
|
|
1655
|
+
export interface DeleteImageOptions {
|
|
1656
|
+
/** Attempts before giving up. Default: the core's teardown figure. */
|
|
1657
|
+
attempts?: number
|
|
1658
|
+
/** Seconds between attempts. Default: the core's teardown figure. */
|
|
1659
|
+
backoff?: number
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
/** `Detached` as a plain object, token included, for a private store. */
|
|
1663
|
+
export interface DetachedObject {
|
|
1664
|
+
microvmId: string
|
|
1665
|
+
endpoint: string
|
|
1666
|
+
region: string
|
|
1667
|
+
port: number
|
|
1668
|
+
agentToken: string
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
/** One file `downloadDir` wrote. */
|
|
1672
|
+
export interface DownloadedFile {
|
|
1673
|
+
/** The file's path under the local directory, as the archive named it. */
|
|
1674
|
+
path: string
|
|
1675
|
+
/** The file's size in bytes. */
|
|
1676
|
+
size: number
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
/** The line range `downloadFile` reads, 1-based and inclusive. Both absent reads the file. */
|
|
1680
|
+
export interface DownloadFileOptions {
|
|
1681
|
+
/** The first line to read. Absent means line 1. */
|
|
1682
|
+
startLine?: number
|
|
1683
|
+
/** The last line to read. Absent, or past the last line, means through EOF. */
|
|
1684
|
+
endLine?: number
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
/**
|
|
1688
|
+
* The egress posture `sandbox.run` with these options would report, without launching.
|
|
1689
|
+
*
|
|
1690
|
+
* One of `"open"`, `"unsealed"`, `"best-effort"`, or `"sealed"`: the value the launched
|
|
1691
|
+
* session's `egressPosture()` and the CLI envelope's `egressPosture` carry. Throws the launch's
|
|
1692
|
+
* own `ERR_INVALID_ARG` for options it would refuse. No AWS call and no credentials, so a
|
|
1693
|
+
* harness can decide before a build whether a no-network task is satisfiable.
|
|
1694
|
+
*
|
|
1695
|
+
* Only `"sealed"` is network isolation, and no option answers it: isolation needs a VPC
|
|
1696
|
+
* egress connector and separately verified VPC routing without an internet gateway or NAT
|
|
1697
|
+
* gateway. Omitting `egress` is `"unsealed"`; `denyEgress` is `"best-effort"`. Without a
|
|
1698
|
+
* `region`, each connector ARN is checked against the region it names.
|
|
1699
|
+
*/
|
|
1700
|
+
export declare function egressPostureFor(egress?: boolean | undefined | null, connectors?: Array<string> | undefined | null, denyEgress?: boolean | undefined | null, region?: Region | undefined | null): string
|
|
1701
|
+
|
|
1702
|
+
/** What `ensureImage` returns: the ready image and how this call got it. */
|
|
1703
|
+
export interface EnsuredImage {
|
|
1704
|
+
/** The ready image; pass `image.identifier` to `run`. */
|
|
1705
|
+
image: Image
|
|
1706
|
+
/**
|
|
1707
|
+
* True when this call's own create did not build the image: it was ready, a build
|
|
1708
|
+
* already running was waited out, or a concurrent caller won the create race.
|
|
1709
|
+
*/
|
|
1710
|
+
reused: boolean
|
|
1711
|
+
/** `s3://<bucket>/<prefix>/<name>/artifact.zip`, whether or not this call uploaded it. */
|
|
1712
|
+
artifactUri: string
|
|
1713
|
+
/** Whether this call uploaded the artifact. */
|
|
1714
|
+
uploaded: boolean
|
|
1715
|
+
/** What reading the build context skipped, one line each. */
|
|
1716
|
+
warnings: Array<string>
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
/**
|
|
1720
|
+
* Everything `ensureImage` needs besides the size class.
|
|
1721
|
+
*
|
|
1722
|
+
* `baseImage` defaults to `baseImageFromDockerfile(dockerfile)`; `waitTimeoutSeconds` is
|
|
1723
|
+
* the build wait, 45 minutes by default. `contextDir` is read as `docker build` reads a
|
|
1724
|
+
* context: `Dockerfile.dockerignore`, else `.dockerignore`, is honoured, and symlinks are
|
|
1725
|
+
* skipped with a line in the result's `warnings`.
|
|
1726
|
+
*/
|
|
1727
|
+
export interface EnsureImageOptions {
|
|
1728
|
+
/** The image name's stem; the name is `<namePrefix>-<hash12>`. */
|
|
1729
|
+
namePrefix: string
|
|
1730
|
+
/** The daemon binary's bytes. */
|
|
1731
|
+
binary: Uint8Array
|
|
1732
|
+
/** The Dockerfile, usually `wrapDockerfile(task)`. */
|
|
1733
|
+
dockerfile: string
|
|
1734
|
+
/** The directory the Dockerfile's `COPY` lines read, or omitted for none. */
|
|
1735
|
+
contextDir?: string
|
|
1736
|
+
/** The artifact bucket, in the sandbox's region. */
|
|
1737
|
+
s3Bucket: string
|
|
1738
|
+
/** A key prefix inside the bucket, or omitted for the bucket root. */
|
|
1739
|
+
s3KeyPrefix?: string
|
|
1740
|
+
/** The build role. */
|
|
1741
|
+
buildRoleArn: string
|
|
1742
|
+
baseImage?: BaseImageInput
|
|
1743
|
+
/** `buildImage`'s `baseImageVersion`; it joins the name's hash. */
|
|
1744
|
+
baseImageVersion?: string
|
|
1745
|
+
/** `buildImage`'s `projectDir`; the pair joins the name's hash. */
|
|
1746
|
+
projectDir?: string
|
|
1747
|
+
/** Delete what exists under the name and build afresh. */
|
|
1748
|
+
force?: boolean
|
|
1749
|
+
tags?: Record<string, string>
|
|
1750
|
+
waitTimeoutSeconds?: number
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
/**
|
|
1754
|
+
* Every `ERR_*` code this library can raise, for a caller building an exhaustive switch.
|
|
1755
|
+
*
|
|
1756
|
+
* Enumerated from the core's own `ErrorKind::ALL` rather than transcribed, so a kind added
|
|
1757
|
+
* there appears here without an edit — a hand-written list would agree with a typo.
|
|
1758
|
+
*/
|
|
1759
|
+
export declare function errorCodes(): Array<string>
|
|
1760
|
+
|
|
1761
|
+
/**
|
|
1762
|
+
* What a plan will cost, before spending anything (COST-10).
|
|
1763
|
+
*
|
|
1764
|
+
* Takes plain seconds and marks every one projected. That is the difference from
|
|
1765
|
+
* [`run_report`]: not the arithmetic, which is shared, but what the durations admit about
|
|
1766
|
+
* themselves.
|
|
1767
|
+
*/
|
|
1768
|
+
export declare function estimateRun(size: SizeClass, options?: PlanUsageOptions | undefined | null, rates?: RateTable | undefined | null): CostReport
|
|
1769
|
+
|
|
1770
|
+
/** How an exec should be started. Every field optional; the defaults are the daemon's. */
|
|
1771
|
+
export interface ExecOptions {
|
|
1772
|
+
/**
|
|
1773
|
+
* `true` runs a single script string under `/bin/sh -c`; a string such as `"bash"`
|
|
1774
|
+
* runs it under that shell, resolved by the daemon in the guest, and a shell the guest
|
|
1775
|
+
* does not have is refused (`unknown_shell`) before anything starts.
|
|
1776
|
+
*/
|
|
1777
|
+
shell?: boolean | string
|
|
1778
|
+
cwd?: string
|
|
1779
|
+
env?: Record<string, string>
|
|
1780
|
+
/**
|
|
1781
|
+
* A numeric uid, or a name the daemon resolves against the guest's `/etc/passwd`. An
|
|
1782
|
+
* unknown name is refused (`unknown_user`) before anything starts. A user with a passwd
|
|
1783
|
+
* row gets `HOME`, `USER` and `LOGNAME` from it, beneath the launch environment and
|
|
1784
|
+
* `env`.
|
|
1785
|
+
*/
|
|
1786
|
+
user?: number | string
|
|
1787
|
+
/** A numeric gid, or a name the daemon resolves against the guest's `/etc/group`. */
|
|
1788
|
+
group?: number | string
|
|
1789
|
+
/** The daemon's own kill deadline for the child, distinct from a client-side `wait`. */
|
|
1790
|
+
timeoutSec?: number
|
|
1791
|
+
/** Whether to open a stdin pipe. Writing without this is a 409. */
|
|
1792
|
+
stdin?: boolean
|
|
1793
|
+
/**
|
|
1794
|
+
* The idempotency key. Omitted, one is minted; supplied, the daemon returns success for
|
|
1795
|
+
* a known id without spawning a second child — so a caller whose retry must be safe
|
|
1796
|
+
* across its own restart passes a stable one.
|
|
1797
|
+
*/
|
|
1798
|
+
execId?: string
|
|
1799
|
+
/** The client-side deadline for `runSync` only. */
|
|
1800
|
+
timeout?: number
|
|
1801
|
+
/**
|
|
1802
|
+
* Signal the whole process group once the command's own child exits, so nothing it
|
|
1803
|
+
* backgrounded outlives it. Off by default, which keeps the backgrounded-grandchild-output
|
|
1804
|
+
* guarantee for callers who rely on it.
|
|
1805
|
+
*/
|
|
1806
|
+
reapGroupOnExit?: boolean
|
|
1807
|
+
/**
|
|
1808
|
+
* Start the child's environment from the image's `ENV` (minus `AGENTD_*`, never the
|
|
1809
|
+
* token), beneath everything else (AGENTD-11). Off by default, which keeps the child's environment
|
|
1810
|
+
* exactly the launch environment plus `env`.
|
|
1811
|
+
*/
|
|
1812
|
+
inheritImageEnv?: boolean
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
/**
|
|
1816
|
+
* An exec's phase and, once it has one, its outcome.
|
|
1817
|
+
*
|
|
1818
|
+
* `#[napi(object)]` is right for this one: it is a pure result with no closure to protect
|
|
1819
|
+
* — there is no `ExecResult` a caller can construct wrongly, because no function takes one
|
|
1820
|
+
* — so a plain JS object with named fields is the friendlier shape and gives up nothing.
|
|
1821
|
+
*/
|
|
1822
|
+
export interface ExecResult {
|
|
1823
|
+
execId: string
|
|
1824
|
+
/** `"running"`, `"exited"`, or `"acked"`. */
|
|
1825
|
+
phase: string
|
|
1826
|
+
/** `null` when the child died to a signal rather than exiting. */
|
|
1827
|
+
exitCode?: number
|
|
1828
|
+
/** The signal that killed the child, when one did. */
|
|
1829
|
+
signal?: number
|
|
1830
|
+
stdout: string
|
|
1831
|
+
stderr: string
|
|
1832
|
+
/**
|
|
1833
|
+
* Set when either stream hit the output cap and was cut. A flag rather than a sentinel
|
|
1834
|
+
* inside the bytes, which would be indistinguishable from output containing it.
|
|
1835
|
+
*/
|
|
1836
|
+
truncated: boolean
|
|
1837
|
+
/** True when the daemon execution deadline expired, distinct from cancellation. */
|
|
1838
|
+
timedOut: boolean
|
|
1839
|
+
/**
|
|
1840
|
+
* Set when the post-exit linger deadline expired with the pipes still open: some
|
|
1841
|
+
* grandchild is alive and may write more that nobody will see.
|
|
1842
|
+
*/
|
|
1843
|
+
writersMayBeAlive: boolean
|
|
1844
|
+
/** Whether the exec has finished, whichever way. */
|
|
1845
|
+
done: boolean
|
|
1846
|
+
/**
|
|
1847
|
+
* Whether the command exited zero. False for a signal death and for a still-running
|
|
1848
|
+
* exec, since neither is a success.
|
|
1849
|
+
*/
|
|
1850
|
+
ok: boolean
|
|
1851
|
+
/**
|
|
1852
|
+
* The exit code a POSIX shell would report (BIND-6): 124 when a deadline ended the
|
|
1853
|
+
* command (the daemon's, or `runToCompletion`'s client deadline), 128 plus the signal
|
|
1854
|
+
* for any other signal death, otherwise `exitCode`. `null` only for a running exec.
|
|
1855
|
+
*/
|
|
1856
|
+
posixExitCode?: number
|
|
1857
|
+
/**
|
|
1858
|
+
* Human-readable annotations, one per condition that changes how the output reads
|
|
1859
|
+
* (BIND-7). Empty for a clean result; append them to stderr as they are.
|
|
1860
|
+
*/
|
|
1861
|
+
notes: Array<string>
|
|
1862
|
+
/**
|
|
1863
|
+
* True when `runToCompletion` synthesized this result because nothing came back after
|
|
1864
|
+
* its client-deadline kill (BIND-10): `posixExitCode` is 124 and the output is unknown.
|
|
1865
|
+
*/
|
|
1866
|
+
synthesized: boolean
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
/**
|
|
1870
|
+
* What to do when the daemon reports evicted output.
|
|
1871
|
+
*
|
|
1872
|
+
* A string union rather than an enum class, because napi renders `#[napi(string_enum)]` as a
|
|
1873
|
+
* TypeScript union of literals — `'error' | 'event'`, which is what a JS caller writes anyway
|
|
1874
|
+
* — and there is no closure here to protect (see `lib.rs` on when a class is required
|
|
1875
|
+
* instead).
|
|
1876
|
+
*/
|
|
1877
|
+
export declare const enum GapPolicy {
|
|
1878
|
+
/**
|
|
1879
|
+
* **The default.** A gap errors both streams, with the lost range in the message. See the
|
|
1880
|
+
* module docs for why an error rather than an ignorable event.
|
|
1881
|
+
*/
|
|
1882
|
+
Error = 'error',
|
|
1883
|
+
/**
|
|
1884
|
+
* A gap is recorded on [`ExecProcess::gaps`] and both streams stay open.
|
|
1885
|
+
*
|
|
1886
|
+
* For a caller that wants the surviving bytes more than the completeness guarantee. The
|
|
1887
|
+
* consumer is then responsible for reading `gaps`, and nothing forces it to.
|
|
1888
|
+
*/
|
|
1889
|
+
Event = 'event'
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
/** What a workload's hook handler did. Its output is in the daemon's log, not here. */
|
|
1893
|
+
export interface HandlerOutcome {
|
|
1894
|
+
/** The exit code, or `null` when the handler was killed or never started. */
|
|
1895
|
+
exitCode?: number
|
|
1896
|
+
/** The signal that ended it, if one did. */
|
|
1897
|
+
signal?: number
|
|
1898
|
+
/** Whether the daemon killed it at its time budget. */
|
|
1899
|
+
timedOut: boolean
|
|
1900
|
+
/** Milliseconds from spawn to exit or kill. */
|
|
1901
|
+
durationMs: number
|
|
1902
|
+
/** Why it could not run at all, such as `not executable`. */
|
|
1903
|
+
error?: string
|
|
1904
|
+
/** Whether it ran and exited 0 within its budget. */
|
|
1905
|
+
succeeded: boolean
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
/** The daemon's liveness answer. `bootstrapped` is the useful field. */
|
|
1909
|
+
export interface Health {
|
|
1910
|
+
/** The daemon's own version, distinct from the protocol version. */
|
|
1911
|
+
version: string
|
|
1912
|
+
/** Whether the run hook has landed and the control API is open. */
|
|
1913
|
+
bootstrapped: boolean
|
|
1914
|
+
/**
|
|
1915
|
+
* Bytes available to an unprivileged writer, or `null` when free space could not be
|
|
1916
|
+
* measured.
|
|
1917
|
+
*
|
|
1918
|
+
* `null` is deliberately distinct from zero: unmeasurable is not full, and a monitor
|
|
1919
|
+
* that conflated them would page on a missing `statvfs`.
|
|
1920
|
+
*/
|
|
1921
|
+
availableBytes?: number
|
|
1922
|
+
/** Bytes that must stay free before a write is refused. Zero means the guard is off. */
|
|
1923
|
+
reserveBytes?: number
|
|
1924
|
+
/**
|
|
1925
|
+
* Whether a write would be refused right now. Precomputed by the daemon so every
|
|
1926
|
+
* consumer applies the same comparison the write path does.
|
|
1927
|
+
*/
|
|
1928
|
+
underPressure?: boolean
|
|
1929
|
+
/**
|
|
1930
|
+
* Whether any startup identity repair step failed — a duplicate machine-id or boot_id
|
|
1931
|
+
* still in place from the shared image.
|
|
1932
|
+
*/
|
|
1933
|
+
identityDegraded: boolean
|
|
1934
|
+
/**
|
|
1935
|
+
* False when identity repair was switched off by config. Separate from `degraded` so a
|
|
1936
|
+
* monitor can tell "opted out" from "nothing to do".
|
|
1937
|
+
*/
|
|
1938
|
+
identityRepaired: boolean
|
|
1939
|
+
/**
|
|
1940
|
+
* Whether any exec is still running.
|
|
1941
|
+
*
|
|
1942
|
+
* For an orchestrator *outside* the VM deciding whether to keep it alive. The platform
|
|
1943
|
+
* measures idleness by inbound traffic through the endpoint proxy, which terminates
|
|
1944
|
+
* outside the guest, so an in-guest keepalive cannot reset the idle timer — polling this
|
|
1945
|
+
* from outside is both the traffic and the decision. An exec that exited and is awaiting
|
|
1946
|
+
* an ack is not busy.
|
|
1947
|
+
*/
|
|
1948
|
+
busy: boolean
|
|
1949
|
+
/**
|
|
1950
|
+
* How many execs are registered, in any phase. `busy: false` with a non-zero count is a
|
|
1951
|
+
* VM holding unacked output somebody still has to collect.
|
|
1952
|
+
*/
|
|
1953
|
+
execs: number
|
|
1954
|
+
/**
|
|
1955
|
+
* Every lifecycle-hook invocation the daemon observed, oldest first, each with its
|
|
1956
|
+
* workload handler's outcome when the image carries one. The hook routes are
|
|
1957
|
+
* reachable over loopback from inside the guest, so a workload can add entries; the
|
|
1958
|
+
* earliest are the platform's.
|
|
1959
|
+
*/
|
|
1960
|
+
hooks: Array<HookObservation>
|
|
1961
|
+
/** How many hook invocations the daemon's log cap dropped. */
|
|
1962
|
+
hooksDropped: number
|
|
1963
|
+
/**
|
|
1964
|
+
* Each identity-repair step and its outcome. Empty until the run hook repairs this
|
|
1965
|
+
* VM's identity.
|
|
1966
|
+
*/
|
|
1967
|
+
identitySteps: Array<IdentityStep>
|
|
1968
|
+
/**
|
|
1969
|
+
* How many variables the daemon's image-environment snapshot holds, or `null` when it
|
|
1970
|
+
* holds none. `null` is also what a daemon built before `inheritImageEnv` reports, and
|
|
1971
|
+
* such a daemon ignores that option. The values are never reported.
|
|
1972
|
+
*/
|
|
1973
|
+
imageEnvKeys?: number
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
/** One lifecycle-hook invocation, as the daemon observed it. */
|
|
1977
|
+
export interface HookObservation {
|
|
1978
|
+
/** `ready`, `validate`, `run`, `suspend`, `resume`, or `terminate`. */
|
|
1979
|
+
hook: string
|
|
1980
|
+
/** Seconds since the epoch on the daemon's clock when the hook arrived. */
|
|
1981
|
+
firedAt: number
|
|
1982
|
+
/** The workload handler's outcome, or `null` when the image has no handler for it. */
|
|
1983
|
+
handler?: HandlerOutcome
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
/** One identity-repair step. */
|
|
1987
|
+
export interface IdentityStep {
|
|
1988
|
+
/** `machine-id`, `hostname`, `boot-id`, `random-seed`, or `cached-credential`. */
|
|
1989
|
+
name: string
|
|
1990
|
+
/** `repaired`, `not_applicable`, or `failed`. */
|
|
1991
|
+
outcome: string
|
|
1992
|
+
/** The OS error for a failed step. */
|
|
1993
|
+
error?: string
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
/** The idle policy the service reports a VM is running under. */
|
|
1997
|
+
export interface IdlePolicy {
|
|
1998
|
+
/** `maxIdleDurationSeconds`: inbound-traffic silence before an auto-suspend. */
|
|
1999
|
+
maxIdleSec: number
|
|
2000
|
+
/** `suspendedDurationSeconds`: how long a suspended VM lasts before it is terminated. */
|
|
2001
|
+
suspendedSec: number
|
|
2002
|
+
/** `autoResumeEnabled`: whether a request to a suspended VM resumes it. */
|
|
2003
|
+
autoResume: boolean
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
/** A built image, and the log group the service created alongside it. */
|
|
2007
|
+
export interface Image {
|
|
2008
|
+
/** The image ARN, which is what `imageIdentifier` takes. */
|
|
2009
|
+
identifier: string
|
|
2010
|
+
name: string
|
|
2011
|
+
version: string
|
|
2012
|
+
state: string
|
|
2013
|
+
/**
|
|
2014
|
+
* The baseline MiB of the class the request selected.
|
|
2015
|
+
*
|
|
2016
|
+
* Carried because billing follows the baseline requested at *create* time, and by the
|
|
2017
|
+
* time anyone asks what a run cost the request is gone.
|
|
2018
|
+
*/
|
|
2019
|
+
baselineMib: number
|
|
2020
|
+
/**
|
|
2021
|
+
* `/aws/lambda-microvms/<image-name>`.
|
|
2022
|
+
*
|
|
2023
|
+
* The service creates this itself, so no Terraform stack owns it and `terraform destroy`
|
|
2024
|
+
* leaves it behind — "the stack destroyed cleanly" is not "the account is clean". Six
|
|
2025
|
+
* accumulated before anyone noticed.
|
|
2026
|
+
*/
|
|
2027
|
+
buildLogGroup: string
|
|
2028
|
+
/**
|
|
2029
|
+
* The resolved exact log stream this build's logs went to, when `logStream` was
|
|
2030
|
+
* configured — the configured prefix plus the per-build `/<16 hex>` discriminator the
|
|
2031
|
+
* client appends. `null` for an unconfigured build (the service names the streams).
|
|
2032
|
+
*
|
|
2033
|
+
* The only copy of the resolved name: the discriminator is minted fresh inside the
|
|
2034
|
+
* create call, so a caller reads it here or never.
|
|
2035
|
+
*/
|
|
2036
|
+
logStream?: string
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* One build of an image version: one per Graviton generation, so a version's builds differ
|
|
2041
|
+
* in `chipsetGeneration`. `getImageBuild` adds the snapshot sizes the listing lacks.
|
|
2042
|
+
*/
|
|
2043
|
+
export interface ImageBuild {
|
|
2044
|
+
imageArn: string
|
|
2045
|
+
imageVersion: string
|
|
2046
|
+
/** What `getImageBuild` takes, and nothing else in the API mints one. */
|
|
2047
|
+
buildId: string
|
|
2048
|
+
/** `buildState`, as the service spells it. */
|
|
2049
|
+
buildState: string
|
|
2050
|
+
architecture: string
|
|
2051
|
+
chipset: string
|
|
2052
|
+
chipsetGeneration: string
|
|
2053
|
+
/** Unix seconds. */
|
|
2054
|
+
createdAt: number
|
|
2055
|
+
/**
|
|
2056
|
+
* Why the build is in this state, when the service said: where a failed build's reason
|
|
2057
|
+
* lives.
|
|
2058
|
+
*/
|
|
2059
|
+
stateReason?: string
|
|
2060
|
+
/**
|
|
2061
|
+
* `snapshotBuild.memorySnapshotSizeInBytes`, from `getImageBuild` only, and only when the
|
|
2062
|
+
* service reported it.
|
|
2063
|
+
*/
|
|
2064
|
+
memorySnapshotSizeInBytes?: number
|
|
2065
|
+
/** `snapshotBuild.codeInstallSizeInBytes`, from `getImageBuild` only. */
|
|
2066
|
+
codeInstallSizeInBytes?: number
|
|
2067
|
+
/** `snapshotBuild.diskSnapshotSizeInBytes`, from `getImageBuild` only. */
|
|
2068
|
+
diskSnapshotSizeInBytes?: number
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
/** One `ListMicrovmImages` item: an image's ARN, name and state. */
|
|
2072
|
+
export interface ImageSummary {
|
|
2073
|
+
imageArn: string
|
|
2074
|
+
name: string
|
|
2075
|
+
/** As the service spells it, such as `"CREATING"` or `"CREATED"`. */
|
|
2076
|
+
state: string
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
/**
|
|
2080
|
+
* One image version as `ListMicrovmImageVersions` or `UpdateMicrovmImageVersion` reads it
|
|
2081
|
+
* back: its build state, whether `RunMicrovm` launches it, and what it was built with.
|
|
2082
|
+
*/
|
|
2083
|
+
export interface ImageVersion {
|
|
2084
|
+
imageArn: string
|
|
2085
|
+
imageVersion: string
|
|
2086
|
+
/** The version's build state, as the service spells it. */
|
|
2087
|
+
state: string
|
|
2088
|
+
/**
|
|
2089
|
+
* `"ACTIVE"` (`RunMicrovm` launches it) or `"INACTIVE"` (it refuses; running VMs keep
|
|
2090
|
+
* running).
|
|
2091
|
+
*/
|
|
2092
|
+
status: string
|
|
2093
|
+
/** Whether `RunMicrovm` launches this version. */
|
|
2094
|
+
isActive: boolean
|
|
2095
|
+
/**
|
|
2096
|
+
* Why the version is in this state, when the service said. A failed build's reason is on
|
|
2097
|
+
* its build (`listImageBuilds`), and this one is usually absent.
|
|
2098
|
+
*/
|
|
2099
|
+
stateReason?: string
|
|
2100
|
+
/** Unix seconds. */
|
|
2101
|
+
createdAt: number
|
|
2102
|
+
/** Unix seconds, when the service reported it. */
|
|
2103
|
+
updatedAt?: number
|
|
2104
|
+
baseImageArn: string
|
|
2105
|
+
/**
|
|
2106
|
+
* The base version the build used, as the service spells it (`"1.0"` where the managed
|
|
2107
|
+
* base lists `"1"`). A record of the build, not a value to pass back as a pin.
|
|
2108
|
+
*/
|
|
2109
|
+
baseImageVersion?: string
|
|
2110
|
+
buildRoleArn: string
|
|
2111
|
+
/** `codeArtifact.uri`: the artifact the version was built from. */
|
|
2112
|
+
codeArtifactUri: string
|
|
2113
|
+
description?: string
|
|
2114
|
+
/**
|
|
2115
|
+
* `resources[0].minimumMemoryInMiB`, the list's one member: the size class the version
|
|
2116
|
+
* was built for, and the only place a built image reports it.
|
|
2117
|
+
*/
|
|
2118
|
+
minimumMemoryMib?: number
|
|
2119
|
+
egressNetworkConnectors?: Array<string>
|
|
2120
|
+
additionalOsCapabilities?: Array<string>
|
|
2121
|
+
environmentVariables?: Record<string, string>
|
|
2122
|
+
tags?: Record<string, string>
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
/**
|
|
2126
|
+
* Installs Bedrock access for `agents` into a running VM over `session`.
|
|
2127
|
+
*
|
|
2128
|
+
* Three uploads (the environment file, Codex's config when Codex is among the agents, the
|
|
2129
|
+
* marker) and one root `chown` of `/workspace` to uid 1000. Re-runnable: a fresh token
|
|
2130
|
+
* overwrites the same files, which is how a twelve-hour token is refreshed.
|
|
2131
|
+
*/
|
|
2132
|
+
export declare function installAgentAccess(session: Session, agents: Array<AgentSpecInput>, token: BearerToken): Promise<void>
|
|
2133
|
+
|
|
2134
|
+
/**
|
|
2135
|
+
* The agents a running VM was provisioned with, read from its guest marker.
|
|
2136
|
+
*
|
|
2137
|
+
* For a process holding only a session (`Session.direct` from the identifier triple): how a
|
|
2138
|
+
* credential refresh learns which agents and models to re-provision. A VM with no marker is
|
|
2139
|
+
* refused as a precondition, naming `agent-up`.
|
|
2140
|
+
*/
|
|
2141
|
+
export declare function installedAgents(session: Session): Promise<Array<AgentSpec>>
|
|
2142
|
+
|
|
2143
|
+
/**
|
|
2144
|
+
* Whether retrying the identical call could plausibly succeed, for an error this library raised.
|
|
2145
|
+
*
|
|
2146
|
+
* The TypeScript spelling of Python's `.retryable`, read off the chain every error here
|
|
2147
|
+
* carries: `err.cause.message` is the `ERR_*` code, and core answers for its kind. A
|
|
2148
|
+
* transient condition (a refused connection, a mint failure, a daemon not yet bootstrapped)
|
|
2149
|
+
* is `true`; a full disk, a credential, or a refused argument is `false`. Anything that
|
|
2150
|
+
* isn't a library error (no cause, or a cause whose message is no `ERR_*` code) is `false`,
|
|
2151
|
+
* because nothing says a retry would land differently.
|
|
2152
|
+
*/
|
|
2153
|
+
export declare function isRetryable(error: unknown): boolean
|
|
2154
|
+
|
|
2155
|
+
/** The options bag for `keepAwake`. */
|
|
2156
|
+
export interface KeepAwakeOptions {
|
|
2157
|
+
/** Seconds between polls. Default: a third of the idle window, at most 20. */
|
|
2158
|
+
intervalSec?: number
|
|
2159
|
+
/** End once no exec is running. */
|
|
2160
|
+
whileBusy?: boolean
|
|
2161
|
+
/** End after this many seconds even if still busy. */
|
|
2162
|
+
maxDurationSec?: number
|
|
2163
|
+
/**
|
|
2164
|
+
* The VM's `maxIdleDurationSeconds`. A sandbox-held session knows it; otherwise the
|
|
2165
|
+
* platform minimum of 60 is assumed. The interval may be at most half of it.
|
|
2166
|
+
*/
|
|
2167
|
+
idleWindowSec?: number
|
|
2168
|
+
/**
|
|
2169
|
+
* How many retryable poll failures in a row are retried, a second apart, before the
|
|
2170
|
+
* keepalive ends with the error. Default: the core's `DEFAULT_TOLERATED_ERRORS`.
|
|
2171
|
+
*/
|
|
2172
|
+
toleratedErrors?: number
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
/** What a finished keepalive did. */
|
|
2176
|
+
export interface KeepAwakeReport {
|
|
2177
|
+
/** Why it ended: `"stopped"`, `"idle"`, `"elapsed"`, or `"not-running"`. */
|
|
2178
|
+
end: string
|
|
2179
|
+
/** Health polls that answered. */
|
|
2180
|
+
polls: number
|
|
2181
|
+
/** `busy` from the last answered poll, or `null` when none answered. */
|
|
2182
|
+
lastBusy?: boolean
|
|
2183
|
+
/** Seconds from start to end. */
|
|
2184
|
+
elapsedSec: number
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
/** The service's optional `ListMicrovms` filters. */
|
|
2188
|
+
export interface ListMicrovmsOptions {
|
|
2189
|
+
imageIdentifier?: string
|
|
2190
|
+
imageVersion?: string
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
/**
|
|
2194
|
+
* The three guarded values a build takes, as separate parameters rather than fields.
|
|
2195
|
+
*
|
|
2196
|
+
* # Why they are not in [`BuildImageOptions`]
|
|
2197
|
+
*
|
|
2198
|
+
* Measured, not preferred. A `#[napi(object)]` field holding a class instance must be a
|
|
2199
|
+
* `ClassInstance<'a, T>`, which carries raw `napi_value`/`napi_env` pointers and is therefore
|
|
2200
|
+
* **not `Send`** — and napi's async path requires `Future: Send`. So an options object with a
|
|
2201
|
+
* `size: SizeClass` field cannot be a parameter of an `async fn`, which
|
|
2202
|
+
* `Sandbox.buildImage` has to be. The compiler said so in as many words:
|
|
2203
|
+
* `future created by async block is not Send ... has type BuildImageOptions<'_> which is not
|
|
2204
|
+
* Send`.
|
|
2205
|
+
*
|
|
2206
|
+
* A *reference* parameter — `Option<&SizeClass>` — has no such problem, because napi
|
|
2207
|
+
* dereferences it before the future is built. So the guarded types move out of the bag and
|
|
2208
|
+
* into the signature, which loses the keyword-argument look and keeps every closure:
|
|
2209
|
+
*
|
|
2210
|
+
* * `size` still refuses an off-table baseline, because the only way to have a `SizeClass` is
|
|
2211
|
+
* `SizeClass.fromBaselineMib` or `SizeClass.defaultClass` (TRAP-10).
|
|
2212
|
+
* * `runHookTimeout` and `buildHookTimeout` are still two distinct classes, so they still
|
|
2213
|
+
* cannot be transposed — which was the whole reason they are types (BIND-2).
|
|
2214
|
+
*
|
|
2215
|
+
* A caller writes `sandbox.buildImage(opts, size, runTimeout, buildTimeout)` with the last
|
|
2216
|
+
* three optional.
|
|
2217
|
+
* One version of a managed base image, from `ListManagedMicrovmImageVersions`.
|
|
2218
|
+
*/
|
|
2219
|
+
export interface ManagedBaseVersion {
|
|
2220
|
+
imageArn: string
|
|
2221
|
+
/**
|
|
2222
|
+
* A bare integer for a managed base (`"0"`, `"1"`), where a custom image's versions read
|
|
2223
|
+
* `"1.0"`: the value `buildImage`'s pin takes, not one to compare with a build's readback.
|
|
2224
|
+
*/
|
|
2225
|
+
imageVersion: string
|
|
2226
|
+
/** Unix seconds. */
|
|
2227
|
+
createdAt: number
|
|
2228
|
+
/** Unix seconds, when the service reported it. */
|
|
2229
|
+
updatedAt?: number
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
/** A MicroVM as `GetMicrovm` last described it. */
|
|
2233
|
+
export interface Microvm {
|
|
2234
|
+
id: string
|
|
2235
|
+
/** As the service spells it. Eventually consistent. */
|
|
2236
|
+
state: string
|
|
2237
|
+
/** Why the VM is in this state, when the service said. */
|
|
2238
|
+
stateReason?: string
|
|
2239
|
+
/** The proxy endpoint. Pair it with the agent token in `Session.attach`. */
|
|
2240
|
+
endpoint: string
|
|
2241
|
+
imageArn: string
|
|
2242
|
+
imageVersion: string
|
|
2243
|
+
idlePolicy?: IdlePolicy
|
|
2244
|
+
/** `maximumDurationInSeconds`. Suspended time counts toward it. */
|
|
2245
|
+
maximumDurationSeconds?: number
|
|
2246
|
+
/** When the VM first started, as Unix seconds. */
|
|
2247
|
+
startedAt?: number
|
|
2248
|
+
/** When the VM terminated, as Unix seconds, once it has. */
|
|
2249
|
+
terminatedAt?: number
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
/** One `ListMicrovms` item: narrower than `Microvm`, with no endpoint or reason. */
|
|
2253
|
+
export interface MicrovmSummary {
|
|
2254
|
+
id: string
|
|
2255
|
+
state: string
|
|
2256
|
+
imageArn: string
|
|
2257
|
+
imageVersion: string
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
/**
|
|
2261
|
+
* Mints a Bedrock bearer token from the default credential chain.
|
|
2262
|
+
*
|
|
2263
|
+
* A SigV4 presign of `POST https://bedrock.amazonaws.com/?Action=CallWithBearerToken`,
|
|
2264
|
+
* base64, prefixed `bedrock-api-key-` — the reference generator's recipe, in process.
|
|
2265
|
+
* `ttlSeconds` defaults to the ceiling, twelve hours; more is refused by the core.
|
|
2266
|
+
*/
|
|
2267
|
+
export declare function mintBedrockToken(region: Region, ttlSeconds?: number | undefined | null): Promise<BearerToken>
|
|
2268
|
+
|
|
2269
|
+
/**
|
|
2270
|
+
* Mint using explicit STS credentials without changing the process environment.
|
|
2271
|
+
* credentialsExpiresAt is Unix seconds from STS Expiration. Do not log these inputs.
|
|
2272
|
+
*/
|
|
2273
|
+
export declare function mintBedrockTokenWithCredentials(region: Region, accessKeyId: string, secretAccessKey: string, sessionToken: string | undefined | null, credentialsExpiresAt: number, ttlSeconds?: number | undefined | null): BearerToken
|
|
2274
|
+
|
|
2275
|
+
/**
|
|
2276
|
+
* A record's JSON-safe form, with the CLI registry's camelCase keys. **Holds the agent
|
|
2277
|
+
* token**; store it privately.
|
|
2278
|
+
*/
|
|
2279
|
+
export interface NameRecordObject {
|
|
2280
|
+
name: string
|
|
2281
|
+
microvmId: string
|
|
2282
|
+
endpoint: string
|
|
2283
|
+
agentToken: string
|
|
2284
|
+
region: string
|
|
2285
|
+
/** Seconds since the epoch when the name was registered. */
|
|
2286
|
+
at: number
|
|
2287
|
+
identityHostSeed?: string
|
|
2288
|
+
identityVmPublicKey?: string
|
|
2289
|
+
egressPosture?: string
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
/**
|
|
2293
|
+
* One byte range the daemon could not replay.
|
|
2294
|
+
*
|
|
2295
|
+
* `from` inclusive, `to` exclusive — so `to` is exactly the offset a resume would pass.
|
|
2296
|
+
*/
|
|
2297
|
+
export interface OutputGap {
|
|
2298
|
+
/**
|
|
2299
|
+
* Which stream lost bytes: `"stdout"` or `"stderr"`.
|
|
2300
|
+
*
|
|
2301
|
+
* Read off the *following* output frame rather than from the gap frame, which carries no
|
|
2302
|
+
* discriminator: the wire's offset space is shared, so a gap is a hole in the combined
|
|
2303
|
+
* stream and the daemon cannot say which side's bytes were in it. `null` when the gap was
|
|
2304
|
+
* the last thing on the stream and nothing followed it to attribute it to.
|
|
2305
|
+
*/
|
|
2306
|
+
stream?: string
|
|
2307
|
+
from: number
|
|
2308
|
+
to: number
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
/**
|
|
2312
|
+
* A plan's phases, in plain seconds, before anything is spent.
|
|
2313
|
+
*
|
|
2314
|
+
* Separate from [`RunUsageOptions`] on purpose (COST-10): every field is a number, so there
|
|
2315
|
+
* is no field an accidentally-measured duration could be written into. The wrapping into
|
|
2316
|
+
* projected durations happens in the core, in one place.
|
|
2317
|
+
*/
|
|
2318
|
+
export interface PlanUsageOptions {
|
|
2319
|
+
runningSeconds?: number
|
|
2320
|
+
suspendedSeconds?: number
|
|
2321
|
+
imageGb?: number
|
|
2322
|
+
imageRetainedSeconds?: number
|
|
2323
|
+
/**
|
|
2324
|
+
* Each cycle pays a snapshot write plus a read. Left out, the plan counts none, as
|
|
2325
|
+
* `microvm cost --estimate` does.
|
|
2326
|
+
*/
|
|
2327
|
+
suspendResumeCycles?: number
|
|
2328
|
+
snapshotGb?: number
|
|
2329
|
+
/**
|
|
2330
|
+
* Whether the plan launches, which reads a snapshot. Left out, the core infers it: running
|
|
2331
|
+
* time, or an image of non-zero size, so suspended time alone reads no launch snapshot.
|
|
2332
|
+
*/
|
|
2333
|
+
launched?: boolean
|
|
2334
|
+
/**
|
|
2335
|
+
* What the report is of. Left out, `"estimate"`: the core's label, the one
|
|
2336
|
+
* `microvm cost --estimate` uses for the same plan (#255).
|
|
2337
|
+
*/
|
|
2338
|
+
label?: string
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
/** What a stopped port-forward did. */
|
|
2342
|
+
export interface PortForwardReport {
|
|
2343
|
+
/** Connections accepted. */
|
|
2344
|
+
served: number
|
|
2345
|
+
/** Exchanges the endpoint proxy refused, a 403 or a 502 among them. */
|
|
2346
|
+
refused: number
|
|
2347
|
+
/** Exchanges that upgraded, a WebSocket among them. */
|
|
2348
|
+
upgrades: number
|
|
2349
|
+
/** Proxy tokens the session minted by the time the forward stopped. */
|
|
2350
|
+
proxyTokenMints: number
|
|
2351
|
+
/** Why it stopped: `"stopped"`, `"limit"`, or `"listener-failed: <why>"`. */
|
|
2352
|
+
stopped: string
|
|
2353
|
+
/** Each connection that didn't end clean, in the order they ended. */
|
|
2354
|
+
ended: Array<ConnectionEnd>
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
/**
|
|
2358
|
+
* Whether a harness can launch in `region` (default: `$AWS_REGION`, `$AWS_DEFAULT_REGION`,
|
|
2359
|
+
* then us-east-1), checked before it queues work.
|
|
2360
|
+
*
|
|
2361
|
+
* Three checks: the region resolves (advisory when `Region.unlisted`), the credential chain
|
|
2362
|
+
* resolves credentials (no AWS call), and one `ListManagedMicrovmImages` page answers in that
|
|
2363
|
+
* region, the only AWS operation, free and read-only. A check after a failure is reported
|
|
2364
|
+
* with `ran: false` and makes no call. Nothing billable, nothing mutating. It does not check
|
|
2365
|
+
* roles, the artifact bucket, quotas, or VPC connectors. Never rejects; read `report.ok`.
|
|
2366
|
+
*/
|
|
2367
|
+
export declare function preflight(region?: Region | undefined | null): Promise<PreflightReport>
|
|
2368
|
+
|
|
2369
|
+
/** One line of a preflight report. */
|
|
2370
|
+
export interface PreflightCheck {
|
|
2371
|
+
/** `"region"`, `"credentials"`, or `"service"`. */
|
|
2372
|
+
name: string
|
|
2373
|
+
ok: boolean
|
|
2374
|
+
/** Whether a failure decides the report's `ok`. An unlisted region's line is advisory. */
|
|
2375
|
+
fatal: boolean
|
|
2376
|
+
/** False when an earlier check's failure kept this one from running (and calling AWS). */
|
|
2377
|
+
ran: boolean
|
|
2378
|
+
detail: string
|
|
2379
|
+
/** What to do about a failure; empty on a pass. */
|
|
2380
|
+
remedy: string
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
/** What `preflight` found: three checks and whether a launch could proceed. */
|
|
2384
|
+
export interface PreflightReport {
|
|
2385
|
+
/** True exactly when no fatal check failed or was skipped. */
|
|
2386
|
+
ok: boolean
|
|
2387
|
+
/** The region checked, absent when none resolved. */
|
|
2388
|
+
region?: string
|
|
2389
|
+
/** `region`, `credentials`, and `service`, in that order. */
|
|
2390
|
+
checks: Array<PreflightCheck>
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
/**
|
|
2394
|
+
* What `wait()` resolves to.
|
|
2395
|
+
*
|
|
2396
|
+
* `exitCode` and nothing else on purpose, matching the harness contract's
|
|
2397
|
+
* `wait(): PromiseLike<{ exitCode: number }>`. A caller wanting the signal, the truncation
|
|
2398
|
+
* flag, or the buffered output polls [`crate::exec::ExecHandle`] instead, which answers with
|
|
2399
|
+
* the whole record.
|
|
2400
|
+
*/
|
|
2401
|
+
export interface ProcessExit {
|
|
2402
|
+
/**
|
|
2403
|
+
* The child's exit status.
|
|
2404
|
+
*
|
|
2405
|
+
* **`null` when the child died to a signal**, which is where this shape and the harness's
|
|
2406
|
+
* `{ exitCode: number }` genuinely differ, and it is deliberate. A signal death has no
|
|
2407
|
+
* exit code, and the two available lies are `0` (a killed build reported as passing) and
|
|
2408
|
+
* `128 + signo` (a number the daemon never published, indistinguishable from a child that
|
|
2409
|
+
* really exited with it). A wrapper that must produce a number can pick one at its own
|
|
2410
|
+
* boundary; this handle will not pick for it.
|
|
2411
|
+
*/
|
|
2412
|
+
exitCode?: number
|
|
2413
|
+
/**
|
|
2414
|
+
* The signal that killed the child, when one did. Not part of the harness shape; here
|
|
2415
|
+
* because it is the only thing that makes a `null` exit code actionable.
|
|
2416
|
+
*/
|
|
2417
|
+
signal?: number
|
|
2418
|
+
/** True when the remote execution deadline expired. */
|
|
2419
|
+
timedOut: boolean
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
/**
|
|
2423
|
+
* One exec's process group, as `GET /v1/procs` reports it.
|
|
2424
|
+
*
|
|
2425
|
+
* `childExited` beside a non-empty `pids` is the shape worth reading: a command that finished
|
|
2426
|
+
* while something it backgrounded did not, which `Health.busy` cannot show. The `execId`
|
|
2427
|
+
* beside it is what `Session.kill` takes.
|
|
2428
|
+
*/
|
|
2429
|
+
export interface ProcGroup {
|
|
2430
|
+
/** The exec this group belongs to — what `kill` takes. */
|
|
2431
|
+
execId: string
|
|
2432
|
+
/**
|
|
2433
|
+
* The process group id captured at spawn, or `null` when the child was reaped before it
|
|
2434
|
+
* could be read (then `pids` is empty: there is no group to scan for).
|
|
2435
|
+
*/
|
|
2436
|
+
pgid?: number
|
|
2437
|
+
/** Seconds since the epoch on the daemon's clock when the child was spawned. */
|
|
2438
|
+
startedAt: number
|
|
2439
|
+
/** Whether the exec's own child has exited. An acked exec still reads `true`. */
|
|
2440
|
+
childExited: boolean
|
|
2441
|
+
/** Whether the exec was started with `reapGroupOnExit`. */
|
|
2442
|
+
reap: boolean
|
|
2443
|
+
/**
|
|
2444
|
+
* Live pids whose process group is `pgid`, read from `/proc` inside the guest. Zombies
|
|
2445
|
+
* are not listed. Empty once the group is gone.
|
|
2446
|
+
*/
|
|
2447
|
+
pids: Array<number>
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
/** Starts one task for `agent` over `session` and resolves with its handle. Does not wait. */
|
|
2451
|
+
export declare function promptAgent(session: Session, agent: AgentSpecInput, task: string, options?: PromptOptions | undefined | null): Promise<ExecHandle>
|
|
2452
|
+
|
|
2453
|
+
/** The knobs on one prompt. */
|
|
2454
|
+
export interface PromptOptions {
|
|
2455
|
+
/** A daemon-side wall-clock budget for the agent process, in seconds. */
|
|
2456
|
+
timeoutSec?: number
|
|
2457
|
+
/** A stable exec id, for a retry that must not spawn twice. */
|
|
2458
|
+
execId?: string
|
|
2459
|
+
/** Agent process permissions: agent-default (default) or unrestricted. */
|
|
2460
|
+
permissionMode?: 'agent-default' | 'unrestricted'
|
|
2461
|
+
/** Stop residual children when the main agent exits. Defaults to false. */
|
|
2462
|
+
reapGroupOnExit?: boolean
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
/**
|
|
2466
|
+
* The `agentd` daemon binary for `options.version` (default: this client's own).
|
|
2467
|
+
*
|
|
2468
|
+
* Answered from `options.binary` or `$MICROVM_AGENTD` when either names a file, else the
|
|
2469
|
+
* version's cache entry, else the GitHub release asset, verified in-process against the
|
|
2470
|
+
* release workflow's Sigstore attestation or, only when GitHub can't be reached for one, the
|
|
2471
|
+
* release's `SHA256SUMS`. A fetch that cannot be verified rejects with `ERR_PRECONDITION`
|
|
2472
|
+
* (on `err.cause.message`), and so does any binary that is not an aarch64 ELF. Neither
|
|
2473
|
+
* `gh` nor `curl` is needed.
|
|
2474
|
+
*/
|
|
2475
|
+
export declare function provisionAgentd(options?: ProvisionOptions | undefined | null): Promise<Buffer>
|
|
2476
|
+
|
|
2477
|
+
/** `provisionAgentd`, answering with the bytes and how they got here. */
|
|
2478
|
+
export declare function provisionAgentdReport(options?: ProvisionOptions | undefined | null): Promise<ProvisionedAgentd>
|
|
2479
|
+
|
|
2480
|
+
/** A provisioned `agentd` binary and how it got here: `provisionAgentdReport()`'s answer. */
|
|
2481
|
+
export interface ProvisionedAgentd {
|
|
2482
|
+
/** The binary itself, an aarch64 ELF. */
|
|
2483
|
+
data: Buffer
|
|
2484
|
+
/** Where the binary is on disk: the cache entry, or the caller's own path. */
|
|
2485
|
+
path: string
|
|
2486
|
+
/** `"caller-supplied"`, `"cache"`, or `"fetched"`. */
|
|
2487
|
+
source: string
|
|
2488
|
+
/**
|
|
2489
|
+
* For a caller-supplied binary, `"argument"` (the `binary` option) or `"env"`
|
|
2490
|
+
* (`$MICROVM_AGENTD`).
|
|
2491
|
+
*/
|
|
2492
|
+
suppliedBy?: string
|
|
2493
|
+
/**
|
|
2494
|
+
* `"attestation"` (the release workflow's Sigstore attestation, provenance) or
|
|
2495
|
+
* `"checksum"` (the release's `SHA256SUMS`, integrity), when fetched or when the cache
|
|
2496
|
+
* entry was installed. Absent for a caller-supplied binary.
|
|
2497
|
+
*/
|
|
2498
|
+
verification?: string
|
|
2499
|
+
/** The release version provisioned for, without a leading `v`. */
|
|
2500
|
+
version: string
|
|
2501
|
+
/** The lowercase hex SHA-256 of `data`. */
|
|
2502
|
+
sha256: string
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
/** What to provision. Every field is optional. */
|
|
2506
|
+
export interface ProvisionOptions {
|
|
2507
|
+
/** The release version, with or without a leading `v`. Defaults to `coreVersion()`. */
|
|
2508
|
+
version?: string
|
|
2509
|
+
/**
|
|
2510
|
+
* The state directory the cache lives under. Defaults to the CLI's
|
|
2511
|
+
* (`$MICROVM_STATE_DIR`, else `~/.microvm/runs`), so every surface shares one cache.
|
|
2512
|
+
*/
|
|
2513
|
+
stateDir?: string
|
|
2514
|
+
/** A binary the caller manages. Outranks `$MICROVM_AGENTD`; must be an aarch64 ELF. */
|
|
2515
|
+
binary?: string
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2518
|
+
/** Everything a launch needs. */
|
|
2519
|
+
export interface RunOptions {
|
|
2520
|
+
/**
|
|
2521
|
+
* The image to launch, as an ARN or a bare image name, or omitted for the one
|
|
2522
|
+
* `buildImage` built. The core resolves a name to its ARN with one `ListMicrovmImages`
|
|
2523
|
+
* read, and a name no image carries is refused with `ERR_PRECONDITION` before anything
|
|
2524
|
+
* launches.
|
|
2525
|
+
*/
|
|
2526
|
+
imageIdentifier?: string
|
|
2527
|
+
/**
|
|
2528
|
+
* `imageVersion`, or omitted for the image's own latest active version.
|
|
2529
|
+
*
|
|
2530
|
+
* Pinning is what makes a canary launch against the version it means to test rather than
|
|
2531
|
+
* against whatever became latest while it was starting, and it is the half of a rollback
|
|
2532
|
+
* that re-points at the known-good build. A version the control plane has set INACTIVE
|
|
2533
|
+
* refuses to launch when named here.
|
|
2534
|
+
*/
|
|
2535
|
+
imageVersion?: string
|
|
2536
|
+
/** The execution role. Optional in the model; every real launch needs one. */
|
|
2537
|
+
executionRoleArn?: string
|
|
2538
|
+
/**
|
|
2539
|
+
* The bearer token the daemon will accept, or omitted to mint one.
|
|
2540
|
+
*
|
|
2541
|
+
* Optional because the common case is a per-VM secret nobody needs to see; a caller who
|
|
2542
|
+
* has one already — a harness minting its own, or a retry that must reuse the first
|
|
2543
|
+
* attempt's — passes it. It rides in `runHookPayload`, which is what keeps it out of the
|
|
2544
|
+
* shared image snapshot.
|
|
2545
|
+
*/
|
|
2546
|
+
agentToken?: string
|
|
2547
|
+
/** Persist once per intended launch and reuse with the identical request. */
|
|
2548
|
+
clientToken?: string
|
|
2549
|
+
/**
|
|
2550
|
+
* Base environment for every exec in the launched VM, delivered in the same
|
|
2551
|
+
* `runHookPayload` as the token.
|
|
2552
|
+
*
|
|
2553
|
+
* Applied *under* each exec's own `env`, so a per-exec value wins on a shared key.
|
|
2554
|
+
* Shares the token's 4096-byte payload budget; the core refuses an over-ceiling
|
|
2555
|
+
* payload before the launch, naming the byte count.
|
|
2556
|
+
*/
|
|
2557
|
+
launchEnv?: Record<string, string>
|
|
2558
|
+
/**
|
|
2559
|
+
* Generate a tunnel identity and deliver the VM's half with the launch, so
|
|
2560
|
+
* `session.tunnel(port, {}, await sandbox.tunnelIdentity())` can prove the far end is
|
|
2561
|
+
* this VM's daemon.
|
|
2562
|
+
*/
|
|
2563
|
+
identity?: boolean
|
|
2564
|
+
/** Request the managed INTERNET_EGRESS connector. Omission does not block egress. */
|
|
2565
|
+
egress?: boolean
|
|
2566
|
+
/**
|
|
2567
|
+
* Existing VPC network connector ARNs. For no egress, use a VPC without an
|
|
2568
|
+
* internet gateway or NAT gateway. Cannot be combined with `egress: true`.
|
|
2569
|
+
*/
|
|
2570
|
+
egressNetworkConnectors?: Array<string>
|
|
2571
|
+
/**
|
|
2572
|
+
* Set advisory HTTP proxy variables. Workloads can ignore or override them;
|
|
2573
|
+
* use a VPC without an internet gateway or NAT gateway for no egress.
|
|
2574
|
+
*/
|
|
2575
|
+
denyEgress?: boolean
|
|
2576
|
+
/**
|
|
2577
|
+
* Whether to launch shell-capable: the ingress set becomes the measured pair
|
|
2578
|
+
* `[HTTP_INGRESS, SHELL_INGRESS]`, which is what `microvm shell` attaches to.
|
|
2579
|
+
*/
|
|
2580
|
+
shell?: boolean
|
|
2581
|
+
maxIdleSec?: number
|
|
2582
|
+
/** Requested suspended window, in seconds; the service also reports its idle policy. */
|
|
2583
|
+
suspendedSec?: number
|
|
2584
|
+
autoResume?: boolean
|
|
2585
|
+
maxDurationSec?: number
|
|
2586
|
+
/**
|
|
2587
|
+
* How long to wait for RUNNING. The wait for the daemon after it is the core's
|
|
2588
|
+
* `defaultReadyTimeoutSeconds`.
|
|
2589
|
+
*/
|
|
2590
|
+
readyTimeout?: number
|
|
2591
|
+
/** A label for the run token. Never the token. */
|
|
2592
|
+
tokenScope?: string
|
|
2593
|
+
/**
|
|
2594
|
+
* Whether `run` waits for RUNNING and for the daemon to answer (default `true`).
|
|
2595
|
+
* `false` resolves once the launch is accepted, with the lifecycle PENDING;
|
|
2596
|
+
* `waitUntilRunning` finishes both waits.
|
|
2597
|
+
*/
|
|
2598
|
+
wait?: boolean
|
|
2599
|
+
/** Per-VM CloudWatch log group. Omitted keeps the service's default destination. */
|
|
2600
|
+
logGroup?: string
|
|
2601
|
+
/** An exact log stream inside `logGroup`. */
|
|
2602
|
+
logStream?: string
|
|
2603
|
+
/** Turns per-VM logging off. Cannot be combined with `logGroup` or `logStream`. */
|
|
2604
|
+
disableLogging?: boolean
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
/**
|
|
2608
|
+
* Per-phase attribution for one sandbox's lifecycle.
|
|
2609
|
+
*
|
|
2610
|
+
* Every duration is a [`Duration`] class and not a number, which is what keeps the
|
|
2611
|
+
* provenance label attached: taking seconds here would need this function to pick a
|
|
2612
|
+
* provenance, and the one it would pick is the stronger claim.
|
|
2613
|
+
*/
|
|
2614
|
+
export declare function runReport(size: SizeClass, options?: RunUsageOptions | undefined | null, rates?: RateTable | undefined | null): CostReport
|
|
2615
|
+
|
|
2616
|
+
/**
|
|
2617
|
+
* Everything a measured report attributes cost to.
|
|
2618
|
+
*
|
|
2619
|
+
* `#[napi(object)]` **is** right here, unlike for the guarded types: this is an options bag
|
|
2620
|
+
* a caller writes as a literal, and every field that carries a closure is a
|
|
2621
|
+
* `ClassInstance<Duration>` rather than a number — so the object shape still cannot express
|
|
2622
|
+
* an unlabelled duration. `ClassInstance` is what makes that hold: it extracts only from a
|
|
2623
|
+
* real `Duration` instance, so `{ running: 3600 }` and `{ running: { seconds: 3600 } }` are
|
|
2624
|
+
* both rejected by napi's conversion before any Rust runs. What the object buys is optional
|
|
2625
|
+
* fields with JS's own `undefined`, which is how "this phase did not happen" is said.
|
|
2626
|
+
*/
|
|
2627
|
+
export interface RunUsageOptions {
|
|
2628
|
+
/**
|
|
2629
|
+
* Wall-clock time in RUNNING. Bills at baseline whether or not anything is executing —
|
|
2630
|
+
* there is no free I/O wait, which is why suspension rather than idleness is the lever.
|
|
2631
|
+
*/
|
|
2632
|
+
running?: Duration
|
|
2633
|
+
/** Time held suspended. Pays storage only: a suspended VM is frozen. */
|
|
2634
|
+
suspended?: Duration
|
|
2635
|
+
/** How long the image build took, if it was timed. Always unpriced. */
|
|
2636
|
+
imageBuild?: Duration
|
|
2637
|
+
/**
|
|
2638
|
+
* The image's size. Passing this adds both an image-storage line *and* the unpriced
|
|
2639
|
+
* build line, so a create-and-destroy report is never complete.
|
|
2640
|
+
*/
|
|
2641
|
+
imageGb?: number
|
|
2642
|
+
/**
|
|
2643
|
+
* How long the image was retained. Defaults to the documented one-week minimum, marked
|
|
2644
|
+
* projected — nobody timed that week either.
|
|
2645
|
+
*/
|
|
2646
|
+
imageRetained?: Duration
|
|
2647
|
+
/**
|
|
2648
|
+
* Each cycle pays a snapshot write plus a read. Left out, the report counts none, so it has
|
|
2649
|
+
* no suspend or resume line: a report claims only what the caller says happened, as
|
|
2650
|
+
* `microvm cost` does.
|
|
2651
|
+
*/
|
|
2652
|
+
suspendResumeCycles?: number
|
|
2653
|
+
/** The suspend snapshot's size. Defaults to the baseline memory footprint. */
|
|
2654
|
+
snapshotGb?: number
|
|
2655
|
+
/**
|
|
2656
|
+
* Whether a launch happened. A launch reads a snapshot. Left out, the core infers it:
|
|
2657
|
+
* running time, or an image of non-zero size.
|
|
2658
|
+
*/
|
|
2659
|
+
launched?: boolean
|
|
2660
|
+
/** What the report is of. Left out, `"run"`: the core's label, the one `microvm cost` uses. */
|
|
2661
|
+
label?: string
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
/** Where a tunnel or a port-forward listens, and when it stops on its own. */
|
|
2665
|
+
export interface ServeOptions {
|
|
2666
|
+
/**
|
|
2667
|
+
* A `host:port` to listen on. Default: loopback, on a port the OS picks; the handle's
|
|
2668
|
+
* `localAddress` says which. Bind beyond loopback only on a network you trust: whoever
|
|
2669
|
+
* connects reaches the VM with this session's credentials.
|
|
2670
|
+
*/
|
|
2671
|
+
bind?: string
|
|
2672
|
+
/** Stop accepting after this many connections. Default: serve until stopped. */
|
|
2673
|
+
maxConnections?: number
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
/**
|
|
2677
|
+
* The daemon's protocol constants, as a JSON string, for a caller asserting against the
|
|
2678
|
+
* wire contract.
|
|
2679
|
+
*/
|
|
2680
|
+
export declare function sessionConstants(): string
|
|
2681
|
+
|
|
2682
|
+
/**
|
|
2683
|
+
* How a `spawn` should behave: the exec's own options, plus the stream's.
|
|
2684
|
+
*
|
|
2685
|
+
* Nested rather than flattened onto [`ExecOptions`], and the reason is that the two sets are
|
|
2686
|
+
* answered by different people. `cwd`/`env`/`user` describe the *child* and are what a caller
|
|
2687
|
+
* composing a command supplies; `offset`/`reconnect`/`gapPolicy` describe how this client
|
|
2688
|
+
* reads the child's output and are what a caller composing a *resume* supplies. Flattening
|
|
2689
|
+
* them would put `maxReconnects` next to `user` in one bag, which is where a caller reaches
|
|
2690
|
+
* for the wrong one.
|
|
2691
|
+
*/
|
|
2692
|
+
export interface SpawnOptions {
|
|
2693
|
+
/**
|
|
2694
|
+
* How to start the child. Identical to `run`'s options, deliberately: `spawn` is a
|
|
2695
|
+
* different view of one exec rather than a different exec.
|
|
2696
|
+
*/
|
|
2697
|
+
exec?: ExecOptions
|
|
2698
|
+
/**
|
|
2699
|
+
* The byte to start reading at. Non-zero resumes output a previous process was reading —
|
|
2700
|
+
* which, with a stable `exec.execId`, is how a spawned process survives *this* process
|
|
2701
|
+
* restarting.
|
|
2702
|
+
*/
|
|
2703
|
+
offset?: number
|
|
2704
|
+
/**
|
|
2705
|
+
* Whether to reconnect after a cut. Defaults to true, and turning it off is what makes a
|
|
2706
|
+
* suspend/resume look like a stream that ended.
|
|
2707
|
+
*/
|
|
2708
|
+
reconnect?: boolean
|
|
2709
|
+
/** How many reconnects before the streams error. A bound rather than forever. */
|
|
2710
|
+
maxReconnects?: number
|
|
2711
|
+
/** How long the body may be silent before the connection is treated as dead, in seconds. */
|
|
2712
|
+
idleTimeout?: number
|
|
2713
|
+
/**
|
|
2714
|
+
* What to do when the daemon reports evicted output. Defaults to `'error'`; see
|
|
2715
|
+
* [`crate::process`] for why.
|
|
2716
|
+
*/
|
|
2717
|
+
gapPolicy?: GapPolicy
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
/** What a stdin write accomplished. */
|
|
2721
|
+
export interface StdinAck {
|
|
2722
|
+
execId: string
|
|
2723
|
+
written: number
|
|
2724
|
+
eof: boolean
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2727
|
+
/**
|
|
2728
|
+
* One event off an exec's output stream.
|
|
2729
|
+
*
|
|
2730
|
+
* One object with a `kind` discriminant rather than three classes, because JS has no
|
|
2731
|
+
* `instanceof` over a union a caller can `switch` on cleanly and the TypeScript idiom is a
|
|
2732
|
+
* tagged union. `kind` is `"output"`, `"gap"`, or `"exit"`, and the fields for the other
|
|
2733
|
+
* two shapes are `null` — which keeps [`Self::exit_code`] distinguishable from an output
|
|
2734
|
+
* chunk that happens to be last. The absence of an `exit` event is what tells a cut
|
|
2735
|
+
* connection from a finished command; the byte sequences are otherwise identical.
|
|
2736
|
+
*/
|
|
2737
|
+
export interface StreamEvent {
|
|
2738
|
+
/** `"output"`, `"gap"`, or `"exit"`. */
|
|
2739
|
+
kind: string
|
|
2740
|
+
/**
|
|
2741
|
+
* `"stdout"` or `"stderr"`, for an output event. Both share one offset space, so a
|
|
2742
|
+
* caller holds one cursor rather than two that can disagree about ordering.
|
|
2743
|
+
*/
|
|
2744
|
+
stream?: string
|
|
2745
|
+
/** Where an output chunk starts, or where a gap starts. */
|
|
2746
|
+
offset?: number
|
|
2747
|
+
/**
|
|
2748
|
+
* One past an output chunk's last byte, or a gap's exclusive end — either way, where a
|
|
2749
|
+
* cursor resumes. `null` on an exit event, whose offset is a *total* rather than a
|
|
2750
|
+
* position, so resuming from it would ask the daemon to replay from the end.
|
|
2751
|
+
*/
|
|
2752
|
+
end?: number
|
|
2753
|
+
/** The bytes, for an output event. */
|
|
2754
|
+
data?: Buffer
|
|
2755
|
+
/** The bytes as text, replacing anything undecodable. `data` is the lossless form. */
|
|
2756
|
+
text?: string
|
|
2757
|
+
/** Total bytes published, on an exit event. */
|
|
2758
|
+
totalOffset?: number
|
|
2759
|
+
exitCode?: number
|
|
2760
|
+
signal?: number
|
|
2761
|
+
truncated?: boolean
|
|
2762
|
+
/** Present on exit: whether the remote execution deadline expired. */
|
|
2763
|
+
timedOut?: boolean
|
|
2764
|
+
writersMayBeAlive?: boolean
|
|
2765
|
+
}
|
|
2766
|
+
|
|
2767
|
+
/** How a stream should behave. */
|
|
2768
|
+
export interface StreamOptionsInput {
|
|
2769
|
+
/** The byte to start at. Non-zero resumes a stream a previous process was reading. */
|
|
2770
|
+
offset?: number
|
|
2771
|
+
/**
|
|
2772
|
+
* Whether to reconnect after a cut. `false` ends the stream at the cut instead, which
|
|
2773
|
+
* is what a caller doing its own reconnection wants.
|
|
2774
|
+
*/
|
|
2775
|
+
reconnect?: boolean
|
|
2776
|
+
/**
|
|
2777
|
+
* How many reconnects before giving up. A bound rather than forever, because a stream
|
|
2778
|
+
* that drops every time is a condition a caller needs reported.
|
|
2779
|
+
*/
|
|
2780
|
+
maxReconnects?: number
|
|
2781
|
+
/**
|
|
2782
|
+
* Turns a gap into a rejection instead of an event. What a caller that must have
|
|
2783
|
+
* complete output wants.
|
|
2784
|
+
*/
|
|
2785
|
+
errorOnGap?: boolean
|
|
2786
|
+
/** How long the body may be silent before the connection is treated as dead. */
|
|
2787
|
+
idleTimeout?: number
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
/** How `syncDir` should behave. */
|
|
2791
|
+
export interface SyncDirOptions {
|
|
2792
|
+
/** Ignore the manifest the last sync left in the VM and upload everything. */
|
|
2793
|
+
full?: boolean
|
|
2794
|
+
/** The in-VM removal's deadline, in seconds. Default: core's, 60. */
|
|
2795
|
+
deleteTimeout?: number
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
/** What one `syncDir` did. */
|
|
2799
|
+
export interface SyncReport {
|
|
2800
|
+
/** The uploaded archive's size, 0 when nothing travelled. */
|
|
2801
|
+
uploadedBytes: number
|
|
2802
|
+
/** How many members the upload carried: the changed ones, or every one when `full`. */
|
|
2803
|
+
uploadedMembers: number
|
|
2804
|
+
/** How many paths gone locally were removed in the VM. */
|
|
2805
|
+
deleted: number
|
|
2806
|
+
/** Deletions the VM's manifest ordered that weren't plain relative paths, so weren't run. */
|
|
2807
|
+
refusedDeletions: number
|
|
2808
|
+
/** No manifest was read (`full: true`, or none in the VM), so the whole tree travelled. */
|
|
2809
|
+
full: boolean
|
|
2810
|
+
/** The VM already held the tree as it is, so nothing travelled. */
|
|
2811
|
+
unchanged: boolean
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
/**
|
|
2815
|
+
* What a teardown should delete beyond the VM itself.
|
|
2816
|
+
*
|
|
2817
|
+
* Both deletions are opt-in, because both destroy something a caller may still want: the
|
|
2818
|
+
* image is reusable across runs, and the log group is where a failed build's only evidence
|
|
2819
|
+
* lives.
|
|
2820
|
+
*/
|
|
2821
|
+
export interface TeardownOptions {
|
|
2822
|
+
deleteImage?: boolean
|
|
2823
|
+
/**
|
|
2824
|
+
* **Names** the group in `report.undeleted` rather than deleting it — CloudWatch is not
|
|
2825
|
+
* in the core's dependency set, and reporting a leak beats reporting a clean teardown
|
|
2826
|
+
* over one.
|
|
2827
|
+
*/
|
|
2828
|
+
deleteLogGroup?: boolean
|
|
2829
|
+
deleteAttempts?: number
|
|
2830
|
+
deleteBackoff?: number
|
|
2831
|
+
/**
|
|
2832
|
+
* `false` by default: the caller is on the way out, and a teardown that blocked five
|
|
2833
|
+
* minutes on a state nobody reads is five minutes of a CI job. The report then honestly
|
|
2834
|
+
* ends in `"TERMINATING"`. `true` waits for TERMINATED up to the core's lifecycle default;
|
|
2835
|
+
* a number of seconds waits up to that instead.
|
|
2836
|
+
*/
|
|
2837
|
+
waitForTerminated?: boolean | number
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
/** What a teardown did, and what it left behind. */
|
|
2841
|
+
export interface TeardownReport {
|
|
2842
|
+
/**
|
|
2843
|
+
* Identifiers of everything a caller asked to have deleted that still exists.
|
|
2844
|
+
*
|
|
2845
|
+
* Identifiers rather than a boolean, because a leak nobody can name is a leak nobody can
|
|
2846
|
+
* clean up. Two things land here: a delete that was attempted and failed, and the build
|
|
2847
|
+
* **log group**, which this client cannot delete at all.
|
|
2848
|
+
*/
|
|
2849
|
+
undeleted: Array<string>
|
|
2850
|
+
/** Whether the terminate call was accepted. */
|
|
2851
|
+
terminateAccepted: boolean
|
|
2852
|
+
/** Whether the image was deleted, or `null` when deletion was not asked for. */
|
|
2853
|
+
imageDeleted?: boolean
|
|
2854
|
+
/**
|
|
2855
|
+
* The lifecycle state the sandbox ended in.
|
|
2856
|
+
*
|
|
2857
|
+
* Commonly `"TERMINATING"` rather than `"TERMINATED"`: the default teardown does not
|
|
2858
|
+
* wait, so claiming TERMINATED would claim an observation nobody made. Pass
|
|
2859
|
+
* `waitForTerminated: true` to observe it.
|
|
2860
|
+
*/
|
|
2861
|
+
lifecycle?: string
|
|
2862
|
+
/**
|
|
2863
|
+
* Every failure the teardown swallowed, in the order it hit them.
|
|
2864
|
+
*
|
|
2865
|
+
* Kept because a teardown that never throws is a teardown whose failures are invisible
|
|
2866
|
+
* otherwise, and the first one is usually the cause of the rest.
|
|
2867
|
+
*/
|
|
2868
|
+
failures: Array<string>
|
|
2869
|
+
/** Whether anything a caller asked for was left behind. */
|
|
2870
|
+
leaked: boolean
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
/** What a stopped tunnel did. */
|
|
2874
|
+
export interface TunnelReport {
|
|
2875
|
+
/** Connections accepted. */
|
|
2876
|
+
served: number
|
|
2877
|
+
/** Connections the daemon refused, or that failed with an error. */
|
|
2878
|
+
refused: number
|
|
2879
|
+
/**
|
|
2880
|
+
* Verified connections that ended without the daemon's end of stream, so their stream
|
|
2881
|
+
* may have been cut short.
|
|
2882
|
+
*/
|
|
2883
|
+
truncated: number
|
|
2884
|
+
/**
|
|
2885
|
+
* Verified connections into a daemon from before the end of stream, whose end nothing
|
|
2886
|
+
* proved.
|
|
2887
|
+
*/
|
|
2888
|
+
unproven: number
|
|
2889
|
+
/** Proxy tokens the session minted by the time the tunnel stopped. */
|
|
2890
|
+
proxyTokenMints: number
|
|
2891
|
+
/** Why it stopped: `"stopped"`, `"limit"`, or `"listener-failed: <why>"`. */
|
|
2892
|
+
stopped: string
|
|
2893
|
+
/** Each connection that didn't end clean, in the order they ended. */
|
|
2894
|
+
ended: Array<ConnectionEnd>
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
/** How `waitForState` polls. */
|
|
2898
|
+
export interface WaitForStateOptions {
|
|
2899
|
+
/** States that reject with `stateReason` instead of being waited through. */
|
|
2900
|
+
failOn?: Array<string>
|
|
2901
|
+
/** Seconds before giving up. Default 300. */
|
|
2902
|
+
timeout?: number
|
|
2903
|
+
/** Seconds between polls. Default 5. */
|
|
2904
|
+
pollInterval?: number
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
/** Every daemon-status class, as `err.cause.cause.message` names them. */
|
|
2908
|
+
export declare function wireKinds(): Array<string>
|
|
2909
|
+
|
|
2910
|
+
/**
|
|
2911
|
+
* A task Dockerfile with the agentd stanza appended, ready for `buildImage`.
|
|
2912
|
+
*
|
|
2913
|
+
* The result is the task text, a newline if it lacked one, `USER root` when the task's last
|
|
2914
|
+
* `USER` is anyone else, then the stanza the default Dockerfile uses: `COPY agentd /agentd`,
|
|
2915
|
+
* the chmod, `ENV AGENTD_PORT`, `EXPOSE`, `ENTRYPOINT []` and `CMD ["/agentd"]`. Pass the
|
|
2916
|
+
* result to `buildImage` with `baseImage: baseImageFromDockerfile(result)`.
|
|
2917
|
+
*
|
|
2918
|
+
* Throws `ERR_INVALID_ARG` for a task with no `FROM`, one that ends inside a line
|
|
2919
|
+
* continuation or an unterminated heredoc (either would swallow the stanza), a keepalive the
|
|
2920
|
+
* client cannot tolerate, a port of 0, a workdir that is not one absolute path, or
|
|
2921
|
+
* `inheritWorkdir` with nothing to inherit.
|
|
2922
|
+
*/
|
|
2923
|
+
export declare function wrapDockerfile(taskDockerfile: string, options?: WrapDockerfileOptions | undefined | null): string
|
|
2924
|
+
|
|
2925
|
+
/** What `wrapDockerfile` takes besides the task text. Every field is optional. */
|
|
2926
|
+
export interface WrapDockerfileOptions {
|
|
2927
|
+
/** The agent port the stanza names, 9000 by default. It must match the sandbox's. */
|
|
2928
|
+
port?: number
|
|
2929
|
+
/** A working directory for the stanza to create and set, as the default Dockerfile does. */
|
|
2930
|
+
workdir?: string
|
|
2931
|
+
/** Refuse a result with no `WORKDIR` anywhere, because the exec would inherit `/`. */
|
|
2932
|
+
inheritWorkdir?: boolean
|
|
2933
|
+
}
|