@rivet-dev/agentos-runtime-core 0.0.0-glibc.4af31c1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +7 -0
  2. package/commands/[ +0 -0
  3. package/commands/_stubs +0 -0
  4. package/commands/arch +0 -0
  5. package/commands/awk +0 -0
  6. package/commands/b2sum +0 -0
  7. package/commands/base32 +0 -0
  8. package/commands/base64 +0 -0
  9. package/commands/basename +0 -0
  10. package/commands/basenc +0 -0
  11. package/commands/bash +0 -0
  12. package/commands/cat +0 -0
  13. package/commands/chcon +0 -0
  14. package/commands/chgrp +0 -0
  15. package/commands/chmod +0 -0
  16. package/commands/chown +0 -0
  17. package/commands/chroot +0 -0
  18. package/commands/cksum +0 -0
  19. package/commands/codex +0 -0
  20. package/commands/codex-exec +0 -0
  21. package/commands/column +0 -0
  22. package/commands/comm +0 -0
  23. package/commands/cp +0 -0
  24. package/commands/curl +0 -0
  25. package/commands/cut +0 -0
  26. package/commands/date +0 -0
  27. package/commands/dd +0 -0
  28. package/commands/df +0 -0
  29. package/commands/diff +0 -0
  30. package/commands/dir +0 -0
  31. package/commands/dircolors +0 -0
  32. package/commands/dirname +0 -0
  33. package/commands/du +0 -0
  34. package/commands/echo +0 -0
  35. package/commands/egrep +0 -0
  36. package/commands/env +0 -0
  37. package/commands/envsubst +0 -0
  38. package/commands/expand +0 -0
  39. package/commands/expr +0 -0
  40. package/commands/factor +0 -0
  41. package/commands/false +0 -0
  42. package/commands/fd +0 -0
  43. package/commands/fgrep +0 -0
  44. package/commands/file +0 -0
  45. package/commands/find +0 -0
  46. package/commands/fmt +0 -0
  47. package/commands/fold +0 -0
  48. package/commands/git +0 -0
  49. package/commands/git-remote-http +0 -0
  50. package/commands/git-remote-https +0 -0
  51. package/commands/grep +0 -0
  52. package/commands/groups +0 -0
  53. package/commands/gunzip +0 -0
  54. package/commands/gzip +0 -0
  55. package/commands/head +0 -0
  56. package/commands/hostid +0 -0
  57. package/commands/hostname +0 -0
  58. package/commands/http-test +0 -0
  59. package/commands/http_get +0 -0
  60. package/commands/id +0 -0
  61. package/commands/install +0 -0
  62. package/commands/join +0 -0
  63. package/commands/jq +0 -0
  64. package/commands/kill +0 -0
  65. package/commands/link +0 -0
  66. package/commands/ln +0 -0
  67. package/commands/logname +0 -0
  68. package/commands/ls +0 -0
  69. package/commands/md5sum +0 -0
  70. package/commands/mkdir +0 -0
  71. package/commands/mkfifo +0 -0
  72. package/commands/mknod +0 -0
  73. package/commands/mktemp +0 -0
  74. package/commands/more +0 -0
  75. package/commands/mv +0 -0
  76. package/commands/nice +0 -0
  77. package/commands/nl +0 -0
  78. package/commands/nohup +0 -0
  79. package/commands/nproc +0 -0
  80. package/commands/numfmt +0 -0
  81. package/commands/od +0 -0
  82. package/commands/paste +0 -0
  83. package/commands/pathchk +0 -0
  84. package/commands/pinky +0 -0
  85. package/commands/printenv +0 -0
  86. package/commands/printf +0 -0
  87. package/commands/ptx +0 -0
  88. package/commands/pwd +0 -0
  89. package/commands/readlink +0 -0
  90. package/commands/realpath +0 -0
  91. package/commands/rev +0 -0
  92. package/commands/rg +0 -0
  93. package/commands/rm +0 -0
  94. package/commands/rmdir +0 -0
  95. package/commands/runcon +0 -0
  96. package/commands/sed +0 -0
  97. package/commands/seq +0 -0
  98. package/commands/sh +0 -0
  99. package/commands/sha1sum +0 -0
  100. package/commands/sha224sum +0 -0
  101. package/commands/sha256sum +0 -0
  102. package/commands/sha384sum +0 -0
  103. package/commands/sha512sum +0 -0
  104. package/commands/shred +0 -0
  105. package/commands/shuf +0 -0
  106. package/commands/sleep +0 -0
  107. package/commands/sort +0 -0
  108. package/commands/spawn-test-host +0 -0
  109. package/commands/split +0 -0
  110. package/commands/sqlite3 +0 -0
  111. package/commands/stat +0 -0
  112. package/commands/stdbuf +0 -0
  113. package/commands/strings +0 -0
  114. package/commands/stty +0 -0
  115. package/commands/sum +0 -0
  116. package/commands/sync +0 -0
  117. package/commands/tac +0 -0
  118. package/commands/tail +0 -0
  119. package/commands/tar +0 -0
  120. package/commands/tee +0 -0
  121. package/commands/test +0 -0
  122. package/commands/timeout +0 -0
  123. package/commands/touch +0 -0
  124. package/commands/tr +0 -0
  125. package/commands/tree +0 -0
  126. package/commands/true +0 -0
  127. package/commands/truncate +0 -0
  128. package/commands/tsort +0 -0
  129. package/commands/tty +0 -0
  130. package/commands/uname +0 -0
  131. package/commands/unexpand +0 -0
  132. package/commands/uniq +0 -0
  133. package/commands/unlink +0 -0
  134. package/commands/unzip +0 -0
  135. package/commands/uptime +0 -0
  136. package/commands/users +0 -0
  137. package/commands/vdir +0 -0
  138. package/commands/wc +0 -0
  139. package/commands/which +0 -0
  140. package/commands/who +0 -0
  141. package/commands/whoami +0 -0
  142. package/commands/xargs +0 -0
  143. package/commands/xu +0 -0
  144. package/commands/yes +0 -0
  145. package/commands/yq +0 -0
  146. package/commands/zcat +0 -0
  147. package/commands/zip +0 -0
  148. package/dist/binary.d.ts +4 -0
  149. package/dist/binary.js +25 -0
  150. package/dist/bytes.d.ts +2 -0
  151. package/dist/bytes.js +6 -0
  152. package/dist/callbacks.d.ts +41 -0
  153. package/dist/callbacks.js +94 -0
  154. package/dist/cargo.d.ts +2 -0
  155. package/dist/cargo.js +142 -0
  156. package/dist/correlation.d.ts +10 -0
  157. package/dist/correlation.js +49 -0
  158. package/dist/descriptors.d.ts +84 -0
  159. package/dist/descriptors.js +60 -0
  160. package/dist/event-buffer.d.ts +90 -0
  161. package/dist/event-buffer.js +313 -0
  162. package/dist/ext.d.ts +7 -0
  163. package/dist/ext.js +13 -0
  164. package/dist/filesystem.d.ts +41 -0
  165. package/dist/filesystem.js +70 -0
  166. package/dist/frame-payload-codec.d.ts +8 -0
  167. package/dist/frame-payload-codec.js +14 -0
  168. package/dist/frame-rpc.d.ts +40 -0
  169. package/dist/frame-rpc.js +81 -0
  170. package/dist/frame-stream.d.ts +34 -0
  171. package/dist/frame-stream.js +109 -0
  172. package/dist/framing.d.ts +8 -0
  173. package/dist/framing.js +23 -0
  174. package/dist/generated/AcpLimitsConfig.d.ts +4 -0
  175. package/dist/generated/AcpLimitsConfig.js +2 -0
  176. package/dist/generated/CreateVmConfig.d.ts +26 -0
  177. package/dist/generated/CreateVmConfig.js +1 -0
  178. package/dist/generated/FsPermissionRule.d.ts +6 -0
  179. package/dist/generated/FsPermissionRule.js +1 -0
  180. package/dist/generated/FsPermissionRuleSet.d.ts +6 -0
  181. package/dist/generated/FsPermissionRuleSet.js +1 -0
  182. package/dist/generated/FsPermissionScope.d.ts +3 -0
  183. package/dist/generated/FsPermissionScope.js +1 -0
  184. package/dist/generated/HttpLimitsConfig.d.ts +3 -0
  185. package/dist/generated/HttpLimitsConfig.js +2 -0
  186. package/dist/generated/JsModuleResolution.d.ts +1 -0
  187. package/dist/generated/JsModuleResolution.js +2 -0
  188. package/dist/generated/JsRuntimeConfig.d.ts +31 -0
  189. package/dist/generated/JsRuntimeConfig.js +1 -0
  190. package/dist/generated/JsRuntimeLimitsConfig.d.ts +11 -0
  191. package/dist/generated/JsRuntimeLimitsConfig.js +2 -0
  192. package/dist/generated/JsRuntimePlatform.d.ts +1 -0
  193. package/dist/generated/JsRuntimePlatform.js +2 -0
  194. package/dist/generated/MountPluginDescriptor.d.ts +4 -0
  195. package/dist/generated/MountPluginDescriptor.js +2 -0
  196. package/dist/generated/NativeRootFilesystemConfig.d.ts +5 -0
  197. package/dist/generated/NativeRootFilesystemConfig.js +1 -0
  198. package/dist/generated/PatternPermissionRule.d.ts +6 -0
  199. package/dist/generated/PatternPermissionRule.js +1 -0
  200. package/dist/generated/PatternPermissionRuleSet.d.ts +6 -0
  201. package/dist/generated/PatternPermissionRuleSet.js +1 -0
  202. package/dist/generated/PatternPermissionScope.d.ts +3 -0
  203. package/dist/generated/PatternPermissionScope.js +1 -0
  204. package/dist/generated/PermissionMode.d.ts +1 -0
  205. package/dist/generated/PermissionMode.js +2 -0
  206. package/dist/generated/PermissionsPolicy.d.ts +10 -0
  207. package/dist/generated/PermissionsPolicy.js +1 -0
  208. package/dist/generated/PluginLimitsConfig.d.ts +4 -0
  209. package/dist/generated/PluginLimitsConfig.js +2 -0
  210. package/dist/generated/PythonLimitsConfig.d.ts +6 -0
  211. package/dist/generated/PythonLimitsConfig.js +2 -0
  212. package/dist/generated/ResourceLimitsConfig.d.ts +24 -0
  213. package/dist/generated/ResourceLimitsConfig.js +2 -0
  214. package/dist/generated/RootFilesystemConfig.d.ts +9 -0
  215. package/dist/generated/RootFilesystemConfig.js +1 -0
  216. package/dist/generated/RootFilesystemEntry.d.ts +13 -0
  217. package/dist/generated/RootFilesystemEntry.js +1 -0
  218. package/dist/generated/RootFilesystemEntryEncoding.d.ts +1 -0
  219. package/dist/generated/RootFilesystemEntryEncoding.js +2 -0
  220. package/dist/generated/RootFilesystemEntryKind.d.ts +1 -0
  221. package/dist/generated/RootFilesystemEntryKind.js +2 -0
  222. package/dist/generated/RootFilesystemLowerDescriptor.d.ts +7 -0
  223. package/dist/generated/RootFilesystemLowerDescriptor.js +1 -0
  224. package/dist/generated/RootFilesystemMode.d.ts +1 -0
  225. package/dist/generated/RootFilesystemMode.js +2 -0
  226. package/dist/generated/ToolLimitsConfig.d.ts +10 -0
  227. package/dist/generated/ToolLimitsConfig.js +2 -0
  228. package/dist/generated/VmDnsConfig.d.ts +6 -0
  229. package/dist/generated/VmDnsConfig.js +2 -0
  230. package/dist/generated/VmLimitsConfig.d.ts +18 -0
  231. package/dist/generated/VmLimitsConfig.js +1 -0
  232. package/dist/generated/VmListenPolicyConfig.d.ts +5 -0
  233. package/dist/generated/VmListenPolicyConfig.js +2 -0
  234. package/dist/generated/WasmLimitsConfig.d.ts +7 -0
  235. package/dist/generated/WasmLimitsConfig.js +2 -0
  236. package/dist/generated-protocol.d.ts +1196 -0
  237. package/dist/generated-protocol.js +3286 -0
  238. package/dist/index.d.ts +29 -0
  239. package/dist/index.js +28 -0
  240. package/dist/json.d.ts +2 -0
  241. package/dist/json.js +20 -0
  242. package/dist/kernel-proxy.d.ts +166 -0
  243. package/dist/kernel-proxy.js +1777 -0
  244. package/dist/native-client.d.ts +42 -0
  245. package/dist/native-client.js +126 -0
  246. package/dist/node-runtime-options-schema.d.ts +117 -0
  247. package/dist/node-runtime-options-schema.js +121 -0
  248. package/dist/node-runtime.d.ts +593 -0
  249. package/dist/node-runtime.js +914 -0
  250. package/dist/numbers.d.ts +1 -0
  251. package/dist/numbers.js +8 -0
  252. package/dist/ownership.d.ts +18 -0
  253. package/dist/ownership.js +77 -0
  254. package/dist/permissions.d.ts +29 -0
  255. package/dist/permissions.js +68 -0
  256. package/dist/process.d.ts +22 -0
  257. package/dist/process.js +97 -0
  258. package/dist/protocol-client.d.ts +48 -0
  259. package/dist/protocol-client.js +181 -0
  260. package/dist/protocol-frames.d.ts +68 -0
  261. package/dist/protocol-frames.js +139 -0
  262. package/dist/protocol-maps.d.ts +31 -0
  263. package/dist/protocol-maps.js +273 -0
  264. package/dist/protocol-schema.d.ts +10 -0
  265. package/dist/protocol-schema.js +11 -0
  266. package/dist/request-payloads.d.ts +171 -0
  267. package/dist/request-payloads.js +269 -0
  268. package/dist/response-payloads.d.ts +186 -0
  269. package/dist/response-payloads.js +250 -0
  270. package/dist/sidecar-client.d.ts +17 -0
  271. package/dist/sidecar-client.js +1 -0
  272. package/dist/sidecar-errors.d.ts +15 -0
  273. package/dist/sidecar-errors.js +30 -0
  274. package/dist/sidecar-process.d.ts +356 -0
  275. package/dist/sidecar-process.js +1008 -0
  276. package/dist/state.d.ts +40 -0
  277. package/dist/state.js +44 -0
  278. package/dist/test-runtime.d.ts +563 -0
  279. package/dist/test-runtime.js +2171 -0
  280. package/dist/vm-config.d.ts +31 -0
  281. package/dist/vm-config.js +1 -0
  282. package/package.json +204 -0
@@ -0,0 +1,593 @@
1
+ /**
2
+ * NodeRuntime — ergonomic façade for running guest JavaScript end-to-end.
3
+ *
4
+ * Boots a fully virtualized VM (via the native sidecar) and runs guest Node
5
+ * programs with minimal boilerplate. All of the sidecar spawn, session
6
+ * handshake, VM creation, root filesystem bootstrap, runtime-driver mounting,
7
+ * and lifecycle waiting are hidden behind `NodeRuntime.create()`.
8
+ *
9
+ * ```ts
10
+ * const rt = await NodeRuntime.create();
11
+ * const { stdout, exitCode } = await rt.exec("console.log('hi', 1 + 1)");
12
+ * await rt.dispose();
13
+ * ```
14
+ *
15
+ * Guest code is written to an ESM module inside the VM and executed as
16
+ * `node <file>` through the kernel, so all execution stays inside the kernel
17
+ * isolation boundary — no host escapes, no real Node.js builtins for guest
18
+ * work.
19
+ */
20
+ import type { BindingDefinition, KernelBootTiming, Permissions, VirtualDirEntry } from "./test-runtime.js";
21
+ import type { JsRuntimeConfig } from "./generated/JsRuntimeConfig.js";
22
+ import type { SidecarProcess } from "./sidecar-process.js";
23
+ export type { BindingDefinition, HostToolExample, VirtualDirEntry, } from "./test-runtime.js";
24
+ export { resolveNodeRuntimeSidecarBinary } from "./test-runtime.js";
25
+ export type NodeRuntimeBootTimingPhase = KernelBootTiming["phase"] | "runtime_mount_wasm" | "runtime_mount_node" | "bindings";
26
+ export interface NodeRuntimeBootTiming {
27
+ phase: NodeRuntimeBootTimingPhase;
28
+ durationMs: number;
29
+ }
30
+ /**
31
+ * Resolve the directory holding the WASM command binaries (the source of the
32
+ * guest `sh` the kernel needs to spawn any process). Precedence:
33
+ *
34
+ * 1. explicit `commandsDir` option,
35
+ * 2. `AGENTOS_WASM_COMMANDS_DIR` env var,
36
+ * 3. the in-repo build output (developer checkout), when present,
37
+ * 4. the commands vendored into the installed package (published installs).
38
+ *
39
+ * The in-repo path wins over the bundled copy so local development picks up
40
+ * freshly built commands without re-vendoring. A fresh `npm install` has no
41
+ * in-repo path, so it falls through to the bundled copy.
42
+ */
43
+ export declare function resolveNodeRuntimeCommandsDir(explicit?: string): string;
44
+ /**
45
+ * Options for {@link NodeRuntime.create}.
46
+ *
47
+ * Keep this public interface in sync with
48
+ * `packages/core/src/node-runtime-options-schema.ts::nodeRuntimeCreateOptionsSchema`.
49
+ * Options that translate into sidecar VM JSON must also stay aligned with
50
+ * `crates/vm-config/src/lib.rs::CreateVmConfig`.
51
+ */
52
+ export interface NodeRuntimeCreateOptions {
53
+ /** Environment variables visible to guest processes. */
54
+ env?: Record<string, string>;
55
+ /** Initial working directory for guest processes. Defaults to `/workspace`. */
56
+ cwd?: string;
57
+ /**
58
+ * Permission policy for the VM. Merged over a secure default that **denies
59
+ * network access** (guest code cannot reach the network until you opt in);
60
+ * the virtualized filesystem and processes stay enabled so programs run.
61
+ * Because it merges, a partial policy works: `{ network: "allow" }` grants
62
+ * the network while keeping the execution essentials. Pass a fuller policy
63
+ * (rule sets) to further sandbox individual scopes.
64
+ */
65
+ permissions?: Permissions;
66
+ /**
67
+ * Override the directory containing the WASM command binaries (the source of
68
+ * the guest `sh`). When unset, resolution falls back through the
69
+ * `AGENTOS_WASM_COMMANDS_DIR` environment variable, the in-repo build
70
+ * output (developer checkouts), then the commands vendored into the installed
71
+ * `@rivet-dev/agentos-runtime-core` package (published installs).
72
+ */
73
+ commandsDir?: string;
74
+ /**
75
+ * Additional directories of wasm32-wasip1 commands to register in the VM.
76
+ * Intended for low-level tooling and benchmark harnesses; normal callers use
77
+ * the bundled shell/coreutils command directory resolved by `commandsDir`.
78
+ */
79
+ wasmCommandDirs?: string[];
80
+ /**
81
+ * Existing native sidecar process to use for this runtime. Omit this to use
82
+ * the default shared sidecar behavior. When provided, the runtime owns only
83
+ * its VM and leaves sidecar process disposal to the caller.
84
+ */
85
+ sidecar?: SidecarProcess;
86
+ /** Receives coarse boot phase timings for benchmarks and diagnostics. */
87
+ onBootTiming?: (timing: NodeRuntimeBootTiming) => void;
88
+ /**
89
+ * Files to seed into the VM's virtual filesystem before the guest runs,
90
+ * keyed by absolute guest path. Parent directories are created as needed.
91
+ * Use this to project host assets, npm packages, or fixtures into the
92
+ * sandbox so guest code can `import`/`require`/read them. The bytes are
93
+ * copied into the VM's in-memory filesystem; the host filesystem is never
94
+ * exposed to the guest.
95
+ *
96
+ * ```ts
97
+ * const rt = await NodeRuntime.create({
98
+ * files: { "/root/data.json": '{"ok":true}' },
99
+ * });
100
+ * ```
101
+ */
102
+ files?: Record<string, string | Uint8Array>;
103
+ /**
104
+ * Host directories to project into the VM's virtual filesystem, Docker-style.
105
+ * Each mount makes a host directory readable at a guest path. Files are read
106
+ * lazily from the host as the guest accesses them, so large trees (for
107
+ * example a `node_modules` package such as the TypeScript compiler) are
108
+ * projected without copying their bytes up front. The guest sees only the
109
+ * mounted subtree, never the wider host filesystem.
110
+ *
111
+ * ```ts
112
+ * const rt = await NodeRuntime.create({
113
+ * mounts: [
114
+ * {
115
+ * guestPath: "/root/node_modules/typescript",
116
+ * hostPath: "/abs/path/to/node_modules/typescript",
117
+ * readOnly: true,
118
+ * },
119
+ * ],
120
+ * });
121
+ * ```
122
+ */
123
+ mounts?: HostDirectoryMount[];
124
+ /**
125
+ * Mount a host `node_modules` directory into the VM in one call so guest
126
+ * `import`/`require` resolve real, host-installed npm packages.
127
+ *
128
+ * Pass the absolute host path to a `node_modules` directory (or an object
129
+ * with that path and an explicit guest location). The whole directory is
130
+ * projected lazily, Docker-style, at a guest `node_modules` on the resolution
131
+ * path, so any package inside it resolves the way Node would over a real
132
+ * filesystem (ancestor `node_modules` walk, `exports`/conditions, symlinks).
133
+ * This is the ergonomic alternative to wiring up individual `mounts` entries
134
+ * per package.
135
+ *
136
+ * By default the directory is mounted at `/tmp/node_modules`, which is where
137
+ * the resolution walk for a program run by {@link NodeRuntime.exec} /
138
+ * {@link NodeRuntime.run} begins (each program is written under `/tmp`). Pass
139
+ * the object form with `guestPath` to mount it elsewhere on a different
140
+ * module's resolution path.
141
+ *
142
+ * ```ts
143
+ * const rt = await NodeRuntime.create({
144
+ * nodeModules: "/abs/path/to/project/node_modules",
145
+ * });
146
+ * await rt.exec(`
147
+ * import isNumber from "is-number";
148
+ * console.log(isNumber(42));
149
+ * `);
150
+ * ```
151
+ *
152
+ * The host filesystem is never exposed beyond the mounted `node_modules`
153
+ * subtree. The mount is read-only.
154
+ */
155
+ nodeModules?: string | NodeModulesMount;
156
+ /**
157
+ * Host-side bindings the guest can invoke as shell commands. Each entry is
158
+ * registered as a named guest command; when the guest runs it, the
159
+ * invocation round-trips back to the host and runs the binding's `handler`,
160
+ * whose return value is delivered back to the guest. This is how you give
161
+ * sandboxed guest code controlled, named host capabilities (the kind an AI
162
+ * agent calls as tools) without granting it the underlying access directly.
163
+ *
164
+ * The guest invokes a binding by name with JSON input:
165
+ *
166
+ * ```ts
167
+ * const rt = await NodeRuntime.create({
168
+ * bindings: {
169
+ * add: {
170
+ * description: "Add two numbers",
171
+ * inputSchema: {
172
+ * type: "object",
173
+ * properties: { a: { type: "number" }, b: { type: "number" } },
174
+ * required: ["a", "b"],
175
+ * },
176
+ * handler: ({ a, b }: { a: number; b: number }) => ({ sum: a + b }),
177
+ * },
178
+ * },
179
+ * });
180
+ * await rt.exec(`
181
+ * import { execFileSync } from "node:child_process";
182
+ * const out = execFileSync("add", ["add", "--json", JSON.stringify({ a: 2, b: 3 })]);
183
+ * console.log(out.toString());
184
+ * `);
185
+ * ```
186
+ *
187
+ * When `bindings` is provided and no `binding` permission scope is set, the
188
+ * `binding` scope is granted so the registered bindings are invocable; pass
189
+ * your own `permissions.binding` policy to gate individual bindings.
190
+ */
191
+ bindings?: Record<string, BindingDefinition>;
192
+ /**
193
+ * Guest-bound ports that may accept non-loopback connections. By default a
194
+ * guest server is reachable only over loopback inside the VM; listing a port
195
+ * here lifts that restriction for that port, letting connections from outside
196
+ * the loopback interface reach it. Use this for guests that run servers which
197
+ * must accept external connections (for example a dev server you expose
198
+ * beyond loopback).
199
+ *
200
+ * ```ts
201
+ * const rt = await NodeRuntime.create({
202
+ * permissions: { network: "allow" },
203
+ * loopbackExemptPorts: [3000],
204
+ * });
205
+ * ```
206
+ */
207
+ loopbackExemptPorts?: number[];
208
+ /**
209
+ * Low-level guest JavaScript runtime configuration. Most callers should leave
210
+ * this unset. Benchmarks may opt in to `highResolutionTime`, which disables
211
+ * the default 1ms timer quantization and should not be enabled for untrusted
212
+ * workloads.
213
+ */
214
+ jsRuntime?: Partial<JsRuntimeConfig>;
215
+ }
216
+ /** A host directory projected into the VM's virtual filesystem. */
217
+ export interface HostDirectoryMount {
218
+ /** Absolute guest path the directory appears at inside the VM. */
219
+ guestPath: string;
220
+ /** Absolute host directory to project (read through the VFS, lazily). */
221
+ hostPath: string;
222
+ /** Mount read-only (the default). Pass `false` to allow guest writes. */
223
+ readOnly?: boolean;
224
+ }
225
+ /**
226
+ * Object form of the `nodeModules` create option: a host `node_modules`
227
+ * directory to project, optionally at an explicit guest path. The string form
228
+ * (`nodeModules: "/abs/node_modules"`) is shorthand for `{ hostPath }`.
229
+ */
230
+ export interface NodeModulesMount {
231
+ /** Absolute host `node_modules` directory to project (read lazily). */
232
+ hostPath: string;
233
+ /**
234
+ * Absolute guest path to mount it at. Defaults to `/tmp/node_modules`, where
235
+ * the resolution walk for {@link NodeRuntime.exec} / {@link NodeRuntime.run}
236
+ * programs begins. Override to put it on a different module's resolution path.
237
+ */
238
+ guestPath?: string;
239
+ }
240
+ /** Result of {@link NodeRuntime.exec}. */
241
+ export interface NodeRuntimeExecResult {
242
+ stdout: string;
243
+ stderr: string;
244
+ exitCode: number;
245
+ }
246
+ /** Options for a single {@link NodeRuntime.exec} call. */
247
+ export interface NodeRuntimeExecOptions {
248
+ /** Extra environment variables for this run, merged over the VM env. */
249
+ env?: Record<string, string>;
250
+ /** Working directory for this run. */
251
+ cwd?: string;
252
+ /** Data piped to the guest program's stdin. */
253
+ stdin?: string | Uint8Array;
254
+ /** Abort the run after this many milliseconds. */
255
+ timeout?: number;
256
+ /**
257
+ * Cancel the run when this signal aborts. On abort the guest process is
258
+ * killed inside the VM (the kernel delivers `SIGTERM`) and the call rejects
259
+ * with the signal's abort reason. Use this to cancel an in-flight run from
260
+ * the outside, for example to enforce your own deadline or stop work when a
261
+ * request is canceled.
262
+ *
263
+ * ```ts
264
+ * const controller = new AbortController();
265
+ * const pending = rt.exec("while (true) {}", { signal: controller.signal });
266
+ * controller.abort();
267
+ * await pending.catch((err) => console.log(err.name)); // "AbortError"
268
+ * ```
269
+ */
270
+ signal?: AbortSignal;
271
+ /**
272
+ * Called with each chunk the guest writes to stdout as it is produced,
273
+ * letting you observe output incrementally instead of waiting for the run to
274
+ * finish. Chunks arrive as raw bytes; decode with a `TextDecoder` for text.
275
+ * The complete output is still returned as `result.stdout` when the run ends.
276
+ */
277
+ onStdout?: (chunk: Uint8Array) => void;
278
+ /**
279
+ * Called with each chunk the guest writes to stderr as it is produced,
280
+ * letting you observe output incrementally instead of waiting for the run to
281
+ * finish. Chunks arrive as raw bytes; decode with a `TextDecoder` for text.
282
+ * The complete output is still returned as `result.stderr` when the run ends.
283
+ */
284
+ onStderr?: (chunk: Uint8Array) => void;
285
+ }
286
+ /** The HTTP request {@link NodeRuntime.fetch} drives into the VM. */
287
+ export interface NodeRuntimeFetchInput {
288
+ /** HTTP method. Defaults to `GET`. */
289
+ method?: string;
290
+ /** Request path (and query), e.g. `/api/users?limit=10`. */
291
+ path: string;
292
+ /** Request headers. */
293
+ headers?: Record<string, string>;
294
+ /** Request body. */
295
+ body?: string | Uint8Array;
296
+ }
297
+ /** The HTTP response {@link NodeRuntime.fetch} returns from the VM. */
298
+ export interface NodeRuntimeFetchResponse {
299
+ /** HTTP status code, e.g. `200`. */
300
+ status: number;
301
+ /** HTTP status text, e.g. `OK`. */
302
+ statusText: string;
303
+ /** Response headers, lower-cased by name. */
304
+ headers: Record<string, string>;
305
+ /** Response body decoded as UTF-8 text. */
306
+ body: string;
307
+ }
308
+ /**
309
+ * Options for {@link NodeRuntime.spawn}. Inherits the streaming `onStdout` /
310
+ * `onStderr` hooks from {@link NodeRuntimeExecOptions}.
311
+ */
312
+ export interface NodeRuntimeSpawnOptions extends NodeRuntimeExecOptions {
313
+ }
314
+ /**
315
+ * Describes the guest TCP listener to wait for with
316
+ * {@link NodeRuntime.waitForListener} or look up with
317
+ * {@link NodeRuntime.findListener}. A listener matches when a guest process is
318
+ * accepting connections on the given `port` (and `host`/`path` when supplied).
319
+ */
320
+ export interface NodeRuntimeListenerQuery {
321
+ /** TCP port the guest listener is bound to, e.g. `3000`. */
322
+ port: number;
323
+ /** Bind host to match, e.g. `127.0.0.1`. Omit to match any host. */
324
+ host?: string;
325
+ /** Unix socket path to match, for path-bound listeners. */
326
+ path?: string;
327
+ }
328
+ /**
329
+ * A matched guest listener returned by {@link NodeRuntime.waitForListener} and
330
+ * {@link NodeRuntime.findListener}. `processId` identifies the guest process
331
+ * that owns the listening socket; the `host`/`port`/`path` it is bound to are
332
+ * reported when known.
333
+ */
334
+ export interface NodeRuntimeListener {
335
+ /** The guest process id that owns the listening socket. */
336
+ processId: string;
337
+ /** The host the listener is bound to, when reported. */
338
+ host?: string;
339
+ /** The port the listener is bound to, when reported. */
340
+ port?: number;
341
+ /** The unix socket path the listener is bound to, when reported. */
342
+ path?: string;
343
+ }
344
+ /** Options for {@link NodeRuntime.waitForListener}. */
345
+ export interface NodeRuntimeWaitForListenerOptions {
346
+ /**
347
+ * Give up after this many milliseconds and reject. Defaults to 10000. The
348
+ * wait also rejects if the bound `signal` aborts first.
349
+ */
350
+ timeoutMs?: number;
351
+ /** Abort the wait early; the returned promise rejects when it fires. */
352
+ signal?: AbortSignal;
353
+ /**
354
+ * How long to wait between listener lookups while polling, in milliseconds.
355
+ * Defaults to 50.
356
+ */
357
+ pollIntervalMs?: number;
358
+ }
359
+ /**
360
+ * A live handle to a guest process started with {@link NodeRuntime.spawn}.
361
+ *
362
+ * Unlike {@link NodeRuntime.exec}, which runs a program to completion and
363
+ * returns its captured output, a handle is returned immediately while the
364
+ * process keeps running. Use it to stream stdout/stderr, feed stdin, signal or
365
+ * kill the process, and await its exit. This is the building block for
366
+ * long-running guests such as dev servers: start one here, then drive requests
367
+ * into it with {@link NodeRuntime.fetch}.
368
+ */
369
+ export interface NodeRuntimeProcess {
370
+ /** The guest process id. */
371
+ readonly pid: number;
372
+ /** Write data to the guest process's stdin. */
373
+ writeStdin(data: string | Uint8Array): void;
374
+ /** Close the guest process's stdin, signalling end-of-input. */
375
+ closeStdin(): void;
376
+ /**
377
+ * Send a signal to the guest process. Defaults to `SIGTERM`. Accepts a
378
+ * signal name (e.g. `"SIGKILL"`) or a raw signal number.
379
+ */
380
+ kill(signal?: NodeJS.Signals | number): void;
381
+ /** Resolve with the guest process's exit code once it terminates. */
382
+ wait(): Promise<number>;
383
+ /** The exit code once the process has exited, or `null` while it runs. */
384
+ readonly exitCode: number | null;
385
+ }
386
+ export interface NodeRuntimeResourceSnapshot {
387
+ runningProcesses: number;
388
+ exitedProcesses: number;
389
+ fdTables: number;
390
+ openFds: number;
391
+ pipes: number;
392
+ pipeBufferedBytes: number;
393
+ ptys: number;
394
+ ptyBufferedInputBytes: number;
395
+ ptyBufferedOutputBytes: number;
396
+ sockets: number;
397
+ socketListeners: number;
398
+ socketConnections: number;
399
+ socketBufferedBytes: number;
400
+ socketDatagramQueueLen: number;
401
+ queueSnapshots: Array<{
402
+ name: string;
403
+ category: string;
404
+ depth: number;
405
+ highWater: number;
406
+ capacity: number;
407
+ fillPercent: number;
408
+ }>;
409
+ }
410
+ export interface NodeRuntimeResidentRunnerExecOptions {
411
+ /** Abort the guest eval after this many milliseconds. */
412
+ timeout?: number;
413
+ }
414
+ export type NodeRuntimeResidentRunnerOptions = {};
415
+ export interface NodeRuntimeResidentRunner {
416
+ exec(code: string, options?: NodeRuntimeResidentRunnerExecOptions): Promise<NodeRuntimeExecResult>;
417
+ dispose(): Promise<void>;
418
+ }
419
+ /** Result of {@link NodeRuntime.run}. */
420
+ export interface NodeRuntimeRunResult<T = unknown> {
421
+ /** The JSON-decoded value the guest produced, when the run succeeded. */
422
+ value?: T;
423
+ stdout: string;
424
+ stderr: string;
425
+ exitCode: number;
426
+ }
427
+ /**
428
+ * Ergonomic, batteries-included runtime for executing guest JavaScript.
429
+ *
430
+ * Construct one with {@link NodeRuntime.create}, run programs with
431
+ * {@link NodeRuntime.exec} / {@link NodeRuntime.run}, and release the VM with
432
+ * {@link NodeRuntime.dispose}. A single instance can run many programs; each
433
+ * call executes a fresh guest process.
434
+ */
435
+ export declare class NodeRuntime {
436
+ private readonly kernel;
437
+ private constructor();
438
+ /**
439
+ * Boot a VM and return a ready-to-use runtime. Spawns the sidecar, opens a
440
+ * session, creates the VM with a bootstrapped root filesystem, mounts the
441
+ * shell and Node runtimes, and waits for the VM to report ready.
442
+ */
443
+ static create(options?: NodeRuntimeCreateOptions): Promise<NodeRuntime>;
444
+ createResidentRunner(_options?: NodeRuntimeResidentRunnerOptions): Promise<NodeRuntimeResidentRunner>;
445
+ /**
446
+ * Run `code` as a guest Node program and capture its output.
447
+ *
448
+ * The source is written to an ES module inside the VM and executed with
449
+ * `node <file>`; it runs as standard ESM (top-level `await`, `import`).
450
+ */
451
+ exec(code: string, options?: NodeRuntimeExecOptions): Promise<NodeRuntimeExecResult>;
452
+ /**
453
+ * Run an already-written guest program file to completion and capture its
454
+ * output, honoring a caller-supplied `signal` for cancellation.
455
+ *
456
+ * Without a `signal`, this runs the program through the shell (`node <file>`)
457
+ * exactly as before. With a `signal`, it starts the program as a guest
458
+ * process so the run can be cancelled: when the signal aborts, the process is
459
+ * killed inside the VM (the kernel delivers `SIGTERM`) and the call rejects
460
+ * with the signal's abort reason.
461
+ */
462
+ private runProgram;
463
+ /**
464
+ * Start `code` as a long-running guest Node program and return a live handle
465
+ * to it, without waiting for it to finish.
466
+ *
467
+ * The source is written to an ES module inside the VM and started with
468
+ * `node <file>`; it runs as standard ESM (top-level `await`, `import`). The
469
+ * returned {@link NodeRuntimeProcess} lets you stream output, write to stdin,
470
+ * signal or kill the process, and await its exit. Pass `onStdout`/`onStderr`
471
+ * to receive output chunks as they are produced.
472
+ *
473
+ * Use this for guests that do not run to completion, such as a dev server you
474
+ * later drive with {@link NodeRuntime.fetch}:
475
+ *
476
+ * ```ts
477
+ * const server = await rt.spawn(`
478
+ * import http from "node:http";
479
+ * http.createServer((_, res) => res.end("ok")).listen(3000);
480
+ * `);
481
+ * const res = await rt.fetch(3000, { path: "/" });
482
+ * server.kill();
483
+ * await server.wait();
484
+ * ```
485
+ */
486
+ spawn(code: string, options?: NodeRuntimeSpawnOptions): Promise<NodeRuntimeProcess>;
487
+ /**
488
+ * Start an arbitrary guest command and return a live handle. This is the
489
+ * command-level companion to {@link spawn}, used by benchmark harnesses that
490
+ * need to measure kernel process spawning directly instead of running a source
491
+ * string through the ergonomic Node wrapper.
492
+ */
493
+ spawnCommand(command: string, args?: string[], options?: NodeRuntimeSpawnOptions): NodeRuntimeProcess;
494
+ /**
495
+ * Run an arbitrary guest command to completion and capture stdout/stderr.
496
+ * Unlike {@link exec}, this does not write a JavaScript source file first.
497
+ */
498
+ execCommand(command: string, args?: string[], options?: NodeRuntimeExecOptions): Promise<NodeRuntimeExecResult>;
499
+ /**
500
+ * Run `code` and return the JSON-serializable value it produces.
501
+ *
502
+ * The guest exposes a `__return(value)` function; call it with a
503
+ * JSON-serializable value and that value is decoded on the host as
504
+ * `result.value`. If `__return` is never called the value is `undefined`.
505
+ * stdout/stderr/exitCode are still captured.
506
+ */
507
+ run<T = unknown>(code: string, options?: NodeRuntimeExecOptions): Promise<NodeRuntimeRunResult<T>>;
508
+ /**
509
+ * Drive an HTTP request to a guest HTTP server listening inside the VM and
510
+ * read the response back on the host.
511
+ *
512
+ * Point this at a port a guest program is serving, for example a dev server
513
+ * started with {@link NodeRuntime.exec}. The
514
+ * request and response never leave the VM: the connection is made to the
515
+ * guest's loopback listener through the kernel socket table, so this works
516
+ * even when guest network egress is denied.
517
+ *
518
+ * ```ts
519
+ * const res = await rt.fetch(3000, { path: "/health" });
520
+ * console.log(res.status, res.body);
521
+ * ```
522
+ */
523
+ fetch(port: number, input: NodeRuntimeFetchInput): Promise<NodeRuntimeFetchResponse>;
524
+ /**
525
+ * Look up a guest TCP listener once and return it, or `null` when nothing is
526
+ * listening yet.
527
+ *
528
+ * This is the immediate, non-blocking check behind
529
+ * {@link NodeRuntime.waitForListener}: it asks the kernel socket table
530
+ * whether a guest process is accepting connections on the requested `port`
531
+ * (optionally narrowed by `host`/`path`) and returns the match, or `null` if
532
+ * none is up. Use {@link NodeRuntime.waitForListener} when you want to block
533
+ * until one appears.
534
+ *
535
+ * ```ts
536
+ * const listener = rt.findListener({ port: 3000 });
537
+ * if (listener) console.log("up on pid", listener.processId);
538
+ * ```
539
+ */
540
+ findListener(query: NodeRuntimeListenerQuery): NodeRuntimeListener | null;
541
+ /**
542
+ * Block until a guest TCP listener is accepting connections on the requested
543
+ * `port` (optionally narrowed by `host`/`path`), then resolve with it.
544
+ *
545
+ * This is the companion to {@link NodeRuntime.spawn} and
546
+ * {@link NodeRuntime.fetch} for dev-server scenarios: start a server, wait
547
+ * until it is actually listening, then drive requests into it. The kernel
548
+ * socket table is polled until a matching listener appears or the wait is
549
+ * cut short. If `timeoutMs` elapses (default 10000) or the supplied `signal`
550
+ * aborts first, the returned promise rejects.
551
+ *
552
+ * ```ts
553
+ * const server = await rt.spawn(`
554
+ * import http from "node:http";
555
+ * http.createServer((_, res) => res.end("ok")).listen(3000);
556
+ * `);
557
+ * const listener = await rt.waitForListener({ port: 3000 });
558
+ * const res = await rt.fetch(listener.port ?? 3000, { path: "/" });
559
+ * server.kill();
560
+ * await server.wait();
561
+ * ```
562
+ */
563
+ waitForListener(query: NodeRuntimeListenerQuery, options?: NodeRuntimeWaitForListenerOptions): Promise<NodeRuntimeListener>;
564
+ /**
565
+ * Register host-side bindings the guest can invoke as shell commands, after
566
+ * the VM is already running. Each entry becomes a named guest command; when
567
+ * the guest runs it, the invocation round-trips back to the host and runs the
568
+ * binding's `handler`, whose return value is delivered back to the guest. This
569
+ * is the same capability as the `bindings` create option, exposed for adding
570
+ * bindings to a live runtime. See `bindings` on {@link NodeRuntime.create} for
571
+ * the invocation shape and permission behavior.
572
+ *
573
+ * When registering bindings this way, make sure the `binding` permission scope
574
+ * is granted (for example `permissions: { binding: "allow" }` on
575
+ * {@link NodeRuntime.create}) so the bindings are invocable.
576
+ */
577
+ registerBindings(bindings: Record<string, BindingDefinition>): Promise<void>;
578
+ /**
579
+ * Write a file into the VM's virtual filesystem, creating parent
580
+ * directories as needed. Use this to project assets or npm packages into
581
+ * the sandbox after boot; the host filesystem is never touched.
582
+ */
583
+ writeFile(filePath: string, content: string | Uint8Array): Promise<void>;
584
+ /** Read a file from the VM's virtual filesystem as raw bytes. */
585
+ readFile(filePath: string): Promise<Uint8Array>;
586
+ /** Read directory entry names from the VM's virtual filesystem. */
587
+ readDir(dirPath: string): Promise<string[]>;
588
+ /** Read typed directory entries from the VM's virtual filesystem. */
589
+ readDirWithTypes(dirPath: string): Promise<VirtualDirEntry[]>;
590
+ getResourceSnapshot(): Promise<NodeRuntimeResourceSnapshot>;
591
+ /** Tear down the VM and release the sidecar. */
592
+ dispose(): Promise<void>;
593
+ }