@rivet-dev/agentos-core 0.0.0-agentos-dylib-plugin.bbfdf95 → 0.0.0-chdir-fix.f899dc6
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 +8 -11
- package/dist/agent-os.d.ts +185 -43
- package/dist/agent-os.js +834 -536
- 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/cron-manager.js +1 -4
- 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-zod.js +27 -7
- package/dist/host-tools.js +9 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -2
- package/dist/layers.d.ts +3 -3
- package/dist/layers.js +22 -13
- package/dist/options-schema.d.ts +453 -0
- package/dist/options-schema.js +268 -0
- package/dist/packages.d.ts +17 -116
- package/dist/packages.js +35 -322
- package/dist/runtime-compat.d.ts +27 -7
- package/dist/runtime-compat.js +133 -147
- package/dist/runtime.d.ts +37 -7
- package/dist/sandbox.d.ts +112 -0
- package/dist/sandbox.js +264 -0
- package/dist/sidecar/{agent-os-protocol.d.ts → agentos-protocol.d.ts} +99 -1
- package/dist/sidecar/{agent-os-protocol.js → agentos-protocol.js} +156 -19
- package/dist/sidecar/native-process-client.d.ts +6 -2
- package/dist/sidecar/native-process-client.js +8 -1
- package/dist/sidecar/permissions.d.ts +1 -1
- package/dist/sidecar/permissions.js +4 -4
- package/dist/sidecar/rpc-client.d.ts +87 -6
- package/dist/sidecar/rpc-client.js +433 -93
- package/dist/test/sandbox-agent.js +1 -1
- package/dist/types.d.ts +10 -3
- package/package.json +42 -35
- 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
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { resolvePublishedSidecarBinary } from "./sidecar/binary.js";
|
|
8
8
|
import { findCargoBinary, resolveCargoBinary } from "./sidecar/cargo.js";
|
|
9
9
|
import { serializePermissionsForSidecar } from "./sidecar/permissions.js";
|
|
10
|
-
import {
|
|
10
|
+
import { NativeSidecarKernelProxy, SidecarProcess, serializeMountConfigForSidecar, } from "./sidecar/rpc-client.js";
|
|
11
11
|
export const AF_INET = 2;
|
|
12
12
|
export const AF_UNIX = 1;
|
|
13
13
|
export const SOCK_STREAM = 1;
|
|
@@ -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",
|
|
@@ -36,7 +41,8 @@ const KERNEL_POSIX_BOOTSTRAP_DIRS = [
|
|
|
36
41
|
"/mnt",
|
|
37
42
|
"/media",
|
|
38
43
|
"/home",
|
|
39
|
-
"/home/
|
|
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"
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
1194
|
-
|
|
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 ?? "/
|
|
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:
|
|
1637
|
+
this.pendingLocalMounts.push(makeLocalCompatMount({
|
|
1638
|
+
path: mount.path,
|
|
1650
1639
|
fs: mount.fs,
|
|
1651
|
-
readOnly: mount.readOnly
|
|
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
|
|
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
|
|
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
|
|
1688
|
-
|
|
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
|
-
|
|
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,18 +1796,29 @@ 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
|
-
|
|
1822
|
-
path: normalizePath(mountPath),
|
|
1823
|
-
fs: filesystem,
|
|
1824
|
-
readOnly: options?.readOnly ?? false,
|
|
1825
|
-
});
|
|
1807
|
+
// Pre-boot mounts apply during kernel initialization.
|
|
1826
1808
|
return;
|
|
1827
1809
|
}
|
|
1828
|
-
this.proxy.mountFs(mountPath, filesystem,
|
|
1810
|
+
return this.proxy.mountFs(mountPath, filesystem, {
|
|
1811
|
+
readOnly: localMount.readOnly,
|
|
1812
|
+
sidecarMount: localMount.sidecarMount,
|
|
1813
|
+
});
|
|
1829
1814
|
}
|
|
1830
1815
|
unmountFs(mountPath) {
|
|
1831
|
-
|
|
1816
|
+
const normalized = normalizePath(mountPath);
|
|
1817
|
+
const pendingIndex = this.pendingLocalMounts.findIndex((mount) => mount.path === normalized);
|
|
1818
|
+
if (pendingIndex >= 0) {
|
|
1819
|
+
this.pendingLocalMounts.splice(pendingIndex, 1);
|
|
1820
|
+
}
|
|
1821
|
+
return this.proxy?.unmountFs(mountPath);
|
|
1832
1822
|
}
|
|
1833
1823
|
async readFile(targetPath) {
|
|
1834
1824
|
await this.ensureReady();
|
|
@@ -1846,6 +1836,10 @@ class NativeKernel {
|
|
|
1846
1836
|
await this.ensureReady();
|
|
1847
1837
|
return this.proxy.readdir(targetPath);
|
|
1848
1838
|
}
|
|
1839
|
+
async readdirRecursive(targetPath, options) {
|
|
1840
|
+
await this.ensureReady();
|
|
1841
|
+
return this.proxy.readdirRecursive(targetPath, options);
|
|
1842
|
+
}
|
|
1849
1843
|
async stat(targetPath) {
|
|
1850
1844
|
await this.ensureReady();
|
|
1851
1845
|
return this.proxy.stat(targetPath);
|
|
@@ -1862,10 +1856,18 @@ class NativeKernel {
|
|
|
1862
1856
|
await this.ensureReady();
|
|
1863
1857
|
return this.proxy.removeDir(targetPath);
|
|
1864
1858
|
}
|
|
1859
|
+
async removePath(targetPath, options) {
|
|
1860
|
+
await this.ensureReady();
|
|
1861
|
+
return this.proxy.removePath(targetPath, options);
|
|
1862
|
+
}
|
|
1865
1863
|
async rename(oldPath, newPath) {
|
|
1866
1864
|
await this.ensureReady();
|
|
1867
1865
|
return this.proxy.rename(oldPath, newPath);
|
|
1868
1866
|
}
|
|
1867
|
+
async movePath(oldPath, newPath) {
|
|
1868
|
+
await this.ensureReady();
|
|
1869
|
+
return this.proxy.movePath(oldPath, newPath);
|
|
1870
|
+
}
|
|
1869
1871
|
tryResolveMountedCommand(command) {
|
|
1870
1872
|
const normalized = normalizeCommandLookup(command);
|
|
1871
1873
|
for (const driver of this.mountedRuntimeDrivers) {
|
|
@@ -1873,15 +1875,6 @@ class NativeKernel {
|
|
|
1873
1875
|
continue;
|
|
1874
1876
|
}
|
|
1875
1877
|
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
1878
|
return true;
|
|
1886
1879
|
}
|
|
1887
1880
|
return false;
|
|
@@ -1916,7 +1909,7 @@ class NativeKernel {
|
|
|
1916
1909
|
lowers: [
|
|
1917
1910
|
{
|
|
1918
1911
|
kind: "snapshot",
|
|
1919
|
-
entries: rootFilesystemEntriesForConfig(mergeRootFilesystemEntries(createBootstrapEntries(
|
|
1912
|
+
entries: rootFilesystemEntriesForConfig(mergeRootFilesystemEntries(createBootstrapEntries(), snapshotEntries)),
|
|
1920
1913
|
},
|
|
1921
1914
|
],
|
|
1922
1915
|
bootstrapEntries: [],
|
|
@@ -1925,7 +1918,6 @@ class NativeKernel {
|
|
|
1925
1918
|
cwd: REPO_ROOT,
|
|
1926
1919
|
command: ensureNativeSidecarBinary(),
|
|
1927
1920
|
args: [],
|
|
1928
|
-
frameTimeoutMs: NATIVE_SIDECAR_FRAME_TIMEOUT_MS,
|
|
1929
1921
|
});
|
|
1930
1922
|
const session = await client.authenticateAndOpenSession();
|
|
1931
1923
|
const createVmConfig = {
|
|
@@ -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:
|
|
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 ? "/
|
|
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
|
@@ -10,6 +10,7 @@ export interface VirtualDirEntry {
|
|
|
10
10
|
export interface VirtualStat {
|
|
11
11
|
mode: number;
|
|
12
12
|
size: number;
|
|
13
|
+
sizeExact?: bigint;
|
|
13
14
|
blocks: number;
|
|
14
15
|
dev: number;
|
|
15
16
|
rdev: number;
|
|
@@ -20,7 +21,9 @@ export interface VirtualStat {
|
|
|
20
21
|
ctimeMs: number;
|
|
21
22
|
birthtimeMs: number;
|
|
22
23
|
ino: number;
|
|
24
|
+
inoExact?: bigint;
|
|
23
25
|
nlink: number;
|
|
26
|
+
nlinkExact?: bigint;
|
|
24
27
|
uid: number;
|
|
25
28
|
gid: number;
|
|
26
29
|
}
|
|
@@ -76,7 +79,7 @@ export type NetworkPermissions = PermissionMode | RulePermissions<PatternPermiss
|
|
|
76
79
|
export type ChildProcessPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
|
|
77
80
|
export type ProcessPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
|
|
78
81
|
export type EnvPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
|
|
79
|
-
export type
|
|
82
|
+
export type BindingPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
|
|
80
83
|
export interface ProcessInfo {
|
|
81
84
|
pid: number;
|
|
82
85
|
ppid: number;
|
|
@@ -93,15 +96,15 @@ export interface ProcessInfo {
|
|
|
93
96
|
}
|
|
94
97
|
export interface ManagedProcess {
|
|
95
98
|
pid: number;
|
|
96
|
-
writeStdin(data: Uint8Array | string): void
|
|
97
|
-
closeStdin(): void
|
|
99
|
+
writeStdin(data: Uint8Array | string): Promise<void>;
|
|
100
|
+
closeStdin(): Promise<void>;
|
|
98
101
|
kill(signal?: number): void;
|
|
99
102
|
wait(): Promise<number>;
|
|
100
103
|
readonly exitCode: number | null;
|
|
101
104
|
}
|
|
102
105
|
export interface ShellHandle {
|
|
103
106
|
pid: number;
|
|
104
|
-
write(data: Uint8Array | string): void
|
|
107
|
+
write(data: Uint8Array | string): Promise<void>;
|
|
105
108
|
onData: ((data: Uint8Array) => void) | null;
|
|
106
109
|
resize(cols: number, rows: number): void;
|
|
107
110
|
kill(signal?: number): void;
|
|
@@ -163,7 +166,7 @@ export interface Permissions {
|
|
|
163
166
|
childProcess?: ChildProcessPermissions;
|
|
164
167
|
process?: ProcessPermissions;
|
|
165
168
|
env?: EnvPermissions;
|
|
166
|
-
|
|
169
|
+
binding?: BindingPermissions;
|
|
167
170
|
}
|
|
168
171
|
export interface ResourceBudgets {
|
|
169
172
|
maxOutputBytes?: number;
|
|
@@ -224,6 +227,7 @@ export interface SystemDriver {
|
|
|
224
227
|
network?: NetworkAdapter;
|
|
225
228
|
commandExecutor?: CommandExecutor;
|
|
226
229
|
permissions?: Permissions;
|
|
230
|
+
mounts: readonly NodeModulesMountConfig[];
|
|
227
231
|
runtime: {
|
|
228
232
|
process: ProcessConfig;
|
|
229
233
|
os: OSConfig;
|
|
@@ -258,6 +262,13 @@ export interface NodeRuntimeDriverFactory {
|
|
|
258
262
|
export interface KernelInterface {
|
|
259
263
|
vfs: VirtualFileSystem;
|
|
260
264
|
}
|
|
265
|
+
export interface KernelRecursiveDirEntry {
|
|
266
|
+
name: string;
|
|
267
|
+
path: string;
|
|
268
|
+
isDirectory: boolean;
|
|
269
|
+
isSymbolicLink: boolean;
|
|
270
|
+
size: number;
|
|
271
|
+
}
|
|
261
272
|
export interface Kernel extends KernelInterface {
|
|
262
273
|
mount(driver: KernelRuntimeDriver): Promise<void>;
|
|
263
274
|
dispose(): Promise<void>;
|
|
@@ -267,17 +278,24 @@ export interface Kernel extends KernelInterface {
|
|
|
267
278
|
connectTerminal(options?: ConnectTerminalOptions): Promise<number>;
|
|
268
279
|
mountFs(path: string, fs: VirtualFileSystem, options?: {
|
|
269
280
|
readOnly?: boolean;
|
|
270
|
-
}): void
|
|
271
|
-
unmountFs(path: string): void
|
|
281
|
+
}): void | Promise<void>;
|
|
282
|
+
unmountFs(path: string): void | Promise<void>;
|
|
272
283
|
readFile(path: string): Promise<Uint8Array>;
|
|
273
284
|
writeFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
274
285
|
mkdir(path: string): Promise<void>;
|
|
275
286
|
readdir(path: string): Promise<string[]>;
|
|
287
|
+
readdirRecursive(path: string, options?: {
|
|
288
|
+
maxDepth?: number;
|
|
289
|
+
}): Promise<KernelRecursiveDirEntry[]>;
|
|
276
290
|
stat(path: string): Promise<VirtualStat>;
|
|
277
291
|
exists(path: string): Promise<boolean>;
|
|
278
292
|
removeFile(path: string): Promise<void>;
|
|
279
293
|
removeDir(path: string): Promise<void>;
|
|
294
|
+
removePath(path: string, options?: {
|
|
295
|
+
recursive?: boolean;
|
|
296
|
+
}): Promise<void>;
|
|
280
297
|
rename(oldPath: string, newPath: string): Promise<void>;
|
|
298
|
+
movePath(oldPath: string, newPath: string): Promise<void>;
|
|
281
299
|
readonly commands: ReadonlyMap<string, string>;
|
|
282
300
|
readonly processes: ReadonlyMap<number, ProcessInfo>;
|
|
283
301
|
readonly env: Record<string, string>;
|
|
@@ -299,11 +317,23 @@ export interface BindingTree {
|
|
|
299
317
|
[key: string]: BindingFunction | BindingTree;
|
|
300
318
|
}
|
|
301
319
|
export type BindingFunction = (...args: unknown[]) => unknown;
|
|
320
|
+
export interface NodeModulesMountConfig {
|
|
321
|
+
path: string;
|
|
322
|
+
plugin: {
|
|
323
|
+
id: "host_dir";
|
|
324
|
+
config: {
|
|
325
|
+
hostPath: string;
|
|
326
|
+
readOnly: boolean;
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
readOnly: boolean;
|
|
330
|
+
}
|
|
302
331
|
export interface NodeDriverOptions {
|
|
303
332
|
filesystem?: VirtualFileSystem;
|
|
304
333
|
networkAdapter?: NetworkAdapter;
|
|
305
334
|
commandExecutor?: CommandExecutor;
|
|
306
335
|
permissions?: Permissions;
|
|
336
|
+
mounts?: readonly NodeModulesMountConfig[];
|
|
307
337
|
processConfig?: ProcessConfig;
|
|
308
338
|
osConfig?: OSConfig;
|
|
309
339
|
}
|