@secure-exec/core 0.3.0-rc.1 → 0.3.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.
Files changed (142) hide show
  1. package/commands/[ +0 -0
  2. package/commands/_stubs +0 -0
  3. package/commands/arch +0 -0
  4. package/commands/awk +0 -0
  5. package/commands/b2sum +0 -0
  6. package/commands/base32 +0 -0
  7. package/commands/base64 +0 -0
  8. package/commands/basename +0 -0
  9. package/commands/basenc +0 -0
  10. package/commands/bash +0 -0
  11. package/commands/cat +0 -0
  12. package/commands/chcon +0 -0
  13. package/commands/chgrp +0 -0
  14. package/commands/chmod +0 -0
  15. package/commands/chown +0 -0
  16. package/commands/chroot +0 -0
  17. package/commands/cksum +0 -0
  18. package/commands/codex +0 -0
  19. package/commands/codex-exec +0 -0
  20. package/commands/column +0 -0
  21. package/commands/comm +0 -0
  22. package/commands/cp +0 -0
  23. package/commands/curl +0 -0
  24. package/commands/cut +0 -0
  25. package/commands/date +0 -0
  26. package/commands/dd +0 -0
  27. package/commands/df +0 -0
  28. package/commands/diff +0 -0
  29. package/commands/dir +0 -0
  30. package/commands/dircolors +0 -0
  31. package/commands/dirname +0 -0
  32. package/commands/du +0 -0
  33. package/commands/echo +0 -0
  34. package/commands/egrep +0 -0
  35. package/commands/env +0 -0
  36. package/commands/expand +0 -0
  37. package/commands/expr +0 -0
  38. package/commands/factor +0 -0
  39. package/commands/false +0 -0
  40. package/commands/fd +0 -0
  41. package/commands/fgrep +0 -0
  42. package/commands/file +0 -0
  43. package/commands/find +0 -0
  44. package/commands/fmt +0 -0
  45. package/commands/fold +0 -0
  46. package/commands/git +0 -0
  47. package/commands/grep +0 -0
  48. package/commands/groups +0 -0
  49. package/commands/gunzip +0 -0
  50. package/commands/gzip +0 -0
  51. package/commands/head +0 -0
  52. package/commands/hostid +0 -0
  53. package/commands/hostname +0 -0
  54. package/commands/http-test +0 -0
  55. package/commands/id +0 -0
  56. package/commands/install +0 -0
  57. package/commands/join +0 -0
  58. package/commands/jq +0 -0
  59. package/commands/kill +0 -0
  60. package/commands/link +0 -0
  61. package/commands/ln +0 -0
  62. package/commands/logname +0 -0
  63. package/commands/ls +0 -0
  64. package/commands/md5sum +0 -0
  65. package/commands/mkdir +0 -0
  66. package/commands/mkfifo +0 -0
  67. package/commands/mknod +0 -0
  68. package/commands/mktemp +0 -0
  69. package/commands/more +0 -0
  70. package/commands/mv +0 -0
  71. package/commands/nice +0 -0
  72. package/commands/nl +0 -0
  73. package/commands/nohup +0 -0
  74. package/commands/nproc +0 -0
  75. package/commands/numfmt +0 -0
  76. package/commands/od +0 -0
  77. package/commands/paste +0 -0
  78. package/commands/pathchk +0 -0
  79. package/commands/pinky +0 -0
  80. package/commands/printenv +0 -0
  81. package/commands/printf +0 -0
  82. package/commands/ptx +0 -0
  83. package/commands/pwd +0 -0
  84. package/commands/readlink +0 -0
  85. package/commands/realpath +0 -0
  86. package/commands/rev +0 -0
  87. package/commands/rg +0 -0
  88. package/commands/rm +0 -0
  89. package/commands/rmdir +0 -0
  90. package/commands/runcon +0 -0
  91. package/commands/sed +0 -0
  92. package/commands/seq +0 -0
  93. package/commands/sh +0 -0
  94. package/commands/sha1sum +0 -0
  95. package/commands/sha224sum +0 -0
  96. package/commands/sha256sum +0 -0
  97. package/commands/sha384sum +0 -0
  98. package/commands/sha512sum +0 -0
  99. package/commands/shred +0 -0
  100. package/commands/shuf +0 -0
  101. package/commands/sleep +0 -0
  102. package/commands/sort +0 -0
  103. package/commands/spawn-test-host +0 -0
  104. package/commands/split +0 -0
  105. package/commands/stat +0 -0
  106. package/commands/stdbuf +0 -0
  107. package/commands/strings +0 -0
  108. package/commands/stty +0 -0
  109. package/commands/sum +0 -0
  110. package/commands/sync +0 -0
  111. package/commands/tac +0 -0
  112. package/commands/tail +0 -0
  113. package/commands/tar +0 -0
  114. package/commands/tee +0 -0
  115. package/commands/test +0 -0
  116. package/commands/timeout +0 -0
  117. package/commands/touch +0 -0
  118. package/commands/tr +0 -0
  119. package/commands/tree +0 -0
  120. package/commands/true +0 -0
  121. package/commands/truncate +0 -0
  122. package/commands/tsort +0 -0
  123. package/commands/tty +0 -0
  124. package/commands/uname +0 -0
  125. package/commands/unexpand +0 -0
  126. package/commands/uniq +0 -0
  127. package/commands/unlink +0 -0
  128. package/commands/uptime +0 -0
  129. package/commands/users +0 -0
  130. package/commands/vdir +0 -0
  131. package/commands/wc +0 -0
  132. package/commands/which +0 -0
  133. package/commands/who +0 -0
  134. package/commands/whoami +0 -0
  135. package/commands/xargs +0 -0
  136. package/commands/xu +0 -0
  137. package/commands/yes +0 -0
  138. package/commands/yq +0 -0
  139. package/commands/zcat +0 -0
  140. package/dist/node-runtime.d.ts +51 -2
  141. package/dist/node-runtime.js +59 -9
  142. package/package.json +6 -3
package/commands/[ ADDED
Binary file
Binary file
package/commands/arch ADDED
Binary file
package/commands/awk ADDED
Binary file
package/commands/b2sum ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
package/commands/bash ADDED
Binary file
package/commands/cat ADDED
Binary file
package/commands/chcon ADDED
Binary file
package/commands/chgrp ADDED
Binary file
package/commands/chmod ADDED
Binary file
package/commands/chown ADDED
Binary file
Binary file
package/commands/cksum ADDED
Binary file
package/commands/codex ADDED
Binary file
Binary file
Binary file
package/commands/comm ADDED
Binary file
package/commands/cp ADDED
Binary file
package/commands/curl ADDED
Binary file
package/commands/cut ADDED
Binary file
package/commands/date ADDED
Binary file
package/commands/dd ADDED
Binary file
package/commands/df ADDED
Binary file
package/commands/diff ADDED
Binary file
package/commands/dir ADDED
Binary file
Binary file
Binary file
package/commands/du ADDED
Binary file
package/commands/echo ADDED
Binary file
package/commands/egrep ADDED
Binary file
package/commands/env ADDED
Binary file
Binary file
package/commands/expr ADDED
Binary file
Binary file
package/commands/false ADDED
Binary file
package/commands/fd ADDED
Binary file
package/commands/fgrep ADDED
Binary file
package/commands/file ADDED
Binary file
package/commands/find ADDED
Binary file
package/commands/fmt ADDED
Binary file
package/commands/fold ADDED
Binary file
package/commands/git ADDED
Binary file
package/commands/grep ADDED
Binary file
Binary file
Binary file
package/commands/gzip ADDED
Binary file
package/commands/head ADDED
Binary file
Binary file
Binary file
Binary file
package/commands/id ADDED
Binary file
Binary file
package/commands/join ADDED
Binary file
package/commands/jq ADDED
Binary file
package/commands/kill ADDED
Binary file
package/commands/link ADDED
Binary file
package/commands/ln ADDED
Binary file
Binary file
package/commands/ls ADDED
Binary file
Binary file
package/commands/mkdir ADDED
Binary file
Binary file
package/commands/mknod ADDED
Binary file
Binary file
package/commands/more ADDED
Binary file
package/commands/mv ADDED
Binary file
package/commands/nice ADDED
Binary file
package/commands/nl ADDED
Binary file
package/commands/nohup ADDED
Binary file
package/commands/nproc ADDED
Binary file
Binary file
package/commands/od ADDED
Binary file
package/commands/paste ADDED
Binary file
Binary file
package/commands/pinky ADDED
Binary file
Binary file
Binary file
package/commands/ptx ADDED
Binary file
package/commands/pwd ADDED
Binary file
Binary file
Binary file
package/commands/rev ADDED
Binary file
package/commands/rg ADDED
Binary file
package/commands/rm ADDED
Binary file
package/commands/rmdir ADDED
Binary file
Binary file
package/commands/sed ADDED
Binary file
package/commands/seq ADDED
Binary file
package/commands/sh ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/commands/shred ADDED
Binary file
package/commands/shuf ADDED
Binary file
package/commands/sleep ADDED
Binary file
package/commands/sort ADDED
Binary file
Binary file
package/commands/split ADDED
Binary file
package/commands/stat ADDED
Binary file
Binary file
Binary file
package/commands/stty ADDED
Binary file
package/commands/sum ADDED
Binary file
package/commands/sync ADDED
Binary file
package/commands/tac ADDED
Binary file
package/commands/tail ADDED
Binary file
package/commands/tar ADDED
Binary file
package/commands/tee ADDED
Binary file
package/commands/test ADDED
Binary file
Binary file
package/commands/touch ADDED
Binary file
package/commands/tr ADDED
Binary file
package/commands/tree ADDED
Binary file
package/commands/true ADDED
Binary file
Binary file
package/commands/tsort ADDED
Binary file
package/commands/tty ADDED
Binary file
package/commands/uname ADDED
Binary file
Binary file
package/commands/uniq ADDED
Binary file
Binary file
Binary file
package/commands/users ADDED
Binary file
package/commands/vdir ADDED
Binary file
package/commands/wc ADDED
Binary file
package/commands/which ADDED
Binary file
package/commands/who ADDED
Binary file
Binary file
package/commands/xargs ADDED
Binary file
package/commands/xu ADDED
Binary file
package/commands/yes ADDED
Binary file
package/commands/yq ADDED
Binary file
package/commands/zcat ADDED
Binary file
@@ -36,8 +36,10 @@ export interface NodeRuntimeCreateOptions {
36
36
  permissions?: Permissions;
37
37
  /**
38
38
  * Override the directory containing the WASM command binaries (the source of
39
- * the guest `sh`). Defaults to the in-repo build output, or the
40
- * `SECURE_EXEC_WASM_COMMANDS_DIR` environment variable when set.
39
+ * the guest `sh`). When unset, resolution falls back through the
40
+ * `SECURE_EXEC_WASM_COMMANDS_DIR` environment variable, the in-repo build
41
+ * output (developer checkouts), then the commands vendored into the installed
42
+ * `@secure-exec/core` package (published installs).
41
43
  */
42
44
  commandsDir?: string;
43
45
  /**
@@ -76,6 +78,38 @@ export interface NodeRuntimeCreateOptions {
76
78
  * ```
77
79
  */
78
80
  mounts?: HostDirectoryMount[];
81
+ /**
82
+ * Mount a host `node_modules` directory into the VM in one call so guest
83
+ * `import`/`require` resolve real, host-installed npm packages.
84
+ *
85
+ * Pass the absolute host path to a `node_modules` directory (or an object
86
+ * with that path and an explicit guest location). The whole directory is
87
+ * projected lazily, Docker-style, at a guest `node_modules` on the resolution
88
+ * path, so any package inside it resolves the way Node would over a real
89
+ * filesystem (ancestor `node_modules` walk, `exports`/conditions, symlinks).
90
+ * This is the ergonomic alternative to wiring up individual `mounts` entries
91
+ * per package.
92
+ *
93
+ * By default the directory is mounted at `/tmp/node_modules`, which is where
94
+ * the resolution walk for a program run by {@link NodeRuntime.exec} /
95
+ * {@link NodeRuntime.run} begins (each program is written under `/tmp`). Pass
96
+ * the object form with `guestPath` to mount it elsewhere on a different
97
+ * module's resolution path.
98
+ *
99
+ * ```ts
100
+ * const rt = await NodeRuntime.create({
101
+ * nodeModules: "/abs/path/to/project/node_modules",
102
+ * });
103
+ * await rt.exec(`
104
+ * import isNumber from "is-number";
105
+ * console.log(isNumber(42));
106
+ * `);
107
+ * ```
108
+ *
109
+ * The host filesystem is never exposed beyond the mounted `node_modules`
110
+ * subtree. The mount is read-only.
111
+ */
112
+ nodeModules?: string | NodeModulesMount;
79
113
  /**
80
114
  * Host-side tools the guest can invoke as shell commands. Each entry is
81
115
  * registered as a named guest command; when the guest runs it, the
@@ -138,6 +172,21 @@ export interface HostDirectoryMount {
138
172
  /** Mount read-only (the default). Pass `false` to allow guest writes. */
139
173
  readOnly?: boolean;
140
174
  }
175
+ /**
176
+ * Object form of the `nodeModules` create option: a host `node_modules`
177
+ * directory to project, optionally at an explicit guest path. The string form
178
+ * (`nodeModules: "/abs/node_modules"`) is shorthand for `{ hostPath }`.
179
+ */
180
+ export interface NodeModulesMount {
181
+ /** Absolute host `node_modules` directory to project (read lazily). */
182
+ hostPath: string;
183
+ /**
184
+ * Absolute guest path to mount it at. Defaults to `/tmp/node_modules`, where
185
+ * the resolution walk for {@link NodeRuntime.exec} / {@link NodeRuntime.run}
186
+ * programs begins. Override to put it on a different module's resolution path.
187
+ */
188
+ guestPath?: string;
189
+ }
141
190
  /** Result of {@link NodeRuntime.exec}. */
142
191
  export interface NodeRuntimeExecResult {
143
192
  stdout: string;
@@ -17,17 +17,53 @@
17
17
  * isolation boundary — no host escapes, no real Node.js builtins for guest
18
18
  * work.
19
19
  */
20
+ import { existsSync } from "node:fs";
20
21
  import path from "node:path";
21
22
  import { fileURLToPath } from "node:url";
22
23
  import { createInMemoryFileSystem, createKernel, createNodeRuntime, createWasmVmRuntime, NodeFileSystem, } from "./test-runtime.js";
23
- /** Repository root, used to locate the bundled WASM command binaries. */
24
+ /** Repository root, used to locate the in-repo WASM command build output. */
24
25
  const REPO_ROOT = fileURLToPath(new URL("../../..", import.meta.url));
25
26
  /**
26
- * Directory containing the WASM coreutils/shell command binaries that provide
27
- * the guest `sh` the kernel needs to drive `exec()`. Built from the in-repo
28
- * Rust command sources.
27
+ * In-repo build output for the WASM coreutils/shell command binaries, produced
28
+ * by the Rust command build (`make -C registry/native wasm`). Only present in a
29
+ * developer checkout; preferred when it exists so local edits are picked up
30
+ * without re-vendoring.
29
31
  */
30
- const DEFAULT_COMMANDS_DIR = path.join(REPO_ROOT, "registry/native/target/wasm32-wasip1/release/commands");
32
+ const REPO_COMMANDS_DIR = path.join(REPO_ROOT, "registry/native/target/wasm32-wasip1/release/commands");
33
+ /**
34
+ * Commands vendored into the published `@secure-exec/core` package by
35
+ * `scripts/copy-wasm-commands.mjs` (listed in `files` as `commands`). This is
36
+ * the directory a real `npm install secure-exec` resolves: from the compiled
37
+ * `dist/node-runtime.js` it sits at `<package>/commands`. This is the analogue
38
+ * of how the sidecar binary ships inside `@secure-exec/sidecar`.
39
+ */
40
+ const BUNDLED_COMMANDS_DIR = fileURLToPath(new URL("../commands", import.meta.url));
41
+ /**
42
+ * Resolve the directory holding the WASM command binaries (the source of the
43
+ * guest `sh` the kernel needs to spawn any process). Precedence:
44
+ *
45
+ * 1. explicit `commandsDir` option,
46
+ * 2. `SECURE_EXEC_WASM_COMMANDS_DIR` env var,
47
+ * 3. the in-repo build output (developer checkout), when present,
48
+ * 4. the commands vendored into the installed package (published installs).
49
+ *
50
+ * The in-repo path wins over the bundled copy so local development picks up
51
+ * freshly built commands without re-vendoring. A fresh `npm install` has no
52
+ * in-repo path, so it falls through to the bundled copy.
53
+ */
54
+ function resolveCommandsDir(explicit) {
55
+ if (explicit !== undefined) {
56
+ return explicit;
57
+ }
58
+ const fromEnv = process.env.SECURE_EXEC_WASM_COMMANDS_DIR;
59
+ if (fromEnv) {
60
+ return fromEnv;
61
+ }
62
+ if (existsSync(REPO_COMMANDS_DIR)) {
63
+ return REPO_COMMANDS_DIR;
64
+ }
65
+ return BUNDLED_COMMANDS_DIR;
66
+ }
31
67
  /**
32
68
  * Secure-by-default permission policy applied when the caller passes no
33
69
  * `permissions`. Outward-facing capabilities are denied: there is **no network
@@ -45,6 +81,8 @@ const DEFAULT_PERMISSIONS = {
45
81
  env: "allow",
46
82
  network: "deny",
47
83
  };
84
+ /** Guest path a `nodeModules` mount is projected at by default. */
85
+ const DEFAULT_NODE_MODULES_GUEST_PATH = "/tmp/node_modules";
48
86
  let nextProgramId = 0;
49
87
  /**
50
88
  * Ergonomic, batteries-included runtime for executing guest JavaScript.
@@ -65,9 +103,7 @@ export class NodeRuntime {
65
103
  * shell and Node runtimes, and waits for the VM to report ready.
66
104
  */
67
105
  static async create(options = {}) {
68
- const commandsDir = options.commandsDir ??
69
- process.env.SECURE_EXEC_WASM_COMMANDS_DIR ??
70
- DEFAULT_COMMANDS_DIR;
106
+ const commandsDir = resolveCommandsDir(options.commandsDir);
71
107
  // Seed caller-provided files into the VM's in-memory filesystem before
72
108
  // boot so they are part of the root filesystem snapshot the guest sees
73
109
  // (e.g. projected npm packages or fixtures). The host filesystem is
@@ -81,7 +117,21 @@ export class NodeRuntime {
81
117
  // Project host directories into the VM, Docker-style. NodeFileSystem
82
118
  // reads lazily through the VFS so large trees never traverse the
83
119
  // protocol frame as a single blob.
84
- const mounts = (options.mounts ?? []).map((mount) => ({
120
+ const hostMounts = [...(options.mounts ?? [])];
121
+ // The `nodeModules` helper is sugar over a single host directory mount:
122
+ // project the whole host `node_modules` at a guest `node_modules` on the
123
+ // resolution path so any package inside resolves like real Node would.
124
+ if (options.nodeModules !== undefined) {
125
+ const nodeModules = typeof options.nodeModules === "string"
126
+ ? { hostPath: options.nodeModules }
127
+ : options.nodeModules;
128
+ hostMounts.push({
129
+ guestPath: nodeModules.guestPath ?? DEFAULT_NODE_MODULES_GUEST_PATH,
130
+ hostPath: nodeModules.hostPath,
131
+ readOnly: true,
132
+ });
133
+ }
134
+ const mounts = hostMounts.map((mount) => ({
85
135
  path: mount.guestPath,
86
136
  fs: new NodeFileSystem({ root: mount.hostPath }),
87
137
  readOnly: mount.readOnly ?? true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secure-exec/core",
3
- "version": "0.3.0-rc.1",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -8,6 +8,7 @@
8
8
  "files": [
9
9
  "dist",
10
10
  "fixtures",
11
+ "commands",
11
12
  "README.md"
12
13
  ],
13
14
  "exports": {
@@ -178,12 +179,14 @@
178
179
  "scripts": {
179
180
  "build:protocol": "pnpm --dir ../build-tools build:protocol",
180
181
  "build:vm-config": "cargo test -p secure-exec-vm-config --quiet",
182
+ "copy-commands": "node scripts/copy-wasm-commands.mjs",
181
183
  "check-types": "pnpm run build:protocol && pnpm run build:vm-config && tsc --noEmit",
182
- "build": "pnpm run build:protocol && pnpm run build:vm-config && tsc",
184
+ "build": "pnpm run build:protocol && pnpm run build:vm-config && tsc && pnpm run copy-commands",
185
+ "prepack": "node scripts/copy-wasm-commands.mjs --require",
183
186
  "test": "vitest run"
184
187
  },
185
188
  "dependencies": {
186
- "@secure-exec/sidecar": "0.3.0-rc.1",
189
+ "@secure-exec/sidecar": "0.3.0",
187
190
  "@rivetkit/bare-ts": "^0.6.2"
188
191
  },
189
192
  "devDependencies": {