@theagenticguy/microvms 0.7.0 → 0.9.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 CHANGED
@@ -1,53 +1,156 @@
1
1
  # @theagenticguy/microvms
2
2
 
3
- Node bindings over `microvms-core`, the client library for AWS Lambda MicroVMs.
3
+ Run coding agents and their tools in sandboxed AWS Lambda MicroVMs. Give each
4
+ task its own Linux workspace, execute commands, collect files, and terminate
5
+ the VM from JavaScript or TypeScript. `AgentVm` runs Claude Code or Codex
6
+ through Amazon Bedrock; `Sandbox` supports your own agent or command runner.
4
7
 
5
- ```bash
8
+ ## Install
9
+
10
+ ```sh
6
11
  npm install @theagenticguy/microvms
7
12
  ```
8
13
 
9
- A prebuilt native addon per platform, selected through `optionalDependencies`. No compiler
10
- and no install-time download script runs on a consumer's machine.
14
+ Requires Node.js **22.13.0+**. Native addons ship for Linux x64/ARM64 (glibc),
15
+ macOS Apple Silicon, and Windows x64. TypeScript declarations are included.
11
16
 
12
- Requires Node >= 22.13.
17
+ ## Run your first command
13
18
 
14
- ## Async-native
19
+ With an existing image and AWS credentials, this is the 90-second path to a
20
+ working SDK example. One-time AWS setup and image builds take longer.
15
21
 
16
- The core's async surface maps straight through: an exported `async` function runs on napi's
17
- managed runtime and returns a real `Promise`, with an error rejecting it. Exec output and
18
- stdin are handed across as `ReadableStream<Uint8Array>` rather than as async iterators a
19
- consumer would have to adapt.
22
+ You need Lambda MicroVMs access, your normal AWS credential configuration,
23
+ and an execution role. Follow [AWS setup](https://laithalsaadoon.github.io/microvms-agentd/learn/tutorial/first-run/)
24
+ to set `AWS_REGION` and `MICROVM_EXECUTION_ROLE_ARN`. Then use the
25
+ [CLI](https://laithalsaadoon.github.io/microvms-agentd/learn/tutorial/install/)
26
+ to prepare an image containing `agentd`:
20
27
 
21
- ## The traps are in the types
28
+ ```sh
29
+ microvm build --name agent-tools --json
30
+ export MICROVM_IMAGE='paste data.imageIdentifier from the result'
31
+ ```
22
32
 
23
- The constraints the platform enforces at runtime are shapes this package refuses to
24
- construct: a raw token cannot be passed where a session is expected, and a dollar amount is
25
- never a bare float. Each planted bypass has a test that goes red if the door reopens.
33
+ Use the **image ARN**, in the same account and region as your credentials.
34
+ The CLI can resolve image names; the SDK example takes the ARN directly.
35
+ The CLI provisions `agentd` and uploads the build artifact for you.
36
+ Shell examples use Bash or Zsh; in PowerShell, set variables with `$env:NAME='value'`.
37
+
38
+ Save as `hello.mjs`:
39
+
40
+ ```js
41
+ import { Region, Sandbox } from '@theagenticguy/microvms';
42
+
43
+ const imageIdentifier = process.env.MICROVM_IMAGE;
44
+ const executionRoleArn = process.env.MICROVM_EXECUTION_ROLE_ARN;
45
+ if (!imageIdentifier || !executionRoleArn) {
46
+ throw new Error('Set MICROVM_IMAGE and MICROVM_EXECUTION_ROLE_ARN first');
47
+ }
48
+ const vm = await Sandbox.create(Region.parse(process.env.AWS_REGION ?? 'us-east-1'));
49
+ try {
50
+ const session = await vm.run({ imageIdentifier, executionRoleArn });
51
+ const result = await session.runSync(['echo', 'hello from a sandbox']);
52
+ process.stdout.write(result.stdout);
53
+ process.stderr.write(result.stderr);
54
+ if (!result.ok) process.exitCode = 1;
55
+ } finally {
56
+ const cleanup = await vm.terminate();
57
+ if (cleanup.failures.length || cleanup.undeleted.length) {
58
+ console.error('Cleanup needs attention:', cleanup);
59
+ process.exitCode = 1;
60
+ }
61
+ }
62
+ ```
26
63
 
27
- ## Coding agents in a VM
64
+ ```sh
65
+ node hello.mjs
66
+ ```
28
67
 
29
- `AgentVm` is the L3 layer over the sandbox: an image with Claude Code and/or Codex CLI in
30
- it, a launch with egress, a Bedrock bearer token minted in process and installed as a file
31
- the agent sources, and one method that hands the agent a task as uid 1000 in `/workspace`.
68
+ Expected output: `hello from a sandbox`. The VM is terminated after the
69
+ command; the image stays available for reuse. `terminate()` returns once
70
+ termination is accepted by default. Pass `{ waitForTerminated: true }` to
71
+ wait for the final state. Inspect `failures` and `undeleted` because cleanup
72
+ reports failures in its result.
32
73
 
33
- ```ts
34
- const vm = await AgentVm.create(Region.usEast1(), [{ agent: 'codex' }]);
35
- await vm.launch({ imageIdentifier: imageArn, executionRoleArn: role });
36
- await vm.installAccess();
37
- console.log((await vm.promptSync('codex', 'Create hello.py that prints hello, run it.')).stdout);
38
- await vm.terminate();
39
- ```
74
+ ## Run a coding agent
40
75
 
41
- `findImage`, `imageName`, `buildArtifact`, and `buildImage` cover the image, with the S3
42
- upload left to you. `installedAgents`, `installAgentAccess`, and `promptAgent` do the same
43
- over a bare `Session` for a process that holds only the identifier triple.
76
+ First prepare a Claude Code image using the same AWS setup plus
77
+ [Bedrock permissions](https://laithalsaadoon.github.io/microvms-agentd/learn/operations/run-coding-agents-on-bedrock/).
78
+ This builds or reuses the agent image and starts a temporary VM. Capture
79
+ only its image ARN, then terminate that temporary VM:
44
80
 
45
- ## Reading
81
+ ```sh
82
+ MICROVM_AGENT_IMAGE="$(microvm agent-up --vm-name sdk-image --agent claude-code --json |
83
+ node -pe 'JSON.parse(require("node:fs").readFileSync(0, "utf8")).data.imageIdentifier')"
84
+ export MICROVM_AGENT_IMAGE
85
+ microvm terminate sdk-image --wait
86
+ ```
46
87
 
47
- - [Documentation](https://laithalsaadoon.github.io/microvms-agentd/)
48
- - [`docs/EMBEDDING.md`](https://github.com/laithalsaadoon/microvms-agentd/blob/main/docs/EMBEDDING.md)
49
- - [`docs/TRUST.md`](https://github.com/laithalsaadoon/microvms-agentd/blob/main/docs/TRUST.md)
88
+ Save as `agent.mjs`. The agent writes a file inside its own VM; the SDK
89
+ downloads that file before cleanup:
90
+
91
+ ```js
92
+ import { writeFile } from 'node:fs/promises';
93
+ import { AgentVm, Region } from '@theagenticguy/microvms';
94
+
95
+ const imageIdentifier = process.env.MICROVM_AGENT_IMAGE;
96
+ const executionRoleArn = process.env.MICROVM_EXECUTION_ROLE_ARN;
97
+ if (!imageIdentifier || !executionRoleArn) {
98
+ throw new Error('Set MICROVM_AGENT_IMAGE and MICROVM_EXECUTION_ROLE_ARN first');
99
+ }
100
+ const vm = await AgentVm.create(Region.parse(process.env.AWS_REGION ?? 'us-east-1'));
101
+ try {
102
+ const session = await vm.launch({ imageIdentifier, executionRoleArn });
103
+ await vm.installAccess();
104
+ const result = await vm.promptSync(
105
+ 'claude-code',
106
+ 'Create /workspace/hello.py that prints hello from a sandbox. Run it.',
107
+ );
108
+ process.stdout.write(result.stdout);
109
+ process.stderr.write(result.stderr);
110
+ if (!result.ok) throw new Error(`Agent exited with ${result.exitCode}`);
111
+ await writeFile('hello-from-agent.py', await session.downloadFile('/workspace/hello.py'));
112
+ } finally {
113
+ const cleanup = await vm.terminate();
114
+ if (cleanup.failures.length || cleanup.undeleted.length) {
115
+ console.error('Cleanup needs attention:', cleanup);
116
+ process.exitCode = 1;
117
+ }
118
+ }
119
+ ```
50
120
 
51
- ## License
121
+ ```sh
122
+ node agent.mjs
123
+ ```
52
124
 
53
- Apache-2.0
125
+ For Codex, prepare the image with `--agent codex`, create the VM with
126
+ `AgentVm.create(region, [{ agent: 'codex' }])`, and prompt `'codex'`.
127
+ Agent images must contain the agent you select. Agents run as UID/GID 1000
128
+ in `/workspace`; `installAccess()` installs a short-lived Bedrock token
129
+ after launch. `AgentVm` enables internet egress for model calls.
130
+
131
+ ## Next steps
132
+
133
+ For a `Sandbox` named `vm` and its `session`:
134
+
135
+ | Need | API |
136
+ | --- | --- |
137
+ | Start a task and poll or stream later | `session.run(argv)` → `ExecHandle` |
138
+ | Read live output as byte streams | `session.spawn(argv)` → `ExecProcess` |
139
+ | Keep the VM awake while an exec runs | `await session.keepAwake({ whileBusy: true })` → `KeepAwake` |
140
+ | Upload input or download results | `session.uploadFile(path, bytes)`, `session.downloadFile(path)` |
141
+ | Transfer a directory | `session.uploadTar(path, tarBytes)`, `session.downloadTar(path)` |
142
+ | Freeze and restore a workspace | `vm.suspend()`, `vm.resume()` |
143
+
144
+ `runSync` returns a Promise: it starts a command, waits, and acknowledges
145
+ its saved output. A nonzero exit is a result, so check `result.ok` or
146
+ `result.exitCode`. Use `{ shell: true }` when passing a shell script string.
147
+ Async library errors expose their `ERR_*` code through `error.cause.message`.
148
+
149
+ Omitting `egress` does not block outbound traffic. For no egress, use
150
+ `egressNetworkConnectors: [vpcConnectorArn]` with a VPC without an internet
151
+ gateway, NAT gateway, or other internet route. `denyEgress` sets advisory proxy variables that
152
+ workloads can bypass. Keep the guest execution role limited to the task's needs.
153
+
154
+ [SDK tutorial](https://laithalsaadoon.github.io/microvms-agentd/learn/tutorial/from-code/)
155
+ · [API reference](https://laithalsaadoon.github.io/microvms-agentd/reference/public-api/)
156
+ · [Source](https://github.com/laithalsaadoon/microvms-agentd) · Apache-2.0
package/index.d.ts CHANGED
@@ -1,6 +1,14 @@
1
1
  /* auto-generated by NAPI-RS */
2
2
  /* eslint-disable */
3
3
 
4
+ /**
5
+ * Which binding artifact the generated loader actually loaded: `'native'` for
6
+ * a native addon, otherwise the `platformArchABI` of the WASI flavor. Every
7
+ * flavor napi-rs can build is listed, because `NAPI_RS_NATIVE_LIBRARY_PATH`
8
+ * can point the loader at a WASI artifact this package does not build itself.
9
+ */
10
+ export declare const __napiBindingTarget: 'native' | 'wasm32-wasi' | 'wasm32-wasip1'
11
+
4
12
  /**
5
13
  * One VM with coding agents in it: the sandbox plus the specs it is built for.
6
14
  *
@@ -17,6 +25,15 @@ export declare class AgentVm {
17
25
  * the core before any AWS call.
18
26
  */
19
27
  static create(region: Region, agents?: Array<AgentSpecInput> | undefined | null): Promise<AgentVm>
28
+ /** Adopts the agent VM registered as `name` in `registry`; see `Sandbox.fromName`. */
29
+ static fromName(region: Region, name: string, registry: NameRegistry, agents?: Array<AgentSpecInput> | undefined | null, port?: number | undefined | null): Promise<AgentVm>
30
+ /**
31
+ * An agent VM for a VM another process launched; see `Sandbox.adopt`.
32
+ *
33
+ * `agents` states what the VM carries and defaults to Claude Code alone; read
34
+ * `installedAgents(session)` first when the adopting process does not know.
35
+ */
36
+ static adopt(region: Region, microvmId: string, endpoint: string, agentToken: string, agents?: Array<AgentSpecInput> | undefined | null, port?: number | undefined | null): Promise<AgentVm>
20
37
  /** The specs this VM carries, resolved, in profile order. */
21
38
  agents(): Array<AgentSpec>
22
39
  region(): Region
@@ -50,8 +67,10 @@ export declare class AgentVm {
50
67
  /**
51
68
  * Launches with egress and waits for the daemon to answer.
52
69
  *
53
- * Egress is not optional: neither agent reaches Bedrock without it. The idle knobs default
54
- * to the core's figures (ten-minute idle and suspended windows, a one-hour ceiling).
70
+ * Egress is not optional: neither agent reaches Bedrock without it. The managed internet
71
+ * connector is the default; `egressNetworkConnectors` replaces it with customer-managed
72
+ * VPC connectors, whose VPC must route to Bedrock. The idle knobs default to the core's
73
+ * figures (ten-minute idle and suspended windows, a one-hour ceiling).
55
74
  */
56
75
  launch(options: AgentLaunchOptions): Promise<Session>
57
76
  /**
@@ -102,8 +121,8 @@ export declare class BearerToken {
102
121
  /** The token text, for a caller writing it into an environment themselves. */
103
122
  expose(): string
104
123
  /**
105
- * The presign's expiry, seconds since the epoch. An upper bound: the service also caps
106
- * validity at the signing credentials' own expiry.
124
+ * Effective Unix expiry, capped at the known signing credential expiry.
125
+ * With missing credential expiry metadata this is only an upper bound.
107
126
  */
108
127
  get expiresAt(): number
109
128
  /** The region the token was minted for. */
@@ -122,6 +141,39 @@ export declare class BuildHookTimeout {
122
141
  toString(): string
123
142
  }
124
143
 
144
+ /**
145
+ * MicroVM lifecycle by ID: get, list, suspend, resume, terminate, and wait.
146
+ *
147
+ * Holds no lifecycle state, so it checks nothing a `Sandbox` would (STATE-5, STATE-7,
148
+ * STATE-12). Use it when a process has only an identifier.
149
+ */
150
+ export declare class ControlPlane {
151
+ /**
152
+ * Resolves credentials for `region` from the default chain. A factory because
153
+ * credential resolution is async.
154
+ */
155
+ static create(region: Region): Promise<ControlPlane>
156
+ /** `GetMicrovm`. */
157
+ get(microvmId: string): Promise<Microvm>
158
+ /** `ListMicrovms`, every page, optionally narrowed to one image and version. */
159
+ list(options?: ListMicrovmsOptions | undefined | null): Promise<Array<MicrovmSummary>>
160
+ /** `SuspendMicrovm`. Resolves once accepted; `waitForState` for SUSPENDED. */
161
+ suspend(microvmId: string): Promise<void>
162
+ /** `ResumeMicrovm`. Resolves once accepted; `waitForState` for RUNNING. */
163
+ resume(microvmId: string): Promise<void>
164
+ /** `TerminateMicrovm`. Resolves once accepted; `waitForState` for TERMINATED. */
165
+ terminate(microvmId: string): Promise<void>
166
+ /**
167
+ * Polls `GetMicrovm` until the state is one of `wanted`.
168
+ *
169
+ * Reaching one of `failOn` first rejects naming the state and `stateReason`; running
170
+ * past `timeout` rejects with a timeout.
171
+ */
172
+ waitForState(microvmId: string, wanted: Array<string>, options?: WaitForStateOptions | undefined | null): Promise<Microvm>
173
+ /** The region this plane addresses. */
174
+ get region(): string
175
+ }
176
+
125
177
  /** Per-phase attribution for one sandbox, measured or projected. */
126
178
  export declare class CostReport {
127
179
  get label(): string
@@ -350,6 +402,19 @@ export declare class ExecProcess {
350
402
  */
351
403
  export declare class ExecStream {}
352
404
 
405
+ /**
406
+ * A running keepalive. Call `stop()` when the work is done; `done()` resolves when it
407
+ * ends on its own. A garbage-collected handle stops the keepalive.
408
+ */
409
+ export declare class KeepAwake {
410
+ /** Whether the keepalive is still polling. */
411
+ get running(): boolean
412
+ /** Stops polling and resolves with the report; rejects with the error that ended it. */
413
+ stop(): Promise<KeepAwakeReport>
414
+ /** Resolves when the keepalive ends (`whileBusy`, `maxDurationSec`, or `stop()`). */
415
+ done(): Promise<KeepAwakeReport>
416
+ }
417
+
353
418
  /** One phase's one billing line: what was consumed, and what that costs. */
354
419
  export declare class LineItem {
355
420
  get phase(): string
@@ -383,6 +448,68 @@ export declare class LineItem {
383
448
  toString(): string
384
449
  }
385
450
 
451
+ /** One named VM: everything `Sandbox.adopt` needs, under a name. */
452
+ export declare class NameRecord {
453
+ /**
454
+ * A record for a VM this process can already address. Refuses an illegal name or an
455
+ * empty id, endpoint, or token.
456
+ */
457
+ constructor(name: string, microvmId: string, endpoint: string, agentToken: string, region: Region)
458
+ /** A record naming the VM `sandbox` addresses — launched or adopted. */
459
+ static forSandbox(name: string, sandbox: Sandbox): Promise<NameRecord>
460
+ /** A record from `toObject()` output (or a CLI registry file's JSON), checked. */
461
+ static fromObject(object: NameRecordObject): NameRecord
462
+ /**
463
+ * The record as a plain object, **agent token included** — the form to store privately
464
+ * and read back with `fromObject`.
465
+ */
466
+ toObject(): NameRecordObject
467
+ get name(): string
468
+ get microvmId(): string
469
+ get endpoint(): string
470
+ /**
471
+ * The VM's bearer credential. A method rather than a getter, so it is never read by
472
+ * accident; store it only privately.
473
+ */
474
+ agentToken(): string
475
+ get region(): string
476
+ /** Seconds since the epoch when the name was registered. */
477
+ get at(): number
478
+ get egressPosture(): string | null
479
+ /** The record without its secrets. */
480
+ toString(): string
481
+ }
482
+
483
+ /**
484
+ * The CLI's name registry: one owner-only JSON file per name under `<stateDir>/names/`.
485
+ *
486
+ * `stateDir` defaults to the CLI's — `$MICROVM_STATE_DIR`, else `~/.microvm/runs` — so a
487
+ * name registered here resolves in `microvm exec --name` and the reverse.
488
+ */
489
+ export declare class NameRegistry {
490
+ constructor(stateDir?: string | undefined | null)
491
+ /** The directory holding the name files. */
492
+ get directory(): string
493
+ /**
494
+ * The record registered as `name`, or `null`. A file that exists but does not parse
495
+ * throws rather than reading as free.
496
+ */
497
+ get(name: string): NameRecord | null
498
+ /** Writes `record` under its name, replacing any earlier record, owner-only on Unix. */
499
+ put(record: NameRecord): void
500
+ /** Names the VM `sandbox` addresses and writes the record; resolves with it. */
501
+ register(name: string, sandbox: Sandbox): Promise<NameRecord>
502
+ /** Removes `name`, answering whether a record was there. */
503
+ delete(name: string): boolean
504
+ /** Every readable record, sorted by name. */
505
+ list(): Array<NameRecord>
506
+ /**
507
+ * Removes every name registered to `microvmId` and returns them — the step after a
508
+ * terminate, so no name outlives its VM.
509
+ */
510
+ releaseByVm(microvmId: string): Array<string>
511
+ }
512
+
386
513
  /** The pinned rate table, and everything it says about itself. */
387
514
  export declare class RateTable {
388
515
  /**
@@ -554,6 +681,23 @@ export declare class Sandbox {
554
681
  wasTerminated(): Promise<boolean>
555
682
  /** How many times the token has been installed. Never above one (STATE-3). */
556
683
  bootstrapCount(): Promise<number>
684
+ /**
685
+ * A sandbox for a VM another process launched, from its private record.
686
+ *
687
+ * The lifecycle is read from `GetMicrovm`, so suspend, resume, and terminate start from
688
+ * the service's state and keep every guard. The VM was bootstrapped by its own launch,
689
+ * so `run` is refused and no run-hook payload is ever sent. Never publish or log
690
+ * `agentToken`; it appears in no error.
691
+ */
692
+ static adopt(region: Region, microvmId: string, endpoint: string, agentToken: string, port?: number | undefined | null): Promise<Sandbox>
693
+ /**
694
+ * Adopts the VM registered as `name` in `registry`; see `Sandbox.adopt`.
695
+ *
696
+ * `region` must match the record's: an id from another region addresses nothing here.
697
+ */
698
+ static fromName(region: Region, name: string, registry: NameRegistry, port?: number | undefined | null): Promise<Sandbox>
699
+ /** Whether this sandbox was built by `adopt` rather than by its own launch. */
700
+ adopted(): Promise<boolean>
557
701
  /** The VM id, once launched. */
558
702
  microvmId(): Promise<string | null>
559
703
  /** The proxy endpoint, once launched. */
@@ -570,9 +714,8 @@ export declare class Sandbox {
570
714
  /**
571
715
  * The suspended window this sandbox asked for at launch, in seconds.
572
716
  *
573
- * `null` before a launch, and for a sandbox that did not send the launch — this client is
574
- * the only party that can name the number, because `suspendedDurationSeconds` exists only
575
- * in the `RunMicrovm` request.
717
+ * `null` before this sandbox launches a VM. This accessor reports the requested
718
+ * window; `GetMicrovm` also returns the service's idle policy.
576
719
  */
577
720
  suspendedWindowSecondsAsync(): Promise<number | null>
578
721
  /**
@@ -609,6 +752,14 @@ export declare class Sandbox {
609
752
  * `Sandbox`. A run with no image at all, before any call. Neither check is in this file.
610
753
  */
611
754
  run(options?: RunOptions | undefined | null): Promise<Session>
755
+ /**
756
+ * Finishes a `run({ wait: false })`: waits for RUNNING and resolves with the session.
757
+ *
758
+ * A launch whose `clientToken` adopted an existing, idle-suspended VM resumes it; a
759
+ * fresh launch that reaches a terminal state first rejects with the service's
760
+ * `stateReason`. Refused unless the launch is still PENDING.
761
+ */
762
+ waitUntilRunning(timeout?: number | undefined | null): Promise<Session>
612
763
  /**
613
764
  * Freezes the VM and waits for the platform to report it.
614
765
  *
@@ -660,12 +811,30 @@ export declare class Session {
660
811
  * in would be handing in one that expires.
661
812
  */
662
813
  static direct(endpoint: string, agentToken: string): Session
814
+ /**
815
+ * Reattach using a private control record, without bootstrapping again.
816
+ * Owns its transport independently of sandbox locks; use a separate attach with
817
+ * a short requestTimeout for keepalives. Never publish or log agentToken.
818
+ */
819
+ static attach(region: Region, microvmId: string, endpoint: string, agentToken: string, port?: number | undefined | null, requestTimeout?: number | undefined | null): Promise<Session>
820
+ /** The guest bearer credential. Store only in a private encrypted control record. */
821
+ agentToken(): Promise<string>
663
822
  /** The endpoint this session addresses. */
664
823
  endpoint(): Promise<string>
665
824
  /** The port the proxy token is scoped to. */
666
825
  port(): Promise<number>
667
826
  /** Unauthenticated liveness. */
668
827
  health(): Promise<Health>
828
+ /**
829
+ * Keeps the VM awake by polling health from this process until stopped.
830
+ *
831
+ * The platform counts only inbound requests as activity, so an exec working with no
832
+ * client traffic is suspended once `maxIdleDurationSeconds` passes. Resolves at once
833
+ * with a running handle. On a sandbox-held session a suspend or terminate through the
834
+ * sandbox ends the keepalive before its next poll; stop it before suspending through
835
+ * anything else, or the next poll auto-resumes the VM.
836
+ */
837
+ keepAwake(options?: KeepAwakeOptions | undefined | null): Promise<KeepAwake>
669
838
  /**
670
839
  * Polls health until the daemon reports bootstrapped.
671
840
  *
@@ -708,6 +877,14 @@ export declare class Session {
708
877
  runSync(command: string | Array<string>, options?: ExecOptions | undefined | null): Promise<ExecResult>
709
878
  /** Signals an exec's whole process group. Returns whether anything was signalled. */
710
879
  kill(execId: string): Promise<boolean>
880
+ /**
881
+ * Process accounting: every registered exec with its group's live pids.
882
+ *
883
+ * The daemon reads `/proc` itself, so this needs no `ps` in the guest. A `ProcGroup` with
884
+ * `childExited` and a non-empty `pids` is a command that finished while something it
885
+ * backgrounded did not; pass its `execId` to `kill`.
886
+ */
887
+ procs(): Promise<Array<ProcGroup>>
711
888
  /**
712
889
  * Writes one file, creating parents. `mode` is an **octal string** (`"0755"`), which is
713
890
  * the daemon's shape — a number here would be ambiguous between 0o755 and 755.
@@ -862,10 +1039,27 @@ export interface AgentLaunchOptions {
862
1039
  imageIdentifier: string
863
1040
  /** The execution role. Optional in the model; every real launch needs one. */
864
1041
  executionRoleArn?: string
1042
+ /** Persist this secret privately before launch when recovery is needed. */
1043
+ agentToken?: string
1044
+ /** Persist once per intended launch and reuse with the identical request. */
1045
+ clientToken?: string
865
1046
  maxIdleSec?: number
866
1047
  suspendedSec?: number
867
1048
  autoResume?: boolean
868
1049
  maxDurationSec?: number
1050
+ /** Pins the launch to one image version rather than the latest active one. */
1051
+ imageVersion?: string
1052
+ /**
1053
+ * Customer-managed VPC egress connector ARNs. When given they replace the managed
1054
+ * internet connector, and the VPC must route to Bedrock.
1055
+ */
1056
+ egressNetworkConnectors?: Array<string>
1057
+ /** Per-VM CloudWatch log group. Omitted keeps the service's default destination. */
1058
+ logGroup?: string
1059
+ /** An exact log stream inside `logGroup`. */
1060
+ logStream?: string
1061
+ /** Turns per-VM logging off. Cannot be combined with `logGroup` or `logStream`. */
1062
+ disableLogging?: boolean
869
1063
  }
870
1064
 
871
1065
  /** A resolved spec: the model it will use and the command `prompt` runs. */
@@ -1033,6 +1227,12 @@ export interface ExecOptions {
1033
1227
  execId?: string
1034
1228
  /** The client-side deadline for `runSync` only. */
1035
1229
  timeout?: number
1230
+ /**
1231
+ * Signal the whole process group once the command's own child exits, so nothing it
1232
+ * backgrounded outlives it. Off by default, which keeps the backgrounded-grandchild-output
1233
+ * guarantee for callers who rely on it.
1234
+ */
1235
+ reapGroupOnExit?: boolean
1036
1236
  }
1037
1237
 
1038
1238
  /**
@@ -1057,6 +1257,8 @@ export interface ExecResult {
1057
1257
  * inside the bytes, which would be indistinguishable from output containing it.
1058
1258
  */
1059
1259
  truncated: boolean
1260
+ /** True when the daemon execution deadline expired, distinct from cancellation. */
1261
+ timedOut: boolean
1060
1262
  /**
1061
1263
  * Set when the post-exit linger deadline expired with the pipes still open: some
1062
1264
  * grandchild is alive and may write more that nobody will see.
@@ -1094,6 +1296,22 @@ export declare const enum GapPolicy {
1094
1296
  Event = 'event',
1095
1297
  }
1096
1298
 
1299
+ /** What a workload's hook handler did. Its output is in the daemon's log, not here. */
1300
+ export interface HandlerOutcome {
1301
+ /** The exit code, or `null` when the handler was killed or never started. */
1302
+ exitCode?: number
1303
+ /** The signal that ended it, if one did. */
1304
+ signal?: number
1305
+ /** Whether the daemon killed it at its time budget. */
1306
+ timedOut: boolean
1307
+ /** Milliseconds from spawn to exit or kill. */
1308
+ durationMs: number
1309
+ /** Why it could not run at all, such as `not executable`. */
1310
+ error?: string
1311
+ /** Whether it ran and exited 0 within its budget. */
1312
+ succeeded: boolean
1313
+ }
1314
+
1097
1315
  /** The daemon's liveness answer. `bootstrapped` is the useful field. */
1098
1316
  export interface Health {
1099
1317
  /** The daemon's own version, distinct from the protocol version. */
@@ -1140,6 +1358,50 @@ export interface Health {
1140
1358
  * VM holding unacked output somebody still has to collect.
1141
1359
  */
1142
1360
  execs: number
1361
+ /**
1362
+ * Every lifecycle-hook invocation the daemon observed, oldest first, each with its
1363
+ * workload handler's outcome when the image carries one. The hook routes are
1364
+ * reachable over loopback from inside the guest, so a workload can add entries; the
1365
+ * earliest are the platform's.
1366
+ */
1367
+ hooks: Array<HookObservation>
1368
+ /** How many hook invocations the daemon's log cap dropped. */
1369
+ hooksDropped: number
1370
+ /**
1371
+ * Each identity-repair step and its outcome. Empty until the run hook repairs this
1372
+ * VM's identity.
1373
+ */
1374
+ identitySteps: Array<IdentityStep>
1375
+ }
1376
+
1377
+ /** One lifecycle-hook invocation, as the daemon observed it. */
1378
+ export interface HookObservation {
1379
+ /** `ready`, `validate`, `run`, `suspend`, `resume`, or `terminate`. */
1380
+ hook: string
1381
+ /** Seconds since the epoch on the daemon's clock when the hook arrived. */
1382
+ firedAt: number
1383
+ /** The workload handler's outcome, or `null` when the image has no handler for it. */
1384
+ handler?: HandlerOutcome
1385
+ }
1386
+
1387
+ /** One identity-repair step. */
1388
+ export interface IdentityStep {
1389
+ /** `machine-id`, `hostname`, `boot-id`, `random-seed`, or `cached-credential`. */
1390
+ name: string
1391
+ /** `repaired`, `not_applicable`, or `failed`. */
1392
+ outcome: string
1393
+ /** The OS error for a failed step. */
1394
+ error?: string
1395
+ }
1396
+
1397
+ /** The idle policy the service reports a VM is running under. */
1398
+ export interface IdlePolicy {
1399
+ /** `maxIdleDurationSeconds`: inbound-traffic silence before an auto-suspend. */
1400
+ maxIdleSec: number
1401
+ /** `suspendedDurationSeconds`: how long a suspended VM lasts before it is terminated. */
1402
+ suspendedSec: number
1403
+ /** `autoResumeEnabled`: whether a request to a suspended VM resumes it. */
1404
+ autoResume: boolean
1143
1405
  }
1144
1406
 
1145
1407
  /** A built image, and the log group the service created alongside it. */
@@ -1193,6 +1455,67 @@ export declare function installAgentAccess(session: Session, agents: Array<Agent
1193
1455
  */
1194
1456
  export declare function installedAgents(session: Session): Promise<Array<AgentSpec>>
1195
1457
 
1458
+ /** The options bag for `keepAwake`. */
1459
+ export interface KeepAwakeOptions {
1460
+ /** Seconds between polls. Default: a third of the idle window, at most 20. */
1461
+ intervalSec?: number
1462
+ /** End once no exec is running. */
1463
+ whileBusy?: boolean
1464
+ /** End after this many seconds even if still busy. */
1465
+ maxDurationSec?: number
1466
+ /**
1467
+ * The VM's `maxIdleDurationSeconds`. A sandbox-held session knows it; otherwise the
1468
+ * platform minimum of 60 is assumed. The interval may be at most half of it.
1469
+ */
1470
+ idleWindowSec?: number
1471
+ }
1472
+
1473
+ /** What a finished keepalive did. */
1474
+ export interface KeepAwakeReport {
1475
+ /** Why it ended: `"stopped"`, `"idle"`, `"elapsed"`, or `"not-running"`. */
1476
+ end: string
1477
+ /** Health polls that answered. */
1478
+ polls: number
1479
+ /** `busy` from the last answered poll, or `null` when none answered. */
1480
+ lastBusy?: boolean
1481
+ /** Seconds from start to end. */
1482
+ elapsedSec: number
1483
+ }
1484
+
1485
+ /** The service's optional `ListMicrovms` filters. */
1486
+ export interface ListMicrovmsOptions {
1487
+ imageIdentifier?: string
1488
+ imageVersion?: string
1489
+ }
1490
+
1491
+ /** A MicroVM as `GetMicrovm` last described it. */
1492
+ export interface Microvm {
1493
+ id: string
1494
+ /** As the service spells it. Eventually consistent. */
1495
+ state: string
1496
+ /** Why the VM is in this state, when the service said. */
1497
+ stateReason?: string
1498
+ /** The proxy endpoint. Pair it with the agent token in `Session.attach`. */
1499
+ endpoint: string
1500
+ imageArn: string
1501
+ imageVersion: string
1502
+ idlePolicy?: IdlePolicy
1503
+ /** `maximumDurationInSeconds`. Suspended time counts toward it. */
1504
+ maximumDurationSeconds?: number
1505
+ /** When the VM first started, as Unix seconds. */
1506
+ startedAt?: number
1507
+ /** When the VM terminated, as Unix seconds, once it has. */
1508
+ terminatedAt?: number
1509
+ }
1510
+
1511
+ /** One `ListMicrovms` item: narrower than `Microvm`, with no endpoint or reason. */
1512
+ export interface MicrovmSummary {
1513
+ id: string
1514
+ state: string
1515
+ imageArn: string
1516
+ imageVersion: string
1517
+ }
1518
+
1196
1519
  /**
1197
1520
  * Mints a Bedrock bearer token from the default credential chain.
1198
1521
  *
@@ -1202,6 +1525,29 @@ export declare function installedAgents(session: Session): Promise<Array<AgentSp
1202
1525
  */
1203
1526
  export declare function mintBedrockToken(region: Region, ttlSeconds?: number | undefined | null): Promise<BearerToken>
1204
1527
 
1528
+ /**
1529
+ * Mint using explicit STS credentials without changing the process environment.
1530
+ * credentialsExpiresAt is Unix seconds from STS Expiration. Do not log these inputs.
1531
+ */
1532
+ export declare function mintBedrockTokenWithCredentials(region: Region, accessKeyId: string, secretAccessKey: string, sessionToken: string | undefined | null, credentialsExpiresAt: number, ttlSeconds?: number | undefined | null): BearerToken
1533
+
1534
+ /**
1535
+ * A record's JSON-safe form, with the CLI registry's camelCase keys. **Holds the agent
1536
+ * token**; store it privately.
1537
+ */
1538
+ export interface NameRecordObject {
1539
+ name: string
1540
+ microvmId: string
1541
+ endpoint: string
1542
+ agentToken: string
1543
+ region: string
1544
+ /** Seconds since the epoch when the name was registered. */
1545
+ at: number
1546
+ identityHostSeed?: string
1547
+ identityVmPublicKey?: string
1548
+ egressPosture?: string
1549
+ }
1550
+
1205
1551
  /**
1206
1552
  * One byte range the daemon could not replay.
1207
1553
  *
@@ -1264,6 +1610,36 @@ export interface ProcessExit {
1264
1610
  * because it is the only thing that makes a `null` exit code actionable.
1265
1611
  */
1266
1612
  signal?: number
1613
+ /** True when the remote execution deadline expired. */
1614
+ timedOut: boolean
1615
+ }
1616
+
1617
+ /**
1618
+ * One exec's process group, as `GET /v1/procs` reports it.
1619
+ *
1620
+ * `childExited` beside a non-empty `pids` is the shape worth reading: a command that finished
1621
+ * while something it backgrounded did not, which `Health.busy` cannot show. The `execId`
1622
+ * beside it is what `Session.kill` takes.
1623
+ */
1624
+ export interface ProcGroup {
1625
+ /** The exec this group belongs to — what `kill` takes. */
1626
+ execId: string
1627
+ /**
1628
+ * The process group id captured at spawn, or `null` when the child was reaped before it
1629
+ * could be read (then `pids` is empty: there is no group to scan for).
1630
+ */
1631
+ pgid?: number
1632
+ /** Seconds since the epoch on the daemon's clock when the child was spawned. */
1633
+ startedAt: number
1634
+ /** Whether the exec's own child has exited. An acked exec still reads `true`. */
1635
+ childExited: boolean
1636
+ /** Whether the exec was started with `reapGroupOnExit`. */
1637
+ reap: boolean
1638
+ /**
1639
+ * Live pids whose process group is `pgid`, read from `/proc` inside the guest. Zombies
1640
+ * are not listed. Empty once the group is gone.
1641
+ */
1642
+ pids: Array<number>
1267
1643
  }
1268
1644
 
1269
1645
  /** Starts one task for `agent` over `session` and resolves with its handle. Does not wait. */
@@ -1275,6 +1651,10 @@ export interface PromptOptions {
1275
1651
  timeoutSec?: number
1276
1652
  /** A stable exec id, for a retry that must not spawn twice. */
1277
1653
  execId?: string
1654
+ /** Agent process permissions: agent-default (default) or unrestricted. */
1655
+ permissionMode?: 'agent-default' | 'unrestricted'
1656
+ /** Stop residual children when the main agent exits. Defaults to false. */
1657
+ reapGroupOnExit?: boolean
1278
1658
  }
1279
1659
 
1280
1660
  /** Everything a launch needs. */
@@ -1301,6 +1681,8 @@ export interface RunOptions {
1301
1681
  * shared image snapshot.
1302
1682
  */
1303
1683
  agentToken?: string
1684
+ /** Persist once per intended launch and reuse with the identical request. */
1685
+ clientToken?: string
1304
1686
  /**
1305
1687
  * Base environment for every exec in the launched VM, delivered in the same
1306
1688
  * `runHookPayload` as the token.
@@ -1310,18 +1692,25 @@ export interface RunOptions {
1310
1692
  * payload before the launch, naming the byte count.
1311
1693
  */
1312
1694
  launchEnv?: Record<string, string>
1313
- /** Whether to request the egress connector. Off means no outbound network. */
1695
+ /** Request the managed INTERNET_EGRESS connector. Omission does not block egress. */
1314
1696
  egress?: boolean
1697
+ /**
1698
+ * Existing VPC network connector ARNs. For no egress, use a VPC without an
1699
+ * internet gateway or NAT gateway. Cannot be combined with `egress: true`.
1700
+ */
1701
+ egressNetworkConnectors?: Array<string>
1702
+ /**
1703
+ * Set advisory HTTP proxy variables. Workloads can ignore or override them;
1704
+ * use a VPC without an internet gateway or NAT gateway for no egress.
1705
+ */
1706
+ denyEgress?: boolean
1315
1707
  /**
1316
1708
  * Whether to launch shell-capable: the ingress set becomes the measured pair
1317
1709
  * `[HTTP_INGRESS, SHELL_INGRESS]`, which is what `microvm shell` attaches to.
1318
1710
  */
1319
1711
  shell?: boolean
1320
1712
  maxIdleSec?: number
1321
- /**
1322
- * The window a resume is refused past (STATE-12). Exists **only** in the launch request:
1323
- * `GetMicrovm` does not return it, so this client is the only party that can name it.
1324
- */
1713
+ /** Requested suspended window, in seconds; the service also reports its idle policy. */
1325
1714
  suspendedSec?: number
1326
1715
  autoResume?: boolean
1327
1716
  maxDurationSec?: number
@@ -1329,6 +1718,17 @@ export interface RunOptions {
1329
1718
  readyTimeout?: number
1330
1719
  /** A label for the run token. Never the token. */
1331
1720
  tokenScope?: string
1721
+ /**
1722
+ * Whether `run` waits for RUNNING (default `true`). `false` resolves once the launch
1723
+ * is accepted, with the lifecycle PENDING; `waitUntilRunning` finishes it.
1724
+ */
1725
+ wait?: boolean
1726
+ /** Per-VM CloudWatch log group. Omitted keeps the service's default destination. */
1727
+ logGroup?: string
1728
+ /** An exact log stream inside `logGroup`. */
1729
+ logStream?: string
1730
+ /** Turns per-VM logging off. Cannot be combined with `logGroup` or `logStream`. */
1731
+ disableLogging?: boolean
1332
1732
  }
1333
1733
 
1334
1734
  /**
@@ -1466,6 +1866,8 @@ export interface StreamEvent {
1466
1866
  exitCode?: number
1467
1867
  signal?: number
1468
1868
  truncated?: boolean
1869
+ /** Present on exit: whether the remote execution deadline expired. */
1870
+ timedOut?: boolean
1469
1871
  writersMayBeAlive?: boolean
1470
1872
  }
1471
1873
 
@@ -1550,5 +1952,15 @@ export interface TeardownReport {
1550
1952
  leaked: boolean
1551
1953
  }
1552
1954
 
1955
+ /** How `waitForState` polls. */
1956
+ export interface WaitForStateOptions {
1957
+ /** States that reject with `stateReason` instead of being waited through. */
1958
+ failOn?: Array<string>
1959
+ /** Seconds before giving up. Default 300. */
1960
+ timeout?: number
1961
+ /** Seconds between polls. Default 5. */
1962
+ pollInterval?: number
1963
+ }
1964
+
1553
1965
  /** Every daemon-status class, as `err.cause.cause.message` names them. */
1554
1966
  export declare function wireKinds(): Array<string>
package/index.js CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  const { readFileSync } = require('fs')
6
6
  let nativeBinding = null
7
+ // Which artifact actually loaded. The WASI fallback chain overwrites it with
8
+ // the flavor it resolved; the late native retry below leaves it alone because
9
+ // it only runs while no WASI candidate has been loaded.
10
+ let __napiLoadedBindingTarget = 'native'
7
11
  const loadErrors = []
8
12
 
9
13
  const isMusl = () => {
@@ -62,7 +66,16 @@ const isMuslFromChildProcess = () => {
62
66
  function requireNative() {
63
67
  if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
64
68
  try {
65
- return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
69
+ const overrideBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
70
+ // The override may be a generated WASI loader, which already reports its
71
+ // own flavor. Adopt it: `module.exports` aliases this object, so claiming
72
+ // 'native' would both misreport the artifact and overwrite the loader's
73
+ // marker through the alias.
74
+ __napiLoadedBindingTarget =
75
+ overrideBinding && typeof overrideBinding.__napiBindingTarget === 'string'
76
+ ? overrideBinding.__napiBindingTarget
77
+ : 'native'
78
+ return overrideBinding
66
79
  } catch (err) {
67
80
  loadErrors.push(err)
68
81
  }
@@ -76,8 +89,8 @@ function requireNative() {
76
89
  try {
77
90
  const binding = require('@theagenticguy/microvms-android-arm64')
78
91
  const bindingPackageVersion = require('@theagenticguy/microvms-android-arm64/package.json').version
79
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
80
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
92
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
93
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
81
94
  }
82
95
  return binding
83
96
  } catch (e) {
@@ -92,8 +105,8 @@ function requireNative() {
92
105
  try {
93
106
  const binding = require('@theagenticguy/microvms-android-arm-eabi')
94
107
  const bindingPackageVersion = require('@theagenticguy/microvms-android-arm-eabi/package.json').version
95
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
96
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
108
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
109
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
97
110
  }
98
111
  return binding
99
112
  } catch (e) {
@@ -113,8 +126,8 @@ function requireNative() {
113
126
  try {
114
127
  const binding = require('@theagenticguy/microvms-win32-x64-gnu')
115
128
  const bindingPackageVersion = require('@theagenticguy/microvms-win32-x64-gnu/package.json').version
116
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
117
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
129
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
130
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
118
131
  }
119
132
  return binding
120
133
  } catch (e) {
@@ -129,8 +142,8 @@ function requireNative() {
129
142
  try {
130
143
  const binding = require('@theagenticguy/microvms-win32-x64-msvc')
131
144
  const bindingPackageVersion = require('@theagenticguy/microvms-win32-x64-msvc/package.json').version
132
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
133
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
145
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
146
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
134
147
  }
135
148
  return binding
136
149
  } catch (e) {
@@ -146,8 +159,8 @@ function requireNative() {
146
159
  try {
147
160
  const binding = require('@theagenticguy/microvms-win32-ia32-msvc')
148
161
  const bindingPackageVersion = require('@theagenticguy/microvms-win32-ia32-msvc/package.json').version
149
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
150
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
162
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
163
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
151
164
  }
152
165
  return binding
153
166
  } catch (e) {
@@ -162,8 +175,8 @@ function requireNative() {
162
175
  try {
163
176
  const binding = require('@theagenticguy/microvms-win32-arm64-msvc')
164
177
  const bindingPackageVersion = require('@theagenticguy/microvms-win32-arm64-msvc/package.json').version
165
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
166
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
178
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
179
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
167
180
  }
168
181
  return binding
169
182
  } catch (e) {
@@ -181,8 +194,8 @@ function requireNative() {
181
194
  try {
182
195
  const binding = require('@theagenticguy/microvms-darwin-universal')
183
196
  const bindingPackageVersion = require('@theagenticguy/microvms-darwin-universal/package.json').version
184
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
185
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
197
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
198
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
186
199
  }
187
200
  return binding
188
201
  } catch (e) {
@@ -197,8 +210,8 @@ function requireNative() {
197
210
  try {
198
211
  const binding = require('@theagenticguy/microvms-darwin-x64')
199
212
  const bindingPackageVersion = require('@theagenticguy/microvms-darwin-x64/package.json').version
200
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
201
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
213
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
214
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
202
215
  }
203
216
  return binding
204
217
  } catch (e) {
@@ -213,8 +226,8 @@ function requireNative() {
213
226
  try {
214
227
  const binding = require('@theagenticguy/microvms-darwin-arm64')
215
228
  const bindingPackageVersion = require('@theagenticguy/microvms-darwin-arm64/package.json').version
216
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
217
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
229
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
230
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
218
231
  }
219
232
  return binding
220
233
  } catch (e) {
@@ -233,8 +246,8 @@ function requireNative() {
233
246
  try {
234
247
  const binding = require('@theagenticguy/microvms-freebsd-x64')
235
248
  const bindingPackageVersion = require('@theagenticguy/microvms-freebsd-x64/package.json').version
236
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
237
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
249
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
250
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
238
251
  }
239
252
  return binding
240
253
  } catch (e) {
@@ -249,8 +262,8 @@ function requireNative() {
249
262
  try {
250
263
  const binding = require('@theagenticguy/microvms-freebsd-arm64')
251
264
  const bindingPackageVersion = require('@theagenticguy/microvms-freebsd-arm64/package.json').version
252
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
253
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
265
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
266
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
254
267
  }
255
268
  return binding
256
269
  } catch (e) {
@@ -270,8 +283,8 @@ function requireNative() {
270
283
  try {
271
284
  const binding = require('@theagenticguy/microvms-linux-x64-musl')
272
285
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-x64-musl/package.json').version
273
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
274
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
286
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
287
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
275
288
  }
276
289
  return binding
277
290
  } catch (e) {
@@ -286,8 +299,8 @@ function requireNative() {
286
299
  try {
287
300
  const binding = require('@theagenticguy/microvms-linux-x64-gnu')
288
301
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-x64-gnu/package.json').version
289
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
290
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
302
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
303
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
291
304
  }
292
305
  return binding
293
306
  } catch (e) {
@@ -304,8 +317,8 @@ function requireNative() {
304
317
  try {
305
318
  const binding = require('@theagenticguy/microvms-linux-arm64-musl')
306
319
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-arm64-musl/package.json').version
307
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
308
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
320
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
321
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
309
322
  }
310
323
  return binding
311
324
  } catch (e) {
@@ -320,8 +333,8 @@ function requireNative() {
320
333
  try {
321
334
  const binding = require('@theagenticguy/microvms-linux-arm64-gnu')
322
335
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-arm64-gnu/package.json').version
323
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
324
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
336
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
337
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
325
338
  }
326
339
  return binding
327
340
  } catch (e) {
@@ -338,8 +351,8 @@ function requireNative() {
338
351
  try {
339
352
  const binding = require('@theagenticguy/microvms-linux-arm-musleabihf')
340
353
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-arm-musleabihf/package.json').version
341
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
342
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
354
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
355
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
343
356
  }
344
357
  return binding
345
358
  } catch (e) {
@@ -354,8 +367,8 @@ function requireNative() {
354
367
  try {
355
368
  const binding = require('@theagenticguy/microvms-linux-arm-gnueabihf')
356
369
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-arm-gnueabihf/package.json').version
357
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
358
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
370
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
371
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
359
372
  }
360
373
  return binding
361
374
  } catch (e) {
@@ -372,8 +385,8 @@ function requireNative() {
372
385
  try {
373
386
  const binding = require('@theagenticguy/microvms-linux-loong64-musl')
374
387
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-loong64-musl/package.json').version
375
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
376
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
388
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
389
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
377
390
  }
378
391
  return binding
379
392
  } catch (e) {
@@ -388,8 +401,8 @@ function requireNative() {
388
401
  try {
389
402
  const binding = require('@theagenticguy/microvms-linux-loong64-gnu')
390
403
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-loong64-gnu/package.json').version
391
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
392
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
404
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
405
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
393
406
  }
394
407
  return binding
395
408
  } catch (e) {
@@ -406,8 +419,8 @@ function requireNative() {
406
419
  try {
407
420
  const binding = require('@theagenticguy/microvms-linux-riscv64-musl')
408
421
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-riscv64-musl/package.json').version
409
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
410
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
422
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
423
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
411
424
  }
412
425
  return binding
413
426
  } catch (e) {
@@ -422,8 +435,8 @@ function requireNative() {
422
435
  try {
423
436
  const binding = require('@theagenticguy/microvms-linux-riscv64-gnu')
424
437
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-riscv64-gnu/package.json').version
425
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
426
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
438
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
439
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
427
440
  }
428
441
  return binding
429
442
  } catch (e) {
@@ -439,8 +452,8 @@ function requireNative() {
439
452
  try {
440
453
  const binding = require('@theagenticguy/microvms-linux-ppc64-gnu')
441
454
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-ppc64-gnu/package.json').version
442
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
443
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
455
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
456
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
444
457
  }
445
458
  return binding
446
459
  } catch (e) {
@@ -455,8 +468,8 @@ function requireNative() {
455
468
  try {
456
469
  const binding = require('@theagenticguy/microvms-linux-s390x-gnu')
457
470
  const bindingPackageVersion = require('@theagenticguy/microvms-linux-s390x-gnu/package.json').version
458
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
459
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
471
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
472
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
460
473
  }
461
474
  return binding
462
475
  } catch (e) {
@@ -475,8 +488,8 @@ function requireNative() {
475
488
  try {
476
489
  const binding = require('@theagenticguy/microvms-openharmony-arm64')
477
490
  const bindingPackageVersion = require('@theagenticguy/microvms-openharmony-arm64/package.json').version
478
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
479
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
491
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
492
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
480
493
  }
481
494
  return binding
482
495
  } catch (e) {
@@ -491,8 +504,8 @@ function requireNative() {
491
504
  try {
492
505
  const binding = require('@theagenticguy/microvms-openharmony-x64')
493
506
  const bindingPackageVersion = require('@theagenticguy/microvms-openharmony-x64/package.json').version
494
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
495
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
507
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
508
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
496
509
  }
497
510
  return binding
498
511
  } catch (e) {
@@ -507,8 +520,8 @@ function requireNative() {
507
520
  try {
508
521
  const binding = require('@theagenticguy/microvms-openharmony-arm')
509
522
  const bindingPackageVersion = require('@theagenticguy/microvms-openharmony-arm/package.json').version
510
- if (bindingPackageVersion !== '0.7.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
511
- throw new Error(`Native binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
523
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
524
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
512
525
  }
