@rivet-dev/agentos-core 0.0.0-integrate-dylib-into-main.815fcda → 0.0.0-main.ab2ce7c

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 (101) hide show
  1. package/README.md +5 -8
  2. package/dist/agent-os.d.ts +168 -46
  3. package/dist/agent-os.js +809 -543
  4. package/dist/agentos-package.d.ts +29 -0
  5. package/dist/agentos-package.js +88 -0
  6. package/dist/base-filesystem.d.ts +2 -15
  7. package/dist/base-filesystem.js +23 -171
  8. package/dist/cron/types.d.ts +1 -1
  9. package/dist/default-software.d.ts +8 -0
  10. package/dist/default-software.js +10 -0
  11. package/dist/generated/AcpLimitsConfig.d.ts +4 -0
  12. package/dist/generated/AcpLimitsConfig.js +2 -0
  13. package/dist/generated/CreateVmConfig.d.ts +26 -0
  14. package/dist/generated/CreateVmConfig.js +1 -0
  15. package/dist/generated/FsPermissionRule.d.ts +6 -0
  16. package/dist/generated/FsPermissionRule.js +1 -0
  17. package/dist/generated/FsPermissionRuleSet.d.ts +6 -0
  18. package/dist/generated/FsPermissionRuleSet.js +1 -0
  19. package/dist/generated/FsPermissionScope.d.ts +3 -0
  20. package/dist/generated/FsPermissionScope.js +1 -0
  21. package/dist/generated/HttpLimitsConfig.d.ts +3 -0
  22. package/dist/generated/HttpLimitsConfig.js +2 -0
  23. package/dist/generated/JsModuleResolution.d.ts +1 -0
  24. package/dist/generated/JsModuleResolution.js +2 -0
  25. package/dist/generated/JsRuntimeConfig.d.ts +31 -0
  26. package/dist/generated/JsRuntimeConfig.js +1 -0
  27. package/dist/generated/JsRuntimeLimitsConfig.d.ts +11 -0
  28. package/dist/generated/JsRuntimeLimitsConfig.js +2 -0
  29. package/dist/generated/JsRuntimePlatform.d.ts +1 -0
  30. package/dist/generated/JsRuntimePlatform.js +2 -0
  31. package/dist/generated/MountPluginDescriptor.d.ts +4 -0
  32. package/dist/generated/MountPluginDescriptor.js +2 -0
  33. package/dist/generated/NativeRootFilesystemConfig.d.ts +5 -0
  34. package/dist/generated/NativeRootFilesystemConfig.js +1 -0
  35. package/dist/generated/PatternPermissionRule.d.ts +6 -0
  36. package/dist/generated/PatternPermissionRule.js +1 -0
  37. package/dist/generated/PatternPermissionRuleSet.d.ts +6 -0
  38. package/dist/generated/PatternPermissionRuleSet.js +1 -0
  39. package/dist/generated/PatternPermissionScope.d.ts +3 -0
  40. package/dist/generated/PatternPermissionScope.js +1 -0
  41. package/dist/generated/PermissionMode.d.ts +1 -0
  42. package/dist/generated/PermissionMode.js +2 -0
  43. package/dist/generated/PermissionsPolicy.d.ts +10 -0
  44. package/dist/generated/PermissionsPolicy.js +1 -0
  45. package/dist/generated/PluginLimitsConfig.d.ts +4 -0
  46. package/dist/generated/PluginLimitsConfig.js +2 -0
  47. package/dist/generated/PythonLimitsConfig.d.ts +6 -0
  48. package/dist/generated/PythonLimitsConfig.js +2 -0
  49. package/dist/generated/ResourceLimitsConfig.d.ts +24 -0
  50. package/dist/generated/ResourceLimitsConfig.js +2 -0
  51. package/dist/generated/RootFilesystemConfig.d.ts +9 -0
  52. package/dist/generated/RootFilesystemConfig.js +1 -0
  53. package/dist/generated/RootFilesystemEntry.d.ts +13 -0
  54. package/dist/generated/RootFilesystemEntry.js +1 -0
  55. package/dist/generated/RootFilesystemEntryEncoding.d.ts +1 -0
  56. package/dist/generated/RootFilesystemEntryEncoding.js +2 -0
  57. package/dist/generated/RootFilesystemEntryKind.d.ts +1 -0
  58. package/dist/generated/RootFilesystemEntryKind.js +2 -0
  59. package/dist/generated/RootFilesystemLowerDescriptor.d.ts +7 -0
  60. package/dist/generated/RootFilesystemLowerDescriptor.js +1 -0
  61. package/dist/generated/RootFilesystemMode.d.ts +1 -0
  62. package/dist/generated/RootFilesystemMode.js +2 -0
  63. package/dist/generated/ToolLimitsConfig.d.ts +10 -0
  64. package/dist/generated/ToolLimitsConfig.js +2 -0
  65. package/dist/generated/VmDnsConfig.d.ts +6 -0
  66. package/dist/generated/VmDnsConfig.js +2 -0
  67. package/dist/generated/VmLimitsConfig.d.ts +18 -0
  68. package/dist/generated/VmLimitsConfig.js +1 -0
  69. package/dist/generated/VmListenPolicyConfig.d.ts +5 -0
  70. package/dist/generated/VmListenPolicyConfig.js +2 -0
  71. package/dist/generated/WasmLimitsConfig.d.ts +7 -0
  72. package/dist/generated/WasmLimitsConfig.js +2 -0
  73. package/dist/host-dir-mount.d.ts +1 -1
  74. package/dist/host-tools-zod.js +27 -7
  75. package/dist/host-tools.js +9 -0
  76. package/dist/index.d.ts +3 -1
  77. package/dist/index.js +2 -1
  78. package/dist/layers.d.ts +2 -2
  79. package/dist/layers.js +19 -10
  80. package/dist/options-schema.d.ts +453 -0
  81. package/dist/options-schema.js +268 -0
  82. package/dist/packages.d.ts +17 -116
  83. package/dist/packages.js +35 -322
  84. package/dist/runtime-compat.d.ts +22 -9
  85. package/dist/runtime-compat.js +130 -144
  86. package/dist/runtime.d.ts +32 -5
  87. package/dist/sandbox.d.ts +112 -0
  88. package/dist/sandbox.js +264 -0
  89. package/dist/sidecar/agentos-protocol.d.ts +99 -1
  90. package/dist/sidecar/agentos-protocol.js +155 -18
  91. package/dist/sidecar/native-process-client.d.ts +6 -2
  92. package/dist/sidecar/native-process-client.js +8 -1
  93. package/dist/sidecar/permissions.d.ts +1 -1
  94. package/dist/sidecar/permissions.js +4 -4
  95. package/dist/sidecar/rpc-client.d.ts +62 -4
  96. package/dist/sidecar/rpc-client.js +339 -85
  97. package/dist/types.d.ts +10 -3
  98. package/package.json +40 -33
  99. package/dist/agents.d.ts +0 -63
  100. package/dist/agents.js +0 -42
  101. package/fixtures/AGENTOS_SYSTEM_PROMPT.md +0 -21
