@rivet-dev/agentos-core 0.0.0-feat-on-limit-warning.62a2bc2 → 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.
- package/README.md +4 -7
- package/dist/agent-os.d.ts +116 -46
- package/dist/agent-os.js +740 -541
- package/dist/agentos-package.d.ts +29 -0
- package/dist/agentos-package.js +88 -0
- package/dist/base-filesystem.d.ts +2 -15
- package/dist/base-filesystem.js +23 -171
- package/dist/cron/types.d.ts +1 -1
- package/dist/default-software.d.ts +8 -0
- package/dist/default-software.js +10 -0
- package/dist/generated/AcpLimitsConfig.d.ts +4 -0
- package/dist/generated/AcpLimitsConfig.js +2 -0
- package/dist/generated/CreateVmConfig.d.ts +26 -0
- package/dist/generated/CreateVmConfig.js +1 -0
- package/dist/generated/FsPermissionRule.d.ts +6 -0
- package/dist/generated/FsPermissionRule.js +1 -0
- package/dist/generated/FsPermissionRuleSet.d.ts +6 -0
- package/dist/generated/FsPermissionRuleSet.js +1 -0
- package/dist/generated/FsPermissionScope.d.ts +3 -0
- package/dist/generated/FsPermissionScope.js +1 -0
- package/dist/generated/HttpLimitsConfig.d.ts +3 -0
- package/dist/generated/HttpLimitsConfig.js +2 -0
- package/dist/generated/JsModuleResolution.d.ts +1 -0
- package/dist/generated/JsModuleResolution.js +2 -0
- package/dist/generated/JsRuntimeConfig.d.ts +31 -0
- package/dist/generated/JsRuntimeConfig.js +1 -0
- package/dist/generated/JsRuntimeLimitsConfig.d.ts +11 -0
- package/dist/generated/JsRuntimeLimitsConfig.js +2 -0
- package/dist/generated/JsRuntimePlatform.d.ts +1 -0
- package/dist/generated/JsRuntimePlatform.js +2 -0
- package/dist/generated/MountPluginDescriptor.d.ts +4 -0
- package/dist/generated/MountPluginDescriptor.js +2 -0
- package/dist/generated/NativeRootFilesystemConfig.d.ts +5 -0
- package/dist/generated/NativeRootFilesystemConfig.js +1 -0
- package/dist/generated/PatternPermissionRule.d.ts +6 -0
- package/dist/generated/PatternPermissionRule.js +1 -0
- package/dist/generated/PatternPermissionRuleSet.d.ts +6 -0
- package/dist/generated/PatternPermissionRuleSet.js +1 -0
- package/dist/generated/PatternPermissionScope.d.ts +3 -0
- package/dist/generated/PatternPermissionScope.js +1 -0
- package/dist/generated/PermissionMode.d.ts +1 -0
- package/dist/generated/PermissionMode.js +2 -0
- package/dist/generated/PermissionsPolicy.d.ts +10 -0
- package/dist/generated/PermissionsPolicy.js +1 -0
- package/dist/generated/PluginLimitsConfig.d.ts +4 -0
- package/dist/generated/PluginLimitsConfig.js +2 -0
- package/dist/generated/PythonLimitsConfig.d.ts +6 -0
- package/dist/generated/PythonLimitsConfig.js +2 -0
- package/dist/generated/ResourceLimitsConfig.d.ts +24 -0
- package/dist/generated/ResourceLimitsConfig.js +2 -0
- package/dist/generated/RootFilesystemConfig.d.ts +9 -0
- package/dist/generated/RootFilesystemConfig.js +1 -0
- package/dist/generated/RootFilesystemEntry.d.ts +13 -0
- package/dist/generated/RootFilesystemEntry.js +1 -0
- package/dist/generated/RootFilesystemEntryEncoding.d.ts +1 -0
- package/dist/generated/RootFilesystemEntryEncoding.js +2 -0
- package/dist/generated/RootFilesystemEntryKind.d.ts +1 -0
- package/dist/generated/RootFilesystemEntryKind.js +2 -0
- package/dist/generated/RootFilesystemLowerDescriptor.d.ts +7 -0
- package/dist/generated/RootFilesystemLowerDescriptor.js +1 -0
- package/dist/generated/RootFilesystemMode.d.ts +1 -0
- package/dist/generated/RootFilesystemMode.js +2 -0
- package/dist/generated/ToolLimitsConfig.d.ts +10 -0
- package/dist/generated/ToolLimitsConfig.js +2 -0
- package/dist/generated/VmDnsConfig.d.ts +6 -0
- package/dist/generated/VmDnsConfig.js +2 -0
- package/dist/generated/VmLimitsConfig.d.ts +18 -0
- package/dist/generated/VmLimitsConfig.js +1 -0
- package/dist/generated/VmListenPolicyConfig.d.ts +5 -0
- package/dist/generated/VmListenPolicyConfig.js +2 -0
- package/dist/generated/WasmLimitsConfig.d.ts +7 -0
- package/dist/generated/WasmLimitsConfig.js +2 -0
- package/dist/host-dir-mount.d.ts +1 -1
- package/dist/host-tools.js +9 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/layers.d.ts +2 -2
- package/dist/layers.js +19 -10
- package/dist/options-schema.d.ts +19 -4
- package/dist/options-schema.js +30 -22
- package/dist/packages.d.ts +17 -116
- package/dist/packages.js +35 -322
- package/dist/runtime-compat.d.ts +22 -9
- package/dist/runtime-compat.js +126 -141
- package/dist/runtime.d.ts +32 -5
- package/dist/sandbox.d.ts +112 -0
- package/dist/sandbox.js +264 -0
- package/dist/sidecar/agentos-protocol.d.ts +88 -1
- package/dist/sidecar/agentos-protocol.js +134 -18
- package/dist/sidecar/native-process-client.d.ts +6 -3
- package/dist/sidecar/native-process-client.js +5 -3
- package/dist/sidecar/permissions.d.ts +1 -1
- package/dist/sidecar/permissions.js +3 -3
- package/dist/sidecar/rpc-client.d.ts +62 -4
- package/dist/sidecar/rpc-client.js +339 -85
- package/dist/types.d.ts +10 -3
- package/package.json +36 -32
- package/dist/agents.d.ts +0 -63
- package/dist/agents.js +0 -42
- package/fixtures/AGENTOS_SYSTEM_PROMPT.md +0 -21
package/dist/runtime-compat.js
CHANGED
|
@@ -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
|
|
21
|
-
|
|
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",
|
|
@@ -119,7 +124,7 @@ export class InMemoryFileSystem {
|
|
|
119
124
|
throw errnoError("ENOENT", `open '${targetPath}'`);
|
|
120
125
|
}
|
|
121
126
|
entry.atimeMs = Date.now();
|
|
122
|
-
return entry.data;
|
|
127
|
+
return new Uint8Array(entry.data);
|
|
123
128
|
}
|
|
124
129
|
async readTextFile(targetPath) {
|
|
125
130
|
return new TextDecoder().decode(await this.readFile(targetPath));
|
|
@@ -152,7 +157,9 @@ export class InMemoryFileSystem {
|
|
|
152
157
|
async writeFile(targetPath, content) {
|
|
153
158
|
const normalized = normalizePath(targetPath);
|
|
154
159
|
await this.mkdir(dirnameVirtual(normalized), { recursive: true });
|
|
155
|
-
const data = typeof content === "string"
|
|
160
|
+
const data = typeof content === "string"
|
|
161
|
+
? new TextEncoder().encode(content)
|
|
162
|
+
: new Uint8Array(content);
|
|
156
163
|
const existing = this.entries.get(normalized);
|
|
157
164
|
if (existing?.type === "file") {
|
|
158
165
|
existing.data = data;
|
|
@@ -212,7 +219,7 @@ export class InMemoryFileSystem {
|
|
|
212
219
|
return this.toStat(entry);
|
|
213
220
|
}
|
|
214
221
|
async removeFile(targetPath) {
|
|
215
|
-
const resolved =
|
|
222
|
+
const resolved = normalizePath(targetPath);
|
|
216
223
|
const entry = this.entries.get(resolved);
|
|
217
224
|
if (!entry || entry.type === "dir") {
|
|
218
225
|
throw errnoError("ENOENT", `unlink '${targetPath}'`);
|
|
@@ -374,7 +381,7 @@ export class InMemoryFileSystem {
|
|
|
374
381
|
const nextSize = Math.max(entry.data.length, offset + data.length);
|
|
375
382
|
const updated = new Uint8Array(nextSize);
|
|
376
383
|
updated.set(entry.data);
|
|
377
|
-
updated.set(data, offset);
|
|
384
|
+
updated.set(new Uint8Array(data), offset);
|
|
378
385
|
entry.data = updated;
|
|
379
386
|
entry.mtimeMs = Date.now();
|
|
380
387
|
entry.ctimeMs = Date.now();
|
|
@@ -730,6 +737,7 @@ export function createNodeDriver(options = {}) {
|
|
|
730
737
|
network: options.networkAdapter,
|
|
731
738
|
commandExecutor: options.commandExecutor,
|
|
732
739
|
permissions: options.permissions,
|
|
740
|
+
mounts: options.mounts ?? [],
|
|
733
741
|
runtime: {
|
|
734
742
|
process: options.processConfig ?? {},
|
|
735
743
|
os: options.osConfig ?? {},
|
|
@@ -817,7 +825,6 @@ export const WASMVM_COMMANDS = Object.freeze([
|
|
|
817
825
|
"sqlite3",
|
|
818
826
|
"curl",
|
|
819
827
|
"wget",
|
|
820
|
-
"make",
|
|
821
828
|
"git",
|
|
822
829
|
"git-remote-http",
|
|
823
830
|
"git-remote-https",
|
|
@@ -916,7 +923,6 @@ export const DEFAULT_FIRST_PARTY_TIERS = Object.freeze({
|
|
|
916
923
|
nice: "full",
|
|
917
924
|
nohup: "full",
|
|
918
925
|
stdbuf: "full",
|
|
919
|
-
make: "full",
|
|
920
926
|
codex: "full",
|
|
921
927
|
"codex-exec": "full",
|
|
922
928
|
git: "full",
|
|
@@ -1016,7 +1022,7 @@ function isWasmBinaryFile(filePath) {
|
|
|
1016
1022
|
function discoverWasmCommandEntries(commandDirs) {
|
|
1017
1023
|
const discovered = [];
|
|
1018
1024
|
const seen = new Set();
|
|
1019
|
-
|
|
1025
|
+
for (const commandDir of commandDirs) {
|
|
1020
1026
|
let entries;
|
|
1021
1027
|
try {
|
|
1022
1028
|
entries = fsSync
|
|
@@ -1024,7 +1030,7 @@ function discoverWasmCommandEntries(commandDirs) {
|
|
|
1024
1030
|
.sort((left, right) => left.localeCompare(right));
|
|
1025
1031
|
}
|
|
1026
1032
|
catch {
|
|
1027
|
-
|
|
1033
|
+
continue;
|
|
1028
1034
|
}
|
|
1029
1035
|
for (const entry of entries) {
|
|
1030
1036
|
if (entry.startsWith("."))
|
|
@@ -1037,7 +1043,6 @@ function discoverWasmCommandEntries(commandDirs) {
|
|
|
1037
1043
|
discovered.push({
|
|
1038
1044
|
name: entry,
|
|
1039
1045
|
hostPath: fullPath,
|
|
1040
|
-
dirOffset,
|
|
1041
1046
|
});
|
|
1042
1047
|
continue;
|
|
1043
1048
|
}
|
|
@@ -1048,13 +1053,12 @@ function discoverWasmCommandEntries(commandDirs) {
|
|
|
1048
1053
|
discovered.push({
|
|
1049
1054
|
name: entry,
|
|
1050
1055
|
hostPath: fullPath,
|
|
1051
|
-
dirOffset,
|
|
1052
1056
|
});
|
|
1053
1057
|
}
|
|
1054
1058
|
}
|
|
1055
1059
|
catch { }
|
|
1056
1060
|
}
|
|
1057
|
-
}
|
|
1061
|
+
}
|
|
1058
1062
|
return discovered;
|
|
1059
1063
|
}
|
|
1060
1064
|
class WasmVmRuntimeDescriptor {
|
|
@@ -1064,7 +1068,6 @@ class WasmVmRuntimeDescriptor {
|
|
|
1064
1068
|
commandDirs;
|
|
1065
1069
|
_commandPaths = new Map();
|
|
1066
1070
|
_moduleCache = new Map();
|
|
1067
|
-
commandDirOffsets = new Map();
|
|
1068
1071
|
constructor(options) {
|
|
1069
1072
|
this.commandDirs =
|
|
1070
1073
|
options.commandDirs && options.commandDirs.length > 0
|
|
@@ -1095,17 +1098,6 @@ class WasmVmRuntimeDescriptor {
|
|
|
1095
1098
|
this.refreshDiscovery();
|
|
1096
1099
|
return this._commandPaths.has(normalized);
|
|
1097
1100
|
}
|
|
1098
|
-
getGuestCommandPaths(startIndex) {
|
|
1099
|
-
const guestPaths = new Map();
|
|
1100
|
-
for (const [name] of this._commandPaths) {
|
|
1101
|
-
const dirOffset = this.commandDirOffsets.get(name);
|
|
1102
|
-
if (dirOffset === undefined) {
|
|
1103
|
-
continue;
|
|
1104
|
-
}
|
|
1105
|
-
guestPaths.set(name, `/__secure_exec/commands/${startIndex + dirOffset}/${name}`);
|
|
1106
|
-
}
|
|
1107
|
-
return guestPaths;
|
|
1108
|
-
}
|
|
1109
1101
|
recordModuleExecution(command) {
|
|
1110
1102
|
const normalized = normalizeCommandLookup(command);
|
|
1111
1103
|
if (this._commandPaths.has(normalized) ||
|
|
@@ -1121,11 +1113,9 @@ class WasmVmRuntimeDescriptor {
|
|
|
1121
1113
|
const discovered = discoverWasmCommandEntries(this.commandDirs);
|
|
1122
1114
|
this.commands.length = 0;
|
|
1123
1115
|
this._commandPaths.clear();
|
|
1124
|
-
this.commandDirOffsets.clear();
|
|
1125
1116
|
for (const entry of discovered) {
|
|
1126
1117
|
this.commands.push(entry.name);
|
|
1127
1118
|
this._commandPaths.set(entry.name, entry.hostPath);
|
|
1128
|
-
this.commandDirOffsets.set(entry.name, entry.dirOffset);
|
|
1129
1119
|
}
|
|
1130
1120
|
}
|
|
1131
1121
|
}
|
|
@@ -1191,8 +1181,8 @@ function ensureNativeSidecarBinary() {
|
|
|
1191
1181
|
function rootEntryExecutable(kind, mode) {
|
|
1192
1182
|
return kind === "file" && (mode & 0o111) !== 0;
|
|
1193
1183
|
}
|
|
1194
|
-
function createBootstrapEntries(
|
|
1195
|
-
|
|
1184
|
+
function createBootstrapEntries() {
|
|
1185
|
+
return [
|
|
1196
1186
|
{
|
|
1197
1187
|
path: "/",
|
|
1198
1188
|
kind: "directory",
|
|
@@ -1220,19 +1210,6 @@ function createBootstrapEntries(commandNames) {
|
|
|
1220
1210
|
executable: false,
|
|
1221
1211
|
},
|
|
1222
1212
|
];
|
|
1223
|
-
for (const command of [...new Set(commandNames)].sort((left, right) => left.localeCompare(right))) {
|
|
1224
|
-
entries.push({
|
|
1225
|
-
path: `/bin/${command}`,
|
|
1226
|
-
kind: "file",
|
|
1227
|
-
mode: 0o755,
|
|
1228
|
-
uid: 0,
|
|
1229
|
-
gid: 0,
|
|
1230
|
-
content: KERNEL_COMMAND_STUB,
|
|
1231
|
-
encoding: "utf8",
|
|
1232
|
-
executable: true,
|
|
1233
|
-
});
|
|
1234
|
-
}
|
|
1235
|
-
return entries;
|
|
1236
1213
|
}
|
|
1237
1214
|
function mergeRootFilesystemEntries(baseEntries, overrideEntries) {
|
|
1238
1215
|
const merged = new Map();
|
|
@@ -1373,23 +1350,6 @@ function planNodeFilesystemPassthroughMounts(filesystem, existingMounts) {
|
|
|
1373
1350
|
passthroughDirectories,
|
|
1374
1351
|
};
|
|
1375
1352
|
}
|
|
1376
|
-
function collectGuestCommandPaths(commandDirs, startIndex = 0) {
|
|
1377
|
-
const guestPaths = new Map();
|
|
1378
|
-
for (const entry of discoverWasmCommandEntries(commandDirs)) {
|
|
1379
|
-
if (!guestPaths.has(entry.name)) {
|
|
1380
|
-
guestPaths.set(entry.name, `/__secure_exec/commands/${startIndex + entry.dirOffset}/${entry.name}`);
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
return guestPaths;
|
|
1384
|
-
}
|
|
1385
|
-
async function ensureCommandStubs(proxy, commands) {
|
|
1386
|
-
const rootView = proxy.createRootView();
|
|
1387
|
-
for (const command of commands) {
|
|
1388
|
-
const stubPath = `/bin/${command}`;
|
|
1389
|
-
await rootView.writeFile(stubPath, KERNEL_COMMAND_STUB);
|
|
1390
|
-
await rootView.chmod(stubPath, 0o755);
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
1353
|
class DeferredFileSystem {
|
|
1394
1354
|
getFilesystem;
|
|
1395
1355
|
constructor(getFilesystem) {
|
|
@@ -1607,6 +1567,35 @@ function bindLiveFilesystem(target, getFilesystem) {
|
|
|
1607
1567
|
},
|
|
1608
1568
|
};
|
|
1609
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
|
+
}
|
|
1610
1599
|
class NativeKernel {
|
|
1611
1600
|
options;
|
|
1612
1601
|
env;
|
|
@@ -1628,7 +1617,6 @@ class NativeKernel {
|
|
|
1628
1617
|
pendingLocalMounts = [];
|
|
1629
1618
|
mountedCommandDirs = [];
|
|
1630
1619
|
mountedRuntimeDrivers = [];
|
|
1631
|
-
runtimeDriverCommandDirStarts = new Map();
|
|
1632
1620
|
loopbackExemptPorts;
|
|
1633
1621
|
constructor(options) {
|
|
1634
1622
|
this.options = options;
|
|
@@ -1646,11 +1634,11 @@ class NativeKernel {
|
|
|
1646
1634
|
};
|
|
1647
1635
|
this.loopbackExemptPorts = [...(options.loopbackExemptPorts ?? [])];
|
|
1648
1636
|
for (const mount of options.mounts ?? []) {
|
|
1649
|
-
this.pendingLocalMounts.push({
|
|
1650
|
-
path:
|
|
1637
|
+
this.pendingLocalMounts.push(makeLocalCompatMount({
|
|
1638
|
+
path: mount.path,
|
|
1651
1639
|
fs: mount.fs,
|
|
1652
|
-
readOnly: mount.readOnly
|
|
1653
|
-
});
|
|
1640
|
+
readOnly: mount.readOnly,
|
|
1641
|
+
}));
|
|
1654
1642
|
}
|
|
1655
1643
|
this.vfs = new DeferredFileSystem(() => this.rootFilesystem);
|
|
1656
1644
|
this.liveFilesystemBinding = bindLiveFilesystem(this.options.filesystem, () => this.rootFilesystem);
|
|
@@ -1658,6 +1646,32 @@ class NativeKernel {
|
|
|
1658
1646
|
get zombieTimerCount() {
|
|
1659
1647
|
return this.proxy?.zombieTimerCount ?? 0;
|
|
1660
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
|
+
}
|
|
1661
1675
|
async mount(driver) {
|
|
1662
1676
|
await this.ensureReady();
|
|
1663
1677
|
if (!this.proxy || !this.client || !this.session || !this.vm) {
|
|
@@ -1669,7 +1683,7 @@ class NativeKernel {
|
|
|
1669
1683
|
this.commands.set(command, "node");
|
|
1670
1684
|
}
|
|
1671
1685
|
this.mountedRuntimeDrivers.push(driver);
|
|
1672
|
-
await
|
|
1686
|
+
await this.configureRuntimeCommandStubs(driver.commands);
|
|
1673
1687
|
return;
|
|
1674
1688
|
}
|
|
1675
1689
|
const commandDirs = driver.commandDirs ?? [];
|
|
@@ -1678,53 +1692,17 @@ class NativeKernel {
|
|
|
1678
1692
|
this.commands.set(command, "wasmvm");
|
|
1679
1693
|
}
|
|
1680
1694
|
this.mountedRuntimeDrivers.push(driver);
|
|
1681
|
-
await
|
|
1695
|
+
await this.configureRuntimeCommandStubs(driver.commands);
|
|
1682
1696
|
return;
|
|
1683
1697
|
}
|
|
1684
|
-
const startIndex = this.mountedCommandDirs.length;
|
|
1685
|
-
const newGuestPaths = driver.getGuestCommandPaths?.(startIndex) ??
|
|
1686
|
-
collectGuestCommandPaths(commandDirs, startIndex);
|
|
1687
1698
|
const allCommandDirs = [...this.mountedCommandDirs, ...commandDirs];
|
|
1688
|
-
const
|
|
1689
|
-
|
|
1690
|
-
readOnly: true,
|
|
1691
|
-
plugin: {
|
|
1692
|
-
id: "host_dir",
|
|
1693
|
-
config: {
|
|
1694
|
-
hostPath: commandDir,
|
|
1695
|
-
readOnly: true,
|
|
1696
|
-
},
|
|
1697
|
-
},
|
|
1698
|
-
}));
|
|
1699
|
-
const localMounts = this.pendingLocalMounts.map((mount) => mount.fs instanceof NodeFileSystem
|
|
1700
|
-
? serializeMountConfigForSidecar({
|
|
1701
|
-
path: mount.path,
|
|
1702
|
-
readOnly: mount.readOnly,
|
|
1703
|
-
plugin: {
|
|
1704
|
-
id: "host_dir",
|
|
1705
|
-
config: {
|
|
1706
|
-
hostPath: mount.fs.rootPath,
|
|
1707
|
-
readOnly: mount.readOnly,
|
|
1708
|
-
},
|
|
1709
|
-
},
|
|
1710
|
-
})
|
|
1711
|
-
: serializeMountConfigForSidecar({
|
|
1712
|
-
path: mount.path,
|
|
1713
|
-
driver: mount.fs,
|
|
1714
|
-
readOnly: mount.readOnly,
|
|
1715
|
-
}));
|
|
1716
|
-
await this.client.configureVm(this.session, this.vm, {
|
|
1717
|
-
mounts: [...localMounts, ...sidecarMounts],
|
|
1718
|
-
loopbackExemptPorts: this.loopbackExemptPorts,
|
|
1719
|
-
});
|
|
1720
|
-
this.proxy.registerCommandGuestPaths(newGuestPaths);
|
|
1699
|
+
const projectedCommands = await this.configureRuntimeCommandStubs(driver.commands, allCommandDirs);
|
|
1700
|
+
this.proxy.registerCommandGuestPaths(projectedCommands);
|
|
1721
1701
|
this.mountedCommandDirs.push(...commandDirs);
|
|
1722
1702
|
this.mountedRuntimeDrivers.push(driver);
|
|
1723
|
-
|
|
1724
|
-
for (const command of newGuestPaths.keys()) {
|
|
1703
|
+
for (const command of projectedCommands.keys()) {
|
|
1725
1704
|
this.commands.set(command, "wasmvm");
|
|
1726
1705
|
}
|
|
1727
|
-
await ensureCommandStubs(this.proxy, newGuestPaths.keys());
|
|
1728
1706
|
}
|
|
1729
1707
|
async dispose() {
|
|
1730
1708
|
await this.readyPromise?.catch(() => { });
|
|
@@ -1785,10 +1763,10 @@ class NativeKernel {
|
|
|
1785
1763
|
return {
|
|
1786
1764
|
pid: proc.pid,
|
|
1787
1765
|
writeStdin(data) {
|
|
1788
|
-
proc.writeStdin(data);
|
|
1766
|
+
return proc.writeStdin(data);
|
|
1789
1767
|
},
|
|
1790
1768
|
closeStdin() {
|
|
1791
|
-
proc.closeStdin();
|
|
1769
|
+
return proc.closeStdin();
|
|
1792
1770
|
},
|
|
1793
1771
|
kill(signal) {
|
|
1794
1772
|
proc.kill(signal);
|
|
@@ -1818,17 +1796,27 @@ class NativeKernel {
|
|
|
1818
1796
|
return this.proxy.connectTerminal(options);
|
|
1819
1797
|
}
|
|
1820
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);
|
|
1821
1806
|
if (!this.proxy) {
|
|
1822
|
-
this.pendingLocalMounts.push({
|
|
1823
|
-
path: normalizePath(mountPath),
|
|
1824
|
-
fs: filesystem,
|
|
1825
|
-
readOnly: options?.readOnly ?? false,
|
|
1826
|
-
});
|
|
1827
1807
|
return;
|
|
1828
1808
|
}
|
|
1829
|
-
this.proxy.mountFs(mountPath, filesystem,
|
|
1809
|
+
this.proxy.mountFs(mountPath, filesystem, {
|
|
1810
|
+
readOnly: localMount.readOnly,
|
|
1811
|
+
sidecarMount: localMount.sidecarMount,
|
|
1812
|
+
});
|
|
1830
1813
|
}
|
|
1831
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
|
+
}
|
|
1832
1820
|
this.proxy?.unmountFs(mountPath);
|
|
1833
1821
|
}
|
|
1834
1822
|
async readFile(targetPath) {
|
|
@@ -1847,6 +1835,10 @@ class NativeKernel {
|
|
|
1847
1835
|
await this.ensureReady();
|
|
1848
1836
|
return this.proxy.readdir(targetPath);
|
|
1849
1837
|
}
|
|
1838
|
+
async readdirRecursive(targetPath, options) {
|
|
1839
|
+
await this.ensureReady();
|
|
1840
|
+
return this.proxy.readdirRecursive(targetPath, options);
|
|
1841
|
+
}
|
|
1850
1842
|
async stat(targetPath) {
|
|
1851
1843
|
await this.ensureReady();
|
|
1852
1844
|
return this.proxy.stat(targetPath);
|
|
@@ -1863,10 +1855,18 @@ class NativeKernel {
|
|
|
1863
1855
|
await this.ensureReady();
|
|
1864
1856
|
return this.proxy.removeDir(targetPath);
|
|
1865
1857
|
}
|
|
1858
|
+
async removePath(targetPath, options) {
|
|
1859
|
+
await this.ensureReady();
|
|
1860
|
+
return this.proxy.removePath(targetPath, options);
|
|
1861
|
+
}
|
|
1866
1862
|
async rename(oldPath, newPath) {
|
|
1867
1863
|
await this.ensureReady();
|
|
1868
1864
|
return this.proxy.rename(oldPath, newPath);
|
|
1869
1865
|
}
|
|
1866
|
+
async movePath(oldPath, newPath) {
|
|
1867
|
+
await this.ensureReady();
|
|
1868
|
+
return this.proxy.movePath(oldPath, newPath);
|
|
1869
|
+
}
|
|
1870
1870
|
tryResolveMountedCommand(command) {
|
|
1871
1871
|
const normalized = normalizeCommandLookup(command);
|
|
1872
1872
|
for (const driver of this.mountedRuntimeDrivers) {
|
|
@@ -1874,15 +1874,6 @@ class NativeKernel {
|
|
|
1874
1874
|
continue;
|
|
1875
1875
|
}
|
|
1876
1876
|
this.commands.set(normalized, driver.kind);
|
|
1877
|
-
if (driver.kind === "wasmvm" && this.proxy) {
|
|
1878
|
-
const startIndex = this.runtimeDriverCommandDirStarts.get(driver);
|
|
1879
|
-
if (startIndex !== undefined) {
|
|
1880
|
-
const guestPaths = driver.getGuestCommandPaths?.(startIndex);
|
|
1881
|
-
if (guestPaths?.has(normalized)) {
|
|
1882
|
-
this.proxy.registerCommandGuestPaths(new Map([[normalized, guestPaths.get(normalized)]]));
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
1877
|
return true;
|
|
1887
1878
|
}
|
|
1888
1879
|
return false;
|
|
@@ -1917,7 +1908,7 @@ class NativeKernel {
|
|
|
1917
1908
|
lowers: [
|
|
1918
1909
|
{
|
|
1919
1910
|
kind: "snapshot",
|
|
1920
|
-
entries: rootFilesystemEntriesForConfig(mergeRootFilesystemEntries(createBootstrapEntries(
|
|
1911
|
+
entries: rootFilesystemEntriesForConfig(mergeRootFilesystemEntries(createBootstrapEntries(), snapshotEntries)),
|
|
1921
1912
|
},
|
|
1922
1913
|
],
|
|
1923
1914
|
bootstrapEntries: [],
|
|
@@ -1936,6 +1927,7 @@ class NativeKernel {
|
|
|
1936
1927
|
? serializePermissionsForSidecar(bootstrapPermissions)
|
|
1937
1928
|
: undefined,
|
|
1938
1929
|
loopbackExemptPorts: this.loopbackExemptPorts,
|
|
1930
|
+
bootstrapCommands: [...NODE_RUNTIME_BOOTSTRAP_COMMANDS],
|
|
1939
1931
|
};
|
|
1940
1932
|
const vm = await client.createVm(session, {
|
|
1941
1933
|
runtime: "java_script",
|
|
@@ -1955,33 +1947,23 @@ class NativeKernel {
|
|
|
1955
1947
|
await materializeSnapshotEntriesIntoVm(client, session, vm, snapshotEntries);
|
|
1956
1948
|
}
|
|
1957
1949
|
if (rootPassthroughPlan.mounts.length > 0) {
|
|
1958
|
-
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
|
+
})));
|
|
1959
1955
|
}
|
|
1960
1956
|
if (this.pendingLocalMounts.length > 0 ||
|
|
1961
1957
|
this.loopbackExemptPorts.length > 0 ||
|
|
1962
1958
|
requestedPermissions) {
|
|
1959
|
+
const sidecarMounts = this.pendingLocalMounts.map((mount) => serializeLocalCompatMountForSidecar(mount));
|
|
1963
1960
|
await client.configureVm(session, vm, {
|
|
1964
|
-
mounts:
|
|
1965
|
-
? serializeMountConfigForSidecar({
|
|
1966
|
-
path: mount.path,
|
|
1967
|
-
readOnly: mount.readOnly,
|
|
1968
|
-
plugin: {
|
|
1969
|
-
id: "host_dir",
|
|
1970
|
-
config: {
|
|
1971
|
-
hostPath: mount.fs.rootPath,
|
|
1972
|
-
readOnly: mount.readOnly,
|
|
1973
|
-
},
|
|
1974
|
-
},
|
|
1975
|
-
})
|
|
1976
|
-
: serializeMountConfigForSidecar({
|
|
1977
|
-
path: mount.path,
|
|
1978
|
-
driver: mount.fs,
|
|
1979
|
-
readOnly: mount.readOnly,
|
|
1980
|
-
})),
|
|
1961
|
+
mounts: sidecarMounts,
|
|
1981
1962
|
permissions: requestedPermissions,
|
|
1982
1963
|
loopbackExemptPorts: this.loopbackExemptPorts,
|
|
1983
1964
|
});
|
|
1984
1965
|
}
|
|
1966
|
+
const configuredSidecarMounts = this.pendingLocalMounts.map((mount) => serializeLocalCompatMountForSidecar(mount));
|
|
1985
1967
|
const proxy = new NativeSidecarKernelProxy({
|
|
1986
1968
|
client,
|
|
1987
1969
|
session,
|
|
@@ -1990,6 +1972,9 @@ class NativeKernel {
|
|
|
1990
1972
|
cwd: this.cwd,
|
|
1991
1973
|
defaultExecCwd: this.options.cwd === undefined ? "/workspace" : this.cwd,
|
|
1992
1974
|
localMounts: this.pendingLocalMounts,
|
|
1975
|
+
sidecarMounts: configuredSidecarMounts,
|
|
1976
|
+
permissions: requestedPermissions,
|
|
1977
|
+
loopbackExemptPorts: this.loopbackExemptPorts,
|
|
1993
1978
|
commandGuestPaths: new Map(),
|
|
1994
1979
|
onWasmCommandResolved: (command) => {
|
|
1995
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
|
|
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
|
-
|
|
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
|
}
|