@rivet-dev/agentos-core 0.0.0-agentos-dylib-plugin.473700e

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 (75) hide show
  1. package/README.md +204 -0
  2. package/dist/agent-os.d.ts +560 -0
  3. package/dist/agent-os.js +3624 -0
  4. package/dist/agent-session-types.d.ts +67 -0
  5. package/dist/agent-session-types.js +1 -0
  6. package/dist/agents.d.ts +63 -0
  7. package/dist/agents.js +42 -0
  8. package/dist/base-filesystem.d.ts +34 -0
  9. package/dist/base-filesystem.js +173 -0
  10. package/dist/cron/cron-manager.d.ts +22 -0
  11. package/dist/cron/cron-manager.js +160 -0
  12. package/dist/cron/index.d.ts +5 -0
  13. package/dist/cron/index.js +3 -0
  14. package/dist/cron/parse-schedule.d.ts +25 -0
  15. package/dist/cron/parse-schedule.js +66 -0
  16. package/dist/cron/schedule-driver.d.ts +19 -0
  17. package/dist/cron/schedule-driver.js +1 -0
  18. package/dist/cron/timer-driver.d.ts +17 -0
  19. package/dist/cron/timer-driver.js +61 -0
  20. package/dist/cron/types.d.ts +55 -0
  21. package/dist/cron/types.js +1 -0
  22. package/dist/filesystem-snapshot.d.ts +14 -0
  23. package/dist/filesystem-snapshot.js +105 -0
  24. package/dist/host-dir-mount.d.ts +38 -0
  25. package/dist/host-dir-mount.js +34 -0
  26. package/dist/host-tools-zod.d.ts +7 -0
  27. package/dist/host-tools-zod.js +243 -0
  28. package/dist/host-tools.d.ts +45 -0
  29. package/dist/host-tools.js +26 -0
  30. package/dist/index.d.ts +10 -0
  31. package/dist/index.js +10 -0
  32. package/dist/js-bridge.d.ts +3 -0
  33. package/dist/js-bridge.js +2 -0
  34. package/dist/json-rpc.d.ts +50 -0
  35. package/dist/json-rpc.js +22 -0
  36. package/dist/layers.d.ts +51 -0
  37. package/dist/layers.js +185 -0
  38. package/dist/overlay-filesystem.d.ts +19 -0
  39. package/dist/overlay-filesystem.js +645 -0
  40. package/dist/packages.d.ts +127 -0
  41. package/dist/packages.js +335 -0
  42. package/dist/runtime-compat.d.ts +471 -0
  43. package/dist/runtime-compat.js +2009 -0
  44. package/dist/runtime.d.ts +336 -0
  45. package/dist/runtime.js +1 -0
  46. package/dist/sidecar/agent-os-protocol.d.ts +219 -0
  47. package/dist/sidecar/agent-os-protocol.js +594 -0
  48. package/dist/sidecar/binary.d.ts +9 -0
  49. package/dist/sidecar/binary.js +30 -0
  50. package/dist/sidecar/cargo.d.ts +2 -0
  51. package/dist/sidecar/cargo.js +142 -0
  52. package/dist/sidecar/native-process-client.d.ts +2 -0
  53. package/dist/sidecar/native-process-client.js +1 -0
  54. package/dist/sidecar/permissions.d.ts +3 -0
  55. package/dist/sidecar/permissions.js +54 -0
  56. package/dist/sidecar/process.d.ts +6 -0
  57. package/dist/sidecar/process.js +8 -0
  58. package/dist/sidecar/rpc-client.d.ts +244 -0
  59. package/dist/sidecar/rpc-client.js +2028 -0
  60. package/dist/test/docker.d.ts +133 -0
  61. package/dist/test/docker.js +336 -0
  62. package/dist/test/file-system.d.ts +39 -0
  63. package/dist/test/file-system.js +562 -0
  64. package/dist/test/mock-s3.d.ts +42 -0
  65. package/dist/test/mock-s3.js +292 -0
  66. package/dist/test/runtime.d.ts +11 -0
  67. package/dist/test/runtime.js +9 -0
  68. package/dist/test/sandbox-agent.d.ts +9 -0
  69. package/dist/test/sandbox-agent.js +395 -0
  70. package/dist/test/terminal-harness.d.ts +27 -0
  71. package/dist/test/terminal-harness.js +122 -0
  72. package/dist/types.d.ts +10 -0
  73. package/dist/types.js +1 -0
  74. package/fixtures/AGENTOS_SYSTEM_PROMPT.md +21 -0
  75. package/package.json +111 -0