513
526
  return binding
514
527
  } catch (e) {
@@ -627,6 +640,7 @@ if (!nativeBinding || forceWasi) {
627
640
  if (!candidateFailed) {
628
641
  wasiBinding = require('./microvms.wasi.cjs')
629
642
  nativeBinding = wasiBinding
643
+ __napiLoadedBindingTarget = 'wasm32-wasi'
630
644
  wasiBindingLoaded = true
631
645
  }
632
646
  } catch (err) {
@@ -647,12 +661,13 @@ if (!nativeBinding || forceWasi) {
647
661
  if (!candidateFailed) {
648
662
  if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
649
663
  const bindingPackageVersion = require('@theagenticguy/microvms-wasm32-wasi/package.json').version
650
- if (bindingPackageVersion !== '0.7.0') {
651
- throw new Error(`WASI binding package version mismatch, expected 0.7.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
664
+ if (bindingPackageVersion !== '0.9.0') {
665
+ throw new Error(`WASI binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
652
666
  }
653
667
  }
654
668
  wasiBinding = require('@theagenticguy/microvms-wasm32-wasi')
655
669
  nativeBinding = wasiBinding
670
+ __napiLoadedBindingTarget = 'wasm32-wasi'
656
671
  wasiBindingLoaded = true
657
672
  }
658
673
  } catch (err) {
@@ -698,18 +713,86 @@ if (!nativeBinding) {
698
713
  throw new Error(`Failed to load native binding`)
699
714
  }
700
715
 
716
+ function __napiStampBindingTarget(exportsObject, target) {
717
+ if (
718
+ Object.prototype.hasOwnProperty.call(exportsObject, '__napiBindingTarget')
719
+ ) {
720
+ if (exportsObject.__napiBindingTarget === target) {
721
+ // Already ours: the root entry aliases the object it loaded, so a WASI
722
+ // fallback candidate — or a `NAPI_RS_NATIVE_LIBRARY_PATH` override that
723
+ // is a generated loader — arrives already stamped with this same value.
724
+ return target
725
+ }
726
+ const error = new Error(
727
+ '`__napiBindingTarget` is reserved by the generated binding loader, but the loaded binding already exports it. Rename the export, e.g. #[napi(js_name = "...")].',
728
+ )
729
+ error.code = 'ERR_NAPI_BINDING_TARGET_CONFLICT'
730
+ throw error
731
+ }
732
+ if (!Object.isExtensible(exportsObject)) {
733
+ // A `#[napi(module_exports)]` hook may seal or freeze this object
734
+ // (`Object::seal` / `Object::freeze`). Reporting the artifact is metadata,
735
+ // never a reason to fail an otherwise successful load, so the stamp is
736
+ // skipped. What a consumer still sees then follows the entry point: the
737
+ // browser and deferred loaders declare `__napiBindingTarget` at module
738
+ // level and go on reporting it, while the CommonJS entries hand back this
739
+ // very object as `module.exports`, so there the value is absent.
740
+ return target
741
+ }
742
+ try {
743
+ // [[Define]], not [[Set]]: an ordinary assignment walks the prototype
744
+ // chain, so an inherited accessor could swallow the value or throw and
745
+ // fail an otherwise successful load. The descriptor is what a successful
746
+ // assignment would have produced.
747
+ Object.defineProperty(exportsObject, '__napiBindingTarget', {
748
+ configurable: true,
749
+ enumerable: true,
750
+ value: target,
751
+ writable: true,
752
+ })
753
+ } catch {
754
+ // Same rule as the non-extensible skip above: reporting the artifact is
755
+ // metadata, never a reason to fail an otherwise successful load. An exotic
756
+ // object (a Proxy whose defineProperty trap refuses) is skipped, not
757
+ // thrown over.
758
+ }
759
+ // The CommonJS loaders assign this return value so `cjs-module-lexer` — and
760
+ // therefore Node's CJS -> ESM named export detection — can see
761
+ // `__napiBindingTarget` statically.
762
+ return target
763
+ }
764
+ // Stamp before the alias, not after. The guard only reads `nativeBinding`
765
+ // (`hasOwnProperty` plus a comparison), which is safe against any addon
766
+ // accessor; an assignment is not, because a `#[napi(module_exports)]` hook can
767
+ // expose a getter reporting this very value and a setter that throws. So the
768
+ // assignment lands on the loader's own `module.exports`, still the original
769
+ // object here, and the alias below replaces it.
770
+ //
771
+ // The assignment is what keeps the marker a statically visible CommonJS export:
772
+ // `cjs-module-lexer` is Node's CJS -> ESM named export detection, it cannot see
773
+ // a bare call, and the later `module.exports = nativeBinding` does not undo the
774
+ // detection. The assignment itself always succeeds — its target is this
775
+ // loader's own, still extensible `module.exports` — and the alias below then
776
+ // discards the value it wrote. What a consumer reads is whatever the guard put
777
+ // on `nativeBinding`, so on a frozen binding, where the guard skips, the
778
+ // linked import resolves to `undefined`.
779
+ module.exports.__napiBindingTarget = __napiStampBindingTarget(nativeBinding, __napiLoadedBindingTarget)
701
780
  module.exports = nativeBinding
702
781
  module.exports.AgentVm = nativeBinding.AgentVm
703
782
  module.exports.Amount = nativeBinding.Amount
704
783
  module.exports.BearerToken = nativeBinding.BearerToken
705
784
  module.exports.BuildHookTimeout = nativeBinding.BuildHookTimeout
785
+ module.exports.ControlPlane = nativeBinding.ControlPlane
706
786
  module.exports.CostReport = nativeBinding.CostReport
707
787
  module.exports.Duration = nativeBinding.Duration
708
788
  module.exports.EstimatedUsd = nativeBinding.EstimatedUsd
709
789
  module.exports.ExecHandle = nativeBinding.ExecHandle
710
790
  module.exports.ExecProcess = nativeBinding.ExecProcess
711
791
  module.exports.ExecStream = nativeBinding.ExecStream
792
+ module.exports.KeepAwake = nativeBinding.KeepAwake
712
793
  module.exports.LineItem = nativeBinding.LineItem
794
+ module.exports.NameRecord = nativeBinding.NameRecord
795
+ module.exports.NameRegistry = nativeBinding.NameRegistry
713
796
  module.exports.RateTable = nativeBinding.RateTable
714
797
  module.exports.Region = nativeBinding.Region
715
798
  module.exports.ResidencyComparison = nativeBinding.ResidencyComparison
@@ -731,6 +814,7 @@ module.exports.GapPolicy = nativeBinding.GapPolicy
731
814
  module.exports.installAgentAccess = nativeBinding.installAgentAccess
732
815
  module.exports.installedAgents = nativeBinding.installedAgents
733
816
  module.exports.mintBedrockToken = nativeBinding.mintBedrockToken
817
+ module.exports.mintBedrockTokenWithCredentials = nativeBinding.mintBedrockTokenWithCredentials
734
818
  module.exports.promptAgent = nativeBinding.promptAgent
735
819
  module.exports.runReport = nativeBinding.runReport
736
820
  module.exports.sessionConstants = nativeBinding.sessionConstants
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@theagenticguy/microvms",
3
- "version": "0.7.0",
4
- "description": "Node bindings over microvms-core: the MicroVMs client with every trap closure",
3
+ "version": "0.9.0",
4
+ "description": "Node.js and TypeScript client for AWS Lambda MicroVMs",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Laith Al-Saadoon",
7
7
  "homepage": "https://laithalsaadoon.github.io/microvms-agentd/",
@@ -45,7 +45,7 @@
45
45
  "build": "napi build --manifest-path ../Cargo.toml --package microvms-js --platform --output-dir .",
46
46
  "test": "node --test __test__/*.mjs",
47
47
  "test:smoke": "node --test __test__/smoke.mjs",
48
- "test:unit": "node --test __test__/cost.mjs __test__/errors.mjs __test__/exec.mjs __test__/process.mjs __test__/session.mjs"
48
+ "test:unit": "node --test __test__/cost.mjs __test__/errors.mjs __test__/exec.mjs __test__/process.mjs __test__/session.mjs __test__/numbers.mjs"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@napi-rs/cli": "^3.8.2"