@@ -17,8 +17,13 @@ const S_IFREG = 0o100000;
17
17
  const S_IFDIR = 0o040000;
18
18
  const S_IFLNK = 0o120000;
19
19
  const MAX_SYMLINK_DEPTH = 40;
20
- const KERNEL_COMMAND_STUB = "#!/bin/sh\n# kernel command stub\n";
21
- const NODE_RUNTIME_BOOTSTRAP_COMMANDS = ["node", "npm", "npx"];
20
+ const NODE_RUNTIME_BOOTSTRAP_COMMANDS = [
21
+ "node",
22
+ "npm",
23
+ "npx",
24
+ "python",
25
+ "python3",
26
+ ];
22
27
  const KERNEL_POSIX_BOOTSTRAP_DIRS = [
23
28
  "/dev",
24
29
  "/proc",
@@ -36,7 +41,8 @@ const KERNEL_POSIX_BOOTSTRAP_DIRS = [
36
41
  "/mnt",
37
42
  "/media",
38
43
  "/home",
39
- "/home/user",
44
+ "/home/agentos",
45
+ "/workspace",
40
46
  "/usr",
41
47
  "/usr/bin",
42
48
  "/usr/games",
@@ -118,7 +124,7 @@ export class InMemoryFileSystem {
118
124
  throw errnoError("ENOENT", `open '${targetPath}'`);
119
125
  }
120
126
  entry.atimeMs = Date.now();
121
- return entry.data;
127
+ return new Uint8Array(entry.data);
122
128
  }
123
129
  async readTextFile(targetPath) {
124
130
  return new TextDecoder().decode(await this.readFile(targetPath));
@@ -151,7 +157,9 @@ export class InMemoryFileSystem {
151
157
  async writeFile(targetPath, content) {
152
158
  const normalized = normalizePath(targetPath);
153
159
  await this.mkdir(dirnameVirtual(normalized), { recursive: true });
154
- const data = typeof content === "string" ? new TextEncoder().encode(content) : content;
160
+ const data = typeof content === "string"
161
+ ? new TextEncoder().encode(content)
162
+ : new Uint8Array(content);
155
163
  const existing = this.entries.get(normalized);
156
164
  if (existing?.type === "file") {
157
165
  existing.data = data;
@@ -211,7 +219,7 @@ export class InMemoryFileSystem {
211
219
  return this.toStat(entry);
212
220
  }
213
221
  async removeFile(targetPath) {
214
- const resolved = this.resolvePath(targetPath);
222
+ const resolved = normalizePath(targetPath);
215
223
  const entry = this.entries.get(resolved);
216
224
  if (!entry || entry.type === "dir") {
217
225
  throw errnoError("ENOENT", `unlink '${targetPath}'`);
@@ -373,7 +381,7 @@ export class InMemoryFileSystem {
373
381
  const nextSize = Math.max(entry.data.length, offset + data.length);
374
382
  const updated = new Uint8Array(nextSize);
375
383
  updated.set(entry.data);
376
- updated.set(data, offset);
384
+ updated.set(new Uint8Array(data), offset);
377
385
  entry.data = updated;
378
386
  entry.mtimeMs = Date.now();
379
387
  entry.ctimeMs = Date.now();
@@ -729,6 +737,7 @@ export function createNodeDriver(options = {}) {
729
737
  network: options.networkAdapter,
730
738
  commandExecutor: options.commandExecutor,
731
739
  permissions: options.permissions,
740
+ mounts: options.mounts ?? [],
732
741
  runtime: {
733
742
  process: options.processConfig ?? {},
734
743
  os: options.osConfig ?? {},
@@ -816,7 +825,6 @@ export const WASMVM_COMMANDS = Object.freeze([
816
825
  "sqlite3",
817
826
  "curl",
818
827
  "wget",
819
- "make",
820
828
  "git",
821
829
  "git-remote-http",
822
830
  "git-remote-https",
@@ -915,7 +923,6 @@ export const DEFAULT_FIRST_PARTY_TIERS = Object.freeze({
915
923
  nice: "full",
916
924
  nohup: "full",
917
925
  stdbuf: "full",
918
- make: "full",
919
926
  codex: "full",
920
927
  "codex-exec": "full",
921
928
  git: "full",
@@ -1015,7 +1022,7 @@ function isWasmBinaryFile(filePath) {
1015
1022
  function discoverWasmCommandEntries(commandDirs) {
1016
1023
  const discovered = [];
1017
1024
  const seen = new Set();
1018
- commandDirs.forEach((commandDir, dirOffset) => {
1025
+ for (const commandDir of commandDirs) {
1019
1026
  let entries;
1020
1027
  try {
1021
1028
  entries = fsSync
@@ -1023,7 +1030,7 @@ function discoverWasmCommandEntries(commandDirs) {
1023
1030
  .sort((left, right) => left.localeCompare(right));
1024
1031
  }
1025
1032
  catch {
1026
- return;
1033
+ continue;
1027
1034
  }
1028
1035
  for (const entry of entries) {
1029
1036
  if (entry.startsWith("."))
@@ -1036,7 +1043,6 @@ function discoverWasmCommandEntries(commandDirs) {
1036
1043
  discovered.push({
1037
1044
  name: entry,
1038
1045
  hostPath: fullPath,
1039
- dirOffset,
1040
1046
  });
1041
1047
  continue;
1042
1048
  }
@@ -1047,13 +1053,12 @@ function discoverWasmCommandEntries(commandDirs) {
1047
1053
  discovered.push({
1048
1054
  name: entry,
1049
1055
  hostPath: fullPath,
1050
- dirOffset,
1051
1056
  });
1052
1057
  }
1053
1058
  }
1054
1059
  catch { }
1055
1060
  }
1056
- });
1061
+ }
1057
1062
  return discovered;
1058
1063
  }
1059
1064
  class WasmVmRuntimeDescriptor {
@@ -1063,7 +1068,6 @@ class WasmVmRuntimeDescriptor {
1063
1068
  commandDirs;
1064
1069
  _commandPaths = new Map();
1065
1070
  _moduleCache = new Map();
1066
- commandDirOffsets = new Map();
1067
1071
  constructor(options) {
1068
1072
  this.commandDirs =
1069
1073
  options.commandDirs && options.commandDirs.length > 0
@@ -1094,17 +1098,6 @@ class WasmVmRuntimeDescriptor {
1094
1098
  this.refreshDiscovery();
1095
1099
  return this._commandPaths.has(normalized);
1096
1100
  }
1097
- getGuestCommandPaths(startIndex) {
1098
- const guestPaths = new Map();
1099
- for (const [name] of this._commandPaths) {
1100
- const dirOffset = this.commandDirOffsets.get(name);
1101
- if (dirOffset === undefined) {
1102
- continue;
1103
- }
1104
- guestPaths.set(name, `/__secure_exec/commands/${startIndex + dirOffset}/${name}`);
1105
- }
1106
- return guestPaths;
1107
- }
1108
1101
  recordModuleExecution(command) {
1109
1102
  const normalized = normalizeCommandLookup(command);
1110
1103
  if (this._commandPaths.has(normalized) ||
@@ -1120,11 +1113,9 @@ class WasmVmRuntimeDescriptor {
1120
1113
  const discovered = discoverWasmCommandEntries(this.commandDirs);
1121
1114
  this.commands.length = 0;
1122
1115
  this._commandPaths.clear();
1123
- this.commandDirOffsets.clear();
1124
1116
  for (const entry of discovered) {
1125
1117
  this.commands.push(entry.name);
1126
1118
  this._commandPaths.set(entry.name, entry.hostPath);
1127
- this.commandDirOffsets.set(entry.name, entry.dirOffset);
1128
1119
  }
1129
1120
  }
1130
1121
  }
@@ -1190,8 +1181,8 @@ function ensureNativeSidecarBinary() {
1190
1181
  function rootEntryExecutable(kind, mode) {
1191
1182
  return kind === "file" && (mode & 0o111) !== 0;
1192
1183
  }
1193
- function createBootstrapEntries(commandNames) {
1194
- const entries = [
1184
+ function createBootstrapEntries() {
1185
+ return [
1195
1186
  {
1196
1187
  path: "/",
1197
1188
  kind: "directory",
@@ -1219,19 +1210,6 @@ function createBootstrapEntries(commandNames) {
1219
1210
  executable: false,
1220
1211
  },
1221
1212
  ];
1222
- for (const command of [...new Set(commandNames)].sort((left, right) => left.localeCompare(right))) {
1223
- entries.push({
1224
- path: `/bin/${command}`,
1225
- kind: "file",
1226
- mode: 0o755,
1227
- uid: 0,
1228
- gid: 0,
1229
- content: KERNEL_COMMAND_STUB,
1230
- encoding: "utf8",
1231
- executable: true,
1232
- });
1233
- }
1234
- return entries;
1235
1213
  }
1236
1214
  function mergeRootFilesystemEntries(baseEntries, overrideEntries) {
1237
1215
  const merged = new Map();
@@ -1372,23 +1350,6 @@ function planNodeFilesystemPassthroughMounts(filesystem, existingMounts) {
1372
1350
  passthroughDirectories,
1373
1351
  };
1374
1352
  }
1375
- function collectGuestCommandPaths(commandDirs, startIndex = 0) {
1376
- const guestPaths = new Map();
1377
- for (const entry of discoverWasmCommandEntries(commandDirs)) {
1378
- if (!guestPaths.has(entry.name)) {
1379
- guestPaths.set(entry.name, `/__secure_exec/commands/${startIndex + entry.dirOffset}/${entry.name}`);
1380
- }
1381
- }
1382
- return guestPaths;
1383
- }
1384
- async function ensureCommandStubs(proxy, commands) {
1385
- const rootView = proxy.createRootView();
1386
- for (const command of commands) {
1387
- const stubPath = `/bin/${command}`;
1388
- await rootView.writeFile(stubPath, KERNEL_COMMAND_STUB);
1389
- await rootView.chmod(stubPath, 0o755);
1390
- }
1391
- }
1392
1353
  class DeferredFileSystem {
1393
1354
  getFilesystem;
1394
1355
  constructor(getFilesystem) {
@@ -1606,6 +1567,35 @@ function bindLiveFilesystem(target, getFilesystem) {
1606
1567
  },
1607
1568
  };
1608
1569
  }
1570
+ function serializeLocalCompatMountForSidecar(mount) {
1571
+ return (mount.sidecarMount ??
1572
+ (mount.fs instanceof NodeFileSystem
1573
+ ? serializeMountConfigForSidecar({
1574
+ path: mount.path,
1575
+ readOnly: mount.readOnly,
1576
+ plugin: {
1577
+ id: "host_dir",
1578
+ config: {
1579
+ hostPath: mount.fs.rootPath,
1580
+ readOnly: mount.readOnly,
1581
+ },
1582
+ },
1583
+ })
1584
+ : serializeMountConfigForSidecar({
1585
+ path: mount.path,
1586
+ driver: mount.fs,
1587
+ readOnly: mount.readOnly,
1588
+ })));
1589
+ }
1590
+ function makeLocalCompatMount(options) {
1591
+ const localMount = {
1592
+ path: normalizePath(options.path),
1593
+ fs: options.fs,
1594
+ readOnly: options.readOnly ?? false,
1595
+ };
1596
+ localMount.sidecarMount = serializeLocalCompatMountForSidecar(localMount);
1597
+ return localMount;
1598
+ }
1609
1599
  class NativeKernel {
1610
1600
  options;
1611
1601
  env;
@@ -1627,12 +1617,11 @@ class NativeKernel {
1627
1617
  pendingLocalMounts = [];
1628
1618
  mountedCommandDirs = [];
1629
1619
  mountedRuntimeDrivers = [];
1630
- runtimeDriverCommandDirStarts = new Map();
1631
1620
  loopbackExemptPorts;
1632
1621
  constructor(options) {
1633
1622
  this.options = options;
1634
1623
  this.env = { ...(options.env ?? {}) };
1635
- this.cwd = options.cwd ?? "/home/user";
1624
+ this.cwd = options.cwd ?? "/workspace";
1636
1625
  this.socketTable = {
1637
1626
  hasHostNetworkAdapter: () => Boolean(options.hostNetworkAdapter),
1638
1627
  findListener: (request) => this.proxy?.findListener(request) ?? null,
@@ -1645,11 +1634,11 @@ class NativeKernel {
1645
1634
  };
1646
1635
  this.loopbackExemptPorts = [...(options.loopbackExemptPorts ?? [])];
1647
1636
  for (const mount of options.mounts ?? []) {
1648
- this.pendingLocalMounts.push({
1649
- path: normalizePath(mount.path),
1637
+ this.pendingLocalMounts.push(makeLocalCompatMount({
1638
+ path: mount.path,
1650
1639
  fs: mount.fs,
1651
- readOnly: mount.readOnly ?? false,
1652
- });
1640
+ readOnly: mount.readOnly,
1641
+ }));
1653
1642
  }
1654
1643
  this.vfs = new DeferredFileSystem(() => this.rootFilesystem);
1655
1644
  this.liveFilesystemBinding = bindLiveFilesystem(this.options.filesystem, () => this.rootFilesystem);
@@ -1657,6 +1646,32 @@ class NativeKernel {
1657
1646
  get zombieTimerCount() {
1658
1647
  return this.proxy?.zombieTimerCount ?? 0;
1659
1648
  }
1649
+ async configureRuntimeCommandStubs(commands, commandDirs = this.mountedCommandDirs) {
1650
+ if (!this.client || !this.session || !this.vm) {
1651
+ throw new Error("kernel is not ready");
1652
+ }
1653
+ const sidecarMounts = commandDirs.map((commandDir, index) => serializeMountConfigForSidecar({
1654
+ path: `/__secure_exec/commands/${index}`,
1655
+ readOnly: true,
1656
+ plugin: {
1657
+ id: "host_dir",
1658
+ config: {
1659
+ hostPath: commandDir,
1660
+ readOnly: true,
1661
+ },
1662
+ },
1663
+ }));
1664
+ const localMounts = this.pendingLocalMounts.map((mount) => serializeLocalCompatMountForSidecar(mount));
1665
+ const configuredVm = await this.client.configureVm(this.session, this.vm, {
1666
+ mounts: [...localMounts, ...sidecarMounts],
1667
+ loopbackExemptPorts: this.loopbackExemptPorts,
1668
+ bootstrapCommands: [...new Set(commands)].sort((left, right) => left.localeCompare(right)),
1669
+ });
1670
+ return new Map(configuredVm.projectedCommands.map((command) => [
1671
+ command.name,
1672
+ command.guestPath,
1673
+ ]));
1674
+ }
1660
1675
  async mount(driver) {
1661
1676
  await this.ensureReady();
1662
1677
  if (!this.proxy || !this.client || !this.session || !this.vm) {
@@ -1668,7 +1683,7 @@ class NativeKernel {
1668
1683
  this.commands.set(command, "node");
1669
1684
  }
1670
1685
  this.mountedRuntimeDrivers.push(driver);
1671
- await ensureCommandStubs(this.proxy, driver.commands);
1686
+ await this.configureRuntimeCommandStubs(driver.commands);
1672
1687
  return;
1673
1688
  }
1674
1689
  const commandDirs = driver.commandDirs ?? [];
@@ -1677,53 +1692,17 @@ class NativeKernel {
1677
1692
  this.commands.set(command, "wasmvm");
1678
1693
  }
1679
1694
  this.mountedRuntimeDrivers.push(driver);
1680
- await ensureCommandStubs(this.proxy, driver.commands);
1695
+ await this.configureRuntimeCommandStubs(driver.commands);
1681
1696
  return;
1682
1697
  }
1683
- const startIndex = this.mountedCommandDirs.length;
1684
- const newGuestPaths = driver.getGuestCommandPaths?.(startIndex) ??
1685
- collectGuestCommandPaths(commandDirs, startIndex);
1686
1698
  const allCommandDirs = [...this.mountedCommandDirs, ...commandDirs];
1687
- const sidecarMounts = allCommandDirs.map((commandDir, index) => serializeMountConfigForSidecar({
1688
- path: `/__secure_exec/commands/${index}`,
1689
- readOnly: true,
1690
- plugin: {
1691
- id: "host_dir",
1692
- config: {
1693
- hostPath: commandDir,
1694
- readOnly: true,
1695
- },
1696
- },
1697
- }));
1698
- const localMounts = this.pendingLocalMounts.map((mount) => mount.fs instanceof NodeFileSystem
1699
- ? serializeMountConfigForSidecar({
1700
- path: mount.path,
1701
- readOnly: mount.readOnly,
1702
- plugin: {
1703
- id: "host_dir",
1704
- config: {
1705
- hostPath: mount.fs.rootPath,
1706
- readOnly: mount.readOnly,
1707
- },
1708
- },
1709
- })
1710
- : serializeMountConfigForSidecar({
1711
- path: mount.path,
1712
- driver: mount.fs,
1713
- readOnly: mount.readOnly,
1714
- }));
1715
- await this.client.configureVm(this.session, this.vm, {
1716
- mounts: [...localMounts, ...sidecarMounts],
1717
- loopbackExemptPorts: this.loopbackExemptPorts,
1718
- });
1719
- this.proxy.registerCommandGuestPaths(newGuestPaths);
1699
+ const projectedCommands = await this.configureRuntimeCommandStubs(driver.commands, allCommandDirs);
1700
+ this.proxy.registerCommandGuestPaths(projectedCommands);
1720
1701
  this.mountedCommandDirs.push(...commandDirs);
1721
1702
  this.mountedRuntimeDrivers.push(driver);
1722
- this.runtimeDriverCommandDirStarts.set(driver, startIndex);
1723
- for (const command of newGuestPaths.keys()) {
1703
+ for (const command of projectedCommands.keys()) {
1724
1704
  this.commands.set(command, "wasmvm");
1725
1705
  }
1726
- await ensureCommandStubs(this.proxy, newGuestPaths.keys());
1727
1706
  }
1728
1707
  async dispose() {
1729
1708
  await this.readyPromise?.catch(() => { });
@@ -1784,10 +1763,10 @@ class NativeKernel {
1784
1763
  return {
1785
1764
  pid: proc.pid,
1786
1765
  writeStdin(data) {
1787
- proc.writeStdin(data);
1766
+ return proc.writeStdin(data);
1788
1767
  },
1789
1768
  closeStdin() {
1790
- proc.closeStdin();
1769
+ return proc.closeStdin();
1791
1770
  },
1792
1771
  kill(signal) {
1793
1772
  proc.kill(signal);
@@ -1817,17 +1796,27 @@ class NativeKernel {
1817
1796
  return this.proxy.connectTerminal(options);
1818
1797
  }
1819
1798
  mountFs(mountPath, filesystem, options) {
1799
+ const localMount = makeLocalCompatMount({
1800
+ path: mountPath,
1801
+ fs: filesystem,
1802
+ readOnly: options?.readOnly,
1803
+ });
1804
+ this.pendingLocalMounts.unshift(localMount);
1805
+ this.pendingLocalMounts.sort((left, right) => right.path.length - left.path.length);
1820
1806
  if (!this.proxy) {
1821
- this.pendingLocalMounts.push({
1822
- path: normalizePath(mountPath),
1823
- fs: filesystem,
1824
- readOnly: options?.readOnly ?? false,
1825
- });
1826
1807
  return;
1827
1808
  }
1828
- this.proxy.mountFs(mountPath, filesystem, options);
1809
+ this.proxy.mountFs(mountPath, filesystem, {
1810
+ readOnly: localMount.readOnly,
1811
+ sidecarMount: localMount.sidecarMount,
1812
+ });
1829
1813
  }
1830
1814
  unmountFs(mountPath) {
1815
+ const normalized = normalizePath(mountPath);
1816
+ const pendingIndex = this.pendingLocalMounts.findIndex((mount) => mount.path === normalized);
1817
+ if (pendingIndex >= 0) {
1818
+ this.pendingLocalMounts.splice(pendingIndex, 1);
1819
+ }
1831
1820
  this.proxy?.unmountFs(mountPath);
1832
1821
  }
1833
1822
  async readFile(targetPath) {
@@ -1846,6 +1835,10 @@ class NativeKernel {
1846
1835
  await this.ensureReady();
1847
1836
  return this.proxy.readdir(targetPath);
1848
1837
  }
1838
+ async readdirRecursive(targetPath, options) {
1839
+ await this.ensureReady();
1840
+ return this.proxy.readdirRecursive(targetPath, options);
1841
+ }
1849
1842
  async stat(targetPath) {
1850
1843
  await this.ensureReady();
1851
1844
  return this.proxy.stat(targetPath);
@@ -1862,10 +1855,18 @@ class NativeKernel {
1862
1855
  await this.ensureReady();
1863
1856
  return this.proxy.removeDir(targetPath);
1864
1857
  }
1858
+ async removePath(targetPath, options) {
1859
+ await this.ensureReady();
1860
+ return this.proxy.removePath(targetPath, options);
1861
+ }
1865
1862
  async rename(oldPath, newPath) {
1866
1863
  await this.ensureReady();
1867
1864
  return this.proxy.rename(oldPath, newPath);
1868
1865
  }
1866
+ async movePath(oldPath, newPath) {
1867
+ await this.ensureReady();
1868
+ return this.proxy.movePath(oldPath, newPath);
1869
+ }
1869
1870
  tryResolveMountedCommand(command) {
1870
1871
  const normalized = normalizeCommandLookup(command);
1871
1872
  for (const driver of this.mountedRuntimeDrivers) {
@@ -1873,15 +1874,6 @@ class NativeKernel {
1873
1874
  continue;
1874
1875
  }
1875
1876
  this.commands.set(normalized, driver.kind);
1876
- if (driver.kind === "wasmvm" && this.proxy) {
1877
- const startIndex = this.runtimeDriverCommandDirStarts.get(driver);
1878
- if (startIndex !== undefined) {
1879
- const guestPaths = driver.getGuestCommandPaths?.(startIndex);
1880
- if (guestPaths?.has(normalized)) {
1881
- this.proxy.registerCommandGuestPaths(new Map([[normalized, guestPaths.get(normalized)]]));
1882
- }
1883
- }
1884
- }
1885
1877
  return true;
1886
1878
  }
1887
1879
  return false;
@@ -1916,7 +1908,7 @@ class NativeKernel {
1916
1908
  lowers: [
1917
1909
  {
1918
1910
  kind: "snapshot",
1919
- entries: rootFilesystemEntriesForConfig(mergeRootFilesystemEntries(createBootstrapEntries([...NODE_RUNTIME_BOOTSTRAP_COMMANDS]), snapshotEntries)),
1911
+ entries: rootFilesystemEntriesForConfig(mergeRootFilesystemEntries(createBootstrapEntries(), snapshotEntries)),
1920
1912
  },
1921
1913
  ],
1922
1914
  bootstrapEntries: [],
@@ -1935,6 +1927,7 @@ class NativeKernel {
1935
1927
  ? serializePermissionsForSidecar(bootstrapPermissions)
1936
1928
  : undefined,
1937
1929
  loopbackExemptPorts: this.loopbackExemptPorts,
1930
+ bootstrapCommands: [...NODE_RUNTIME_BOOTSTRAP_COMMANDS],
1938
1931
  };
1939
1932
  const vm = await client.createVm(session, {
1940
1933
  runtime: "java_script",
@@ -1954,41 +1947,34 @@ class NativeKernel {
1954
1947
  await materializeSnapshotEntriesIntoVm(client, session, vm, snapshotEntries);
1955
1948
  }
1956
1949
  if (rootPassthroughPlan.mounts.length > 0) {
1957
- this.pendingLocalMounts.push(...rootPassthroughPlan.mounts);
1950
+ this.pendingLocalMounts.push(...rootPassthroughPlan.mounts.map((mount) => makeLocalCompatMount({
1951
+ path: mount.path,
1952
+ fs: mount.fs,
1953
+ readOnly: mount.readOnly,
1954
+ })));
1958
1955
  }
1959
1956
  if (this.pendingLocalMounts.length > 0 ||
1960
1957
  this.loopbackExemptPorts.length > 0 ||
1961
1958
  requestedPermissions) {
1959
+ const sidecarMounts = this.pendingLocalMounts.map((mount) => serializeLocalCompatMountForSidecar(mount));
1962
1960
  await client.configureVm(session, vm, {
1963
- mounts: this.pendingLocalMounts.map((mount) => mount.fs instanceof NodeFileSystem
1964
- ? serializeMountConfigForSidecar({
1965
- path: mount.path,
1966
- readOnly: mount.readOnly,
1967
- plugin: {
1968
- id: "host_dir",
1969
- config: {
1970
- hostPath: mount.fs.rootPath,
1971
- readOnly: mount.readOnly,
1972
- },
1973
- },
1974
- })
1975
- : serializeMountConfigForSidecar({
1976
- path: mount.path,
1977
- driver: mount.fs,
1978
- readOnly: mount.readOnly,
1979
- })),
1961
+ mounts: sidecarMounts,
1980
1962
  permissions: requestedPermissions,
1981
1963
  loopbackExemptPorts: this.loopbackExemptPorts,
1982
1964
  });
1983
1965
  }
1966
+ const configuredSidecarMounts = this.pendingLocalMounts.map((mount) => serializeLocalCompatMountForSidecar(mount));
1984
1967
  const proxy = new NativeSidecarKernelProxy({
1985
1968
  client,
1986
1969
  session,
1987
1970
  vm,
1988
1971
  env: this.env,
1989
1972
  cwd: this.cwd,
1990
- defaultExecCwd: this.options.cwd === undefined ? "/home/user" : this.cwd,
1973
+ defaultExecCwd: this.options.cwd === undefined ? "/workspace" : this.cwd,
1991
1974
  localMounts: this.pendingLocalMounts,
1975
+ sidecarMounts: configuredSidecarMounts,
1976
+ permissions: requestedPermissions,
1977
+ loopbackExemptPorts: this.loopbackExemptPorts,
1992
1978
  commandGuestPaths: new Map(),
1993
1979
  onWasmCommandResolved: (command) => {
1994
1980
  this.recordModuleExecution(command);
package/dist/runtime.d.ts CHANGED
@@ -76,7 +76,7 @@ export type NetworkPermissions = PermissionMode | RulePermissions<PatternPermiss
76
76
  export type ChildProcessPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
77
77
  export type ProcessPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
78
78
  export type EnvPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
79
- export type ToolPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
79
+ export type BindingPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
80
80
  export interface ProcessInfo {
81
81
  pid: number;
82
82
  ppid: number;
@@ -93,15 +93,15 @@ export interface ProcessInfo {
93
93
  }
94
94
  export interface ManagedProcess {
95
95
  pid: number;
96
- writeStdin(data: Uint8Array | string): void;
97
- closeStdin(): void;
96
+ writeStdin(data: Uint8Array | string): Promise<void>;
97
+ closeStdin(): Promise<void>;
98
98
  kill(signal?: number): void;
99
99
  wait(): Promise<number>;
100
100
  readonly exitCode: number | null;
101
101
  }
102
102
  export interface ShellHandle {
103
103
  pid: number;
104
- write(data: Uint8Array | string): void;
104
+ write(data: Uint8Array | string): Promise<void>;
105
105
  onData: ((data: Uint8Array) => void) | null;
106
106
  resize(cols: number, rows: number): void;
107
107
  kill(signal?: number): void;
@@ -163,7 +163,7 @@ export interface Permissions {
163
163
  childProcess?: ChildProcessPermissions;
164
164
  process?: ProcessPermissions;
165
165
  env?: EnvPermissions;
166
- tool?: ToolPermissions;
166
+ binding?: BindingPermissions;
167
167
  }
168
168
  export interface ResourceBudgets {
169
169
  maxOutputBytes?: number;
@@ -224,6 +224,7 @@ export interface SystemDriver {
224
224
  network?: NetworkAdapter;
225
225
  commandExecutor?: CommandExecutor;
226
226
  permissions?: Permissions;
227
+ mounts: readonly NodeModulesMountConfig[];
227
228
  runtime: {
228
229
  process: ProcessConfig;
229
230
  os: OSConfig;
@@ -258,6 +259,13 @@ export interface NodeRuntimeDriverFactory {
258
259
  export interface KernelInterface {
259
260
  vfs: VirtualFileSystem;
260
261
  }
262
+ export interface KernelRecursiveDirEntry {
263
+ name: string;
264
+ path: string;
265
+ isDirectory: boolean;
266
+ isSymbolicLink: boolean;
267
+ size: number;
268
+ }
261
269
  export interface Kernel extends KernelInterface {
262
270
  mount(driver: KernelRuntimeDriver): Promise<void>;
263
271
  dispose(): Promise<void>;
@@ -273,11 +281,18 @@ export interface Kernel extends KernelInterface {
273
281
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
274
282
  mkdir(path: string): Promise<void>;
275
283
  readdir(path: string): Promise<string[]>;
284
+ readdirRecursive(path: string, options?: {
285
+ maxDepth?: number;
286
+ }): Promise<KernelRecursiveDirEntry[]>;
276
287
  stat(path: string): Promise<VirtualStat>;
277
288
  exists(path: string): Promise<boolean>;
278
289
  removeFile(path: string): Promise<void>;
279
290
  removeDir(path: string): Promise<void>;
291
+ removePath(path: string, options?: {
292
+ recursive?: boolean;
293
+ }): Promise<void>;
280
294
  rename(oldPath: string, newPath: string): Promise<void>;
295
+ movePath(oldPath: string, newPath: string): Promise<void>;
281
296
  readonly commands: ReadonlyMap<string, string>;
282
297
  readonly processes: ReadonlyMap<number, ProcessInfo>;
283
298
  readonly env: Record<string, string>;
@@ -299,11 +314,23 @@ export interface BindingTree {
299
314
  [key: string]: BindingFunction | BindingTree;
300
315
  }
301
316
  export type BindingFunction = (...args: unknown[]) => unknown;
317
+ export interface NodeModulesMountConfig {
318
+ path: string;
319
+ plugin: {
320
+ id: "host_dir";
321
+ config: {
322
+ hostPath: string;
323
+ readOnly: boolean;
324
+ };
325
+ };
326
+ readOnly: boolean;
327
+ }
302
328
  export interface NodeDriverOptions {
303
329
  filesystem?: VirtualFileSystem;
304
330
  networkAdapter?: NetworkAdapter;
305
331
  commandExecutor?: CommandExecutor;
306
332
  permissions?: Permissions;
333
+ mounts?: readonly NodeModulesMountConfig[];
307
334
  processConfig?: ProcessConfig;
308
335
  osConfig?: OSConfig;
309
336
  }