@@ -0,0 +1,127 @@
1
+ import type { PermissionTier } from "./runtime.js";
2
+ /**
3
+ * Resolve a package directory by walking up the directory tree.
4
+ * Supports both nested (pnpm) and flat (npm) node_modules layouts.
5
+ */
6
+ export declare function resolvePackageDir(startDir: string, packageName: string): string;
7
+ import type { AgentConfig } from "./agents.js";
8
+ export interface SoftwareDescriptor {
9
+ name: string;
10
+ type: "agent" | "tool" | "wasm-commands";
11
+ }
12
+ export interface AgentSoftwareDescriptor extends SoftwareDescriptor {
13
+ type: "agent";
14
+ /**
15
+ * Root directory of this npm package on the host. Used to resolve
16
+ * dependencies listed in `requires` from this package's node_modules/.
17
+ */
18
+ packageDir: string;
19
+ /** npm packages that must be available inside the VM. */
20
+ requires: string[];
21
+ agent: {
22
+ /** Unique agent ID used in createSession(id). */
23
+ id: string;
24
+ /** npm package name of the ACP adapter. Must be in requires. */
25
+ acpAdapter: string;
26
+ /** npm package name of the agent CLI. Must be in requires. */
27
+ agentPackage: string;
28
+ /** Static env vars passed when spawning the adapter. */
29
+ staticEnv?: Record<string, string>;
30
+ /** Dynamic env vars computed at boot time. */
31
+ env?: (ctx: SoftwareContext) => Record<string, string>;
32
+ /** Additional CLI args prepended when launching the ACP adapter. */
33
+ launchArgs?: string[];
34
+ };
35
+ }
36
+ export interface ToolSoftwareDescriptor extends SoftwareDescriptor {
37
+ type: "tool";
38
+ /**
39
+ * Root directory of this npm package on the host. Used to resolve
40
+ * dependencies listed in `requires` from this package's node_modules/.
41
+ */
42
+ packageDir: string;
43
+ /** npm packages that must be available inside the VM. */
44
+ requires: string[];
45
+ /** Map of bin command name -> npm package name. */
46
+ bins: Record<string, string>;
47
+ }
48
+ export interface WasmCommandSoftwareDescriptor extends SoftwareDescriptor {
49
+ type: "wasm-commands";
50
+ /** Absolute path to directory containing WASM command binaries on the host. */
51
+ commandDir: string;
52
+ /** Symlink aliases: aliasName -> targetCommandName. */
53
+ aliases?: Record<string, string>;
54
+ /** Permission tier assignments. */
55
+ permissions?: {
56
+ full?: string[];
57
+ readWrite?: string[];
58
+ readOnly?: string[] | "*";
59
+ isolated?: string[];
60
+ };
61
+ }
62
+ /**
63
+ * Any object with a commandDir property is treated as a WASM command package.
64
+ * This allows registry packages (e.g., @agent-os-pkgs/coreutils) to be
65
+ * passed directly to the `software` option without wrapping.
66
+ */
67
+ export interface WasmCommandDirDescriptor {
68
+ readonly commandDir: string;
69
+ [key: string]: unknown;
70
+ }
71
+ export type AnySoftwareDescriptor = AgentSoftwareDescriptor | ToolSoftwareDescriptor | WasmCommandSoftwareDescriptor | WasmCommandDirDescriptor;
72
+ /** Input type for the `software` option. Accepts descriptors or arrays of descriptors (for meta-packages). */
73
+ export type SoftwareInput = AnySoftwareDescriptor | AnySoftwareDescriptor[];
74
+ export interface SoftwareContext {
75
+ /**
76
+ * Resolve the bin entry for an npm package to a VM-side path.
77
+ * Uses require.resolve on the HOST, then maps to /root/node_modules/...
78
+ *
79
+ * Example: ctx.resolveBin("@mariozechner/pi-coding-agent", "pi")
80
+ * -> "/root/node_modules/@mariozechner/pi-coding-agent/dist/cli.js"
81
+ */
82
+ resolveBin(packageName: string, binName?: string): string;
83
+ /**
84
+ * Resolve a package's root directory to a VM-side path.
85
+ *
86
+ * Example: ctx.resolvePackage("pi-acp")
87
+ * -> "/root/node_modules/pi-acp"
88
+ */
89
+ resolvePackage(packageName: string): string;
90
+ }
91
+ /** Host-to-VM path mapping for a software package's `/root/node_modules/<pkg>` mount. */
92
+ export interface SoftwareRoot {
93
+ hostPath: string;
94
+ vmPath: string;
95
+ }
96
+ export interface CommandPackageMetadata {
97
+ commandDir: string;
98
+ declaredCommands: string[];
99
+ aliases: Record<string, string>;
100
+ }
101
+ /**
102
+ * Define a software descriptor. This is a type-safe identity function that
103
+ * validates the descriptor shape at compile time.
104
+ */
105
+ export declare function defineSoftware<T extends AnySoftwareDescriptor>(desc: T): T;
106
+ /** Result of processing all software descriptors at boot time. */
107
+ export interface ProcessedSoftware {
108
+ /** WASM command directories to pass to the WasmVM driver. */
109
+ commandDirs: string[];
110
+ /** Per-package command metadata used to preserve command availability on the sidecar path. */
111
+ commandPackages: CommandPackageMetadata[];
112
+ /** Per-command permission tiers propagated into the WasmVM runtime. */
113
+ commandPermissions: Record<string, PermissionTier>;
114
+ /** Host-to-VM path mappings for software-package `/root/node_modules/<pkg>` mounts. */
115
+ softwareRoots: SoftwareRoot[];
116
+ /** Agent configs registered by agent software. */
117
+ agentConfigs: Map<string, AgentConfig>;
118
+ }
119
+ /**
120
+ * Process an array of software descriptors at boot time.
121
+ * Collects WASM command dirs, module access roots, and agent configurations.
122
+ *
123
+ * Any object with a `commandDir` property (e.g., registry packages) is treated
124
+ * as a WASM command source. Typed descriptors with `type: "agent"` or `type: "tool"`
125
+ * are processed for module mounting and agent registration.
126
+ */
127
+ export declare function processSoftware(software: SoftwareInput[]): ProcessedSoftware;
@@ -0,0 +1,335 @@
1
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
2
+ import { dirname, join, resolve, sep } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * Resolve a package directory by walking up the directory tree.
6
+ * Supports both nested (pnpm) and flat (npm) node_modules layouts.
7
+ */
8
+ export function resolvePackageDir(startDir, packageName) {
9
+ const localPkgJson = join(startDir, "package.json");
10
+ if (existsSync(localPkgJson)) {
11
+ try {
12
+ const localPkg = JSON.parse(readFileSync(localPkgJson, "utf-8"));
13
+ if (localPkg.name === packageName) {
14
+ return realpathSync(startDir);
15
+ }
16
+ }
17
+ catch {
18
+ // Ignore malformed local package metadata and continue walking.
19
+ }
20
+ }
21
+ let searchDir = startDir;
22
+ while (true) {
23
+ const candidate = join(searchDir, "node_modules", packageName);
24
+ if (existsSync(join(candidate, "package.json"))) {
25
+ return realpathSync(candidate);
26
+ }
27
+ const parent = dirname(searchDir);
28
+ if (parent === searchDir)
29
+ break;
30
+ searchDir = parent;
31
+ }
32
+ throw new Error(`Package "${packageName}" not found starting from ${startDir}. ` +
33
+ `Ensure it is installed.`);
34
+ }
35
+ const LOCAL_REGISTRY_COMMAND_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../../..", "registry/native/target/wasm32-wasip1/release/commands");
36
+ function readPackageName(packageDir) {
37
+ const pkg = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf-8"));
38
+ if (typeof pkg.name !== "string" || pkg.name.length === 0) {
39
+ throw new Error(`Package at ${packageDir} is missing a valid name`);
40
+ }
41
+ return pkg.name;
42
+ }
43
+ function pushSoftwareRoot(softwareRoots, seenVmPaths, hostPath, vmPath) {
44
+ if (seenVmPaths.has(vmPath)) {
45
+ return;
46
+ }
47
+ seenVmPaths.add(vmPath);
48
+ softwareRoots.push({ hostPath, vmPath });
49
+ }
50
+ function findPnpmStoreRoot(hostPath) {
51
+ const marker = `${sep}node_modules${sep}.pnpm${sep}`;
52
+ const markerIndex = hostPath.indexOf(marker);
53
+ if (markerIndex === -1) {
54
+ return null;
55
+ }
56
+ const nodeModulesRoot = `${hostPath.slice(0, markerIndex)}${sep}node_modules`;
57
+ const pnpmStoreRoot = join(nodeModulesRoot, ".pnpm");
58
+ return existsSync(pnpmStoreRoot) ? pnpmStoreRoot : null;
59
+ }
60
+ function pushPackageSoftwareRoot(softwareRoots, seenVmPaths, hostPath, vmPath) {
61
+ pushSoftwareRoot(softwareRoots, seenVmPaths, hostPath, vmPath);
62
+ const pnpmStoreRoot = findPnpmStoreRoot(hostPath);
63
+ if (!pnpmStoreRoot) {
64
+ return;
65
+ }
66
+ pushSoftwareRoot(softwareRoots, seenVmPaths, pnpmStoreRoot, "/root/node_modules/.pnpm");
67
+ }
68
+ /**
69
+ * Create a SoftwareContext for a software descriptor.
70
+ * Resolves npm package paths relative to the descriptor's packageDir.
71
+ */
72
+ function createSoftwareContext(packageDir, requires) {
73
+ // Pre-resolve all required packages to host paths
74
+ const resolvedPackages = new Map();
75
+ for (const reqPkg of requires) {
76
+ const hostDir = resolvePackageDir(packageDir, reqPkg);
77
+ const pkg = JSON.parse(readFileSync(join(hostDir, "package.json"), "utf-8"));
78
+ const vmDir = `/root/node_modules/${reqPkg}`;
79
+ resolvedPackages.set(reqPkg, { hostDir, vmDir, pkg });
80
+ }
81
+ return {
82
+ resolveBin(packageName, binName) {
83
+ const resolved = resolvedPackages.get(packageName);
84
+ if (!resolved) {
85
+ throw new Error(`Package "${packageName}" is not in the requires list. ` +
86
+ `Available: ${[...resolvedPackages.keys()].join(", ")}`);
87
+ }
88
+ const { pkg, vmDir } = resolved;
89
+ let binEntry;
90
+ const effectiveBinName = binName ?? packageName;
91
+ if (typeof pkg.bin === "string") {
92
+ binEntry = pkg.bin;
93
+ }
94
+ else if (typeof pkg.bin === "object" && pkg.bin !== null) {
95
+ const binMap = pkg.bin;
96
+ binEntry = binMap[effectiveBinName] ?? Object.values(binMap)[0];
97
+ }
98
+ if (!binEntry) {
99
+ throw new Error(`No bin entry "${effectiveBinName}" found in ${packageName}/package.json`);
100
+ }
101
+ return `${vmDir}/${binEntry}`;
102
+ },
103
+ resolvePackage(packageName) {
104
+ const resolved = resolvedPackages.get(packageName);
105
+ if (!resolved) {
106
+ throw new Error(`Package "${packageName}" is not in the requires list. ` +
107
+ `Available: ${[...resolvedPackages.keys()].join(", ")}`);
108
+ }
109
+ return resolved.vmDir;
110
+ },
111
+ };
112
+ }
113
+ // ── defineSoftware ───────────────────────────────────────────────────
114
+ /**
115
+ * Define a software descriptor. This is a type-safe identity function that
116
+ * validates the descriptor shape at compile time.
117
+ */
118
+ export function defineSoftware(desc) {
119
+ return desc;
120
+ }
121
+ /** Check if a descriptor is a typed software descriptor (has a `type` field). */
122
+ function isTypedDescriptor(desc) {
123
+ return ("type" in desc && typeof desc.type === "string");
124
+ }
125
+ const VALID_PERMISSION_TIERS = new Set([
126
+ "full",
127
+ "read-write",
128
+ "read-only",
129
+ "isolated",
130
+ ]);
131
+ function isPermissionTier(value) {
132
+ return (typeof value === "string" &&
133
+ VALID_PERMISSION_TIERS.has(value));
134
+ }
135
+ function registerPermission(commandPermissions, commandName, tier) {
136
+ if (commandName in commandPermissions)
137
+ return;
138
+ commandPermissions[commandName] = tier;
139
+ }
140
+ function appendDeclaredCommand(declaredCommands, seen, commandName) {
141
+ if (typeof commandName !== "string" || seen.has(commandName)) {
142
+ return;
143
+ }
144
+ seen.add(commandName);
145
+ declaredCommands.push(commandName);
146
+ }
147
+ function collectCommandMetadata(pkg) {
148
+ const declaredCommands = [];
149
+ const seen = new Set();
150
+ const aliases = {};
151
+ if ("aliases" in pkg && pkg.aliases) {
152
+ for (const [aliasName, targetName] of Object.entries(pkg.aliases)) {
153
+ if (typeof targetName !== "string") {
154
+ continue;
155
+ }
156
+ aliases[aliasName] = targetName;
157
+ appendDeclaredCommand(declaredCommands, seen, aliasName);
158
+ appendDeclaredCommand(declaredCommands, seen, targetName);
159
+ }
160
+ }
161
+ const rawCommands = pkg.commands;
162
+ if (Array.isArray(rawCommands)) {
163
+ for (const rawCommand of rawCommands) {
164
+ if (typeof rawCommand !== "object" || rawCommand === null) {
165
+ continue;
166
+ }
167
+ const name = rawCommand.name;
168
+ const aliasOf = rawCommand.aliasOf;
169
+ appendDeclaredCommand(declaredCommands, seen, name);
170
+ appendDeclaredCommand(declaredCommands, seen, aliasOf);
171
+ if (typeof name === "string" && typeof aliasOf === "string") {
172
+ aliases[name] = aliasOf;
173
+ }
174
+ }
175
+ }
176
+ const permissions = pkg.permissions;
177
+ if (permissions) {
178
+ for (const commandName of permissions.full ?? []) {
179
+ appendDeclaredCommand(declaredCommands, seen, commandName);
180
+ }
181
+ for (const commandName of permissions.readWrite ?? []) {
182
+ appendDeclaredCommand(declaredCommands, seen, commandName);
183
+ }
184
+ if (Array.isArray(permissions.readOnly)) {
185
+ for (const commandName of permissions.readOnly) {
186
+ appendDeclaredCommand(declaredCommands, seen, commandName);
187
+ }
188
+ }
189
+ for (const commandName of permissions.isolated ?? []) {
190
+ appendDeclaredCommand(declaredCommands, seen, commandName);
191
+ }
192
+ }
193
+ const commandDir = resolveLocalCommandDirFallback(pkg.commandDir, declaredCommands);
194
+ return {
195
+ commandDir,
196
+ declaredCommands,
197
+ aliases,
198
+ };
199
+ }
200
+ function hasUsableCommandDir(commandDir, declaredCommands) {
201
+ if (!existsSync(commandDir)) {
202
+ return false;
203
+ }
204
+ return declaredCommands.every((commandName) => existsSync(join(commandDir, commandName)));
205
+ }
206
+ function resolveLocalCommandDirFallback(commandDir, declaredCommands) {
207
+ if (declaredCommands.length === 0 ||
208
+ hasUsableCommandDir(commandDir, declaredCommands) ||
209
+ !hasUsableCommandDir(LOCAL_REGISTRY_COMMAND_DIR, declaredCommands)) {
210
+ return commandDir;
211
+ }
212
+ return LOCAL_REGISTRY_COMMAND_DIR;
213
+ }
214
+ function collectRegistryPackagePermissions(commandPermissions, pkg) {
215
+ const rawCommands = pkg.commands;
216
+ if (!Array.isArray(rawCommands))
217
+ return;
218
+ for (const rawCommand of rawCommands) {
219
+ if (typeof rawCommand !== "object" ||
220
+ rawCommand === null ||
221
+ !Object.hasOwn(rawCommand, "name") ||
222
+ !Object.hasOwn(rawCommand, "permissionTier")) {
223
+ continue;
224
+ }
225
+ const name = rawCommand.name;
226
+ const permissionTier = rawCommand
227
+ .permissionTier;
228
+ if (typeof name !== "string" || !isPermissionTier(permissionTier))
229
+ continue;
230
+ registerPermission(commandPermissions, name, permissionTier);
231
+ }
232
+ }
233
+ function collectTypedDescriptorPermissions(commandPermissions, pkg) {
234
+ const permissions = pkg.permissions;
235
+ if (!permissions)
236
+ return;
237
+ for (const commandName of permissions.full ?? []) {
238
+ registerPermission(commandPermissions, commandName, "full");
239
+ }
240
+ for (const commandName of permissions.readWrite ?? []) {
241
+ registerPermission(commandPermissions, commandName, "read-write");
242
+ }
243
+ if (Array.isArray(permissions.readOnly)) {
244
+ for (const commandName of permissions.readOnly) {
245
+ registerPermission(commandPermissions, commandName, "read-only");
246
+ }
247
+ }
248
+ for (const commandName of permissions.isolated ?? []) {
249
+ registerPermission(commandPermissions, commandName, "isolated");
250
+ }
251
+ }
252
+ /**
253
+ * Process an array of software descriptors at boot time.
254
+ * Collects WASM command dirs, module access roots, and agent configurations.
255
+ *
256
+ * Any object with a `commandDir` property (e.g., registry packages) is treated
257
+ * as a WASM command source. Typed descriptors with `type: "agent"` or `type: "tool"`
258
+ * are processed for module mounting and agent registration.
259
+ */
260
+ export function processSoftware(software) {
261
+ const commandDirs = [];
262
+ const commandPackages = [];
263
+ const commandPermissions = {};
264
+ const softwareRoots = [];
265
+ const seenSoftwareVmPaths = new Set();
266
+ const agentConfigs = new Map();
267
+ // Flatten nested arrays (meta-packages export arrays of sub-packages).
268
+ const flat = software.flat();
269
+ for (const pkg of flat) {
270
+ if (!isTypedDescriptor(pkg)) {
271
+ // Duck-typed: any object with commandDir is a WASM command source.
272
+ const commandMetadata = collectCommandMetadata(pkg);
273
+ commandDirs.push(commandMetadata.commandDir);
274
+ commandPackages.push(commandMetadata);
275
+ collectRegistryPackagePermissions(commandPermissions, pkg);
276
+ continue;
277
+ }
278
+ switch (pkg.type) {
279
+ case "wasm-commands": {
280
+ const commandMetadata = collectCommandMetadata(pkg);
281
+ commandDirs.push(commandMetadata.commandDir);
282
+ commandPackages.push(commandMetadata);
283
+ collectTypedDescriptorPermissions(commandPermissions, pkg);
284
+ break;
285
+ }
286
+ case "agent": {
287
+ // Collect module roots for all required npm packages.
288
+ // Walks up directory tree to support flat (npm) and nested (pnpm) layouts.
289
+ const ctx = createSoftwareContext(pkg.packageDir, pkg.requires);
290
+ const declaringPackageName = readPackageName(pkg.packageDir);
291
+ pushPackageSoftwareRoot(softwareRoots, seenSoftwareVmPaths, pkg.packageDir, `/root/node_modules/${declaringPackageName}`);
292
+ for (const reqPkg of pkg.requires) {
293
+ const hostDir = resolvePackageDir(pkg.packageDir, reqPkg);
294
+ const vmDir = `/root/node_modules/${reqPkg}`;
295
+ pushPackageSoftwareRoot(softwareRoots, seenSoftwareVmPaths, hostDir, vmDir);
296
+ }
297
+ // Compute static + dynamic env vars.
298
+ const staticEnv = pkg.agent.staticEnv ?? {};
299
+ const dynamicEnv = pkg.agent.env ? pkg.agent.env(ctx) : {};
300
+ const combinedEnv = { ...staticEnv, ...dynamicEnv };
301
+ // Register agent config.
302
+ const agentConfig = {
303
+ acpAdapter: pkg.agent.acpAdapter,
304
+ agentPackage: pkg.agent.agentPackage,
305
+ declaringPackageDir: pkg.packageDir,
306
+ launchArgs: pkg.agent.launchArgs,
307
+ defaultEnv: Object.keys(combinedEnv).length > 0 ? combinedEnv : undefined,
308
+ };
309
+ agentConfigs.set(pkg.agent.id, agentConfig);
310
+ break;
311
+ }
312
+ case "tool": {
313
+ // Collect module roots for all required npm packages.
314
+ // Walks up directory tree to support flat (npm) and nested (pnpm) layouts.
315
+ const declaringPackageName = readPackageName(pkg.packageDir);
316
+ pushPackageSoftwareRoot(softwareRoots, seenSoftwareVmPaths, pkg.packageDir, `/root/node_modules/${declaringPackageName}`);
317
+ for (const reqPkg of pkg.requires) {
318
+ const hostDir = resolvePackageDir(pkg.packageDir, reqPkg);
319
+ const vmDir = `/root/node_modules/${reqPkg}`;
320
+ pushPackageSoftwareRoot(softwareRoots, seenSoftwareVmPaths, hostDir, vmDir);
321
+ }
322
+ // Tool bin registration is handled by the caller (AgentOs.create)
323
+ // since it requires kernel access.
324
+ break;
325
+ }
326
+ }
327
+ }
328
+ return {
329
+ commandDirs,
330
+ commandPackages,
331
+ commandPermissions,
332
+ softwareRoots,
333
+ agentConfigs,
334
+ };
335
+ }