@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.
Files changed (100) hide show
  1. package/README.md +4 -7
  2. package/dist/agent-os.d.ts +116 -46
  3. package/dist/agent-os.js +740 -541
  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.js +9 -0
  75. package/dist/index.d.ts +2 -1
  76. package/dist/index.js +1 -1
  77. package/dist/layers.d.ts +2 -2
  78. package/dist/layers.js +19 -10
  79. package/dist/options-schema.d.ts +19 -4
  80. package/dist/options-schema.js +30 -22
  81. package/dist/packages.d.ts +17 -116
  82. package/dist/packages.js +35 -322
  83. package/dist/runtime-compat.d.ts +22 -9
  84. package/dist/runtime-compat.js +126 -141
  85. package/dist/runtime.d.ts +32 -5
  86. package/dist/sandbox.d.ts +112 -0
  87. package/dist/sandbox.js +264 -0
  88. package/dist/sidecar/agentos-protocol.d.ts +88 -1
  89. package/dist/sidecar/agentos-protocol.js +134 -18
  90. package/dist/sidecar/native-process-client.d.ts +6 -3
  91. package/dist/sidecar/native-process-client.js +5 -3
  92. package/dist/sidecar/permissions.d.ts +1 -1
  93. package/dist/sidecar/permissions.js +3 -3
  94. package/dist/sidecar/rpc-client.d.ts +62 -4
  95. package/dist/sidecar/rpc-client.js +339 -85
  96. package/dist/types.d.ts +10 -3
  97. package/package.json +36 -32
  98. package/dist/agents.d.ts +0 -63
  99. package/dist/agents.js +0 -42
  100. package/fixtures/AGENTOS_SYSTEM_PROMPT.md +0 -21
@@ -1,127 +1,28 @@
1
- import type { PermissionTier } from "./runtime.js";
1
+ import type { SoftwarePackageRef } from "./agentos-package.js";
2
2
  /**
3
- * Resolve a package directory by walking up the directory tree.
4
- * Supports both nested (pnpm) and flat (npm) node_modules layouts.
3
+ * Input type for the `software` option. Software is a self-contained package
4
+ * directory that the secure-exec sidecar materializes into the `/opt/agentos`
5
+ * projection. Accepts a package-dir ref or an array of refs for meta-packages.
5
6
  */
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., @agentos-software/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
- }
7
+ export type SoftwareEntry = SoftwarePackageRef;
8
+ export type SoftwareInput = SoftwareEntry | SoftwareEntry[];
91
9
  /** Host-to-VM path mapping for a software package's `/root/node_modules/<pkg>` mount. */
92
10
  export interface SoftwareRoot {
93
11
  hostPath: string;
94
12
  vmPath: string;
95
13
  }
96
- export interface CommandPackageMetadata {
97
- commandDir: string;
98
- declaredCommands: string[];
99
- aliases: Record<string, string>;
100
- }
101
14
  /**
102
- * Define a software descriptor. This is a type-safe identity function that
103
- * validates the descriptor shape at compile time.
15
+ * Define a software descriptor. A type-safe identity function that validates the
16
+ * package-dir reference at compile time. The sidecar materializes the package into
17
+ * the `/opt/agentos` projection.
104
18
  */
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
- }
19
+ export declare function defineSoftware<T extends SoftwareEntry>(desc: T): T;
119
20
  /**
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.
21
+ * Resolve the agent-SDK snapshot bundle (an esbuild IIFE at
22
+ * `<dir>/dist/sdk-snapshot.js`) for the first snapshot-enabled agent package in
23
+ * the software set. Returns its source so it can be evaluated once into the
24
+ * per-sidecar V8 startup snapshot (`jsRuntime.snapshotUserlandCode`) and reused
25
+ * across sessions. Returns `undefined` when no agent opts in (`agent.snapshot`)
26
+ * or the bundle is absent -- the runtime then keeps the per-session import path.
126
27
  */
127
- export declare function processSoftware(software: SoftwareInput[]): ProcessedSoftware;
28
+ export declare function resolveAgentSnapshotBundle(software: SoftwareInput[]): string | undefined;
package/dist/packages.js CHANGED
@@ -1,335 +1,48 @@
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
- }
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { tryReadAgentosPackageManifest } from "./agentos-package.js";
113
4
  // ── defineSoftware ───────────────────────────────────────────────────
114
5
  /**
115
- * Define a software descriptor. This is a type-safe identity function that
116
- * validates the descriptor shape at compile time.
6
+ * Define a software descriptor. A type-safe identity function that validates the
7
+ * package-dir reference at compile time. The sidecar materializes the package into
8
+ * the `/opt/agentos` projection.
117
9
  */
118
10
  export function defineSoftware(desc) {
119
11
  return desc;
120
12
  }
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")) {
13
+ /**
14
+ * Resolve the agent-SDK snapshot bundle (an esbuild IIFE at
15
+ * `<dir>/dist/sdk-snapshot.js`) for the first snapshot-enabled agent package in
16
+ * the software set. Returns its source so it can be evaluated once into the
17
+ * per-sidecar V8 startup snapshot (`jsRuntime.snapshotUserlandCode`) and reused
18
+ * across sessions. Returns `undefined` when no agent opts in (`agent.snapshot`)
19
+ * or the bundle is absent -- the runtime then keeps the per-session import path.
20
+ */
21
+ export function resolveAgentSnapshotBundle(software) {
22
+ const descriptors = software.flat();
23
+ for (const entry of descriptors) {
24
+ // Only transition package DIRS are readable host-side (their
25
+ // agentos-package.json is the toolchain-input manifest). Packed
26
+ // `.aospkg` refs carry the bundle inside the mount tar; the sidecar
27
+ // reads it from the packed vbare manifest's snapshotBundlePath.
28
+ const path = entry.packagePath;
29
+ if (path === undefined || !statIsDirectory(path))
223
30
  continue;
224
- }
225
- const name = rawCommand.name;
226
- const permissionTier = rawCommand
227
- .permissionTier;
228
- if (typeof name !== "string" || !isPermissionTier(permissionTier))
31
+ const manifest = tryReadAgentosPackageManifest(path);
32
+ if (!manifest?.agent?.snapshot)
229
33
  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");
34
+ const bundlePath = join(path, "dist", "sdk-snapshot.js");
35
+ if (existsSync(bundlePath)) {
36
+ return readFileSync(bundlePath, "utf-8");
246
37
  }
247
38
  }
248
- for (const commandName of permissions.isolated ?? []) {
249
- registerPermission(commandPermissions, commandName, "isolated");
250
- }
39
+ return undefined;
251
40
  }
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
- }
41
+ function statIsDirectory(path) {
42
+ try {
43
+ return statSync(path).isDirectory();
44
+ }
45
+ catch {
46
+ return false;
327
47
  }
328
- return {
329
- commandDirs,
330
- commandPackages,
331
- commandPermissions,
332
- softwareRoots,
333
- agentConfigs,
334
- };
335
48
  }
@@ -1,3 +1,4 @@
1
+ import type { NodeModulesMountConfig } from "./host-dir-mount.js";
1
2
  export declare const AF_INET = 2;
2
3
  export declare const AF_UNIX = 1;
3
4
  export declare const SOCK_STREAM = 1;
@@ -81,7 +82,7 @@ export type NetworkPermissions = PermissionMode | RulePermissions<PatternPermiss
81
82
  export type ChildProcessPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
82
83
  export type ProcessPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
83
84
  export type EnvPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
84
- export type ToolPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
85
+ export type BindingPermissions = PermissionMode | RulePermissions<PatternPermissionRule>;
85
86
  export interface ProcessInfo {
86
87
  pid: number;
87
88
  ppid: number;
@@ -98,15 +99,15 @@ export interface ProcessInfo {
98
99
  }
99
100
  export interface ManagedProcess {
100
101
  pid: number;
101
- writeStdin(data: Uint8Array | string): void;
102
- closeStdin(): void;
102
+ writeStdin(data: Uint8Array | string): Promise<void>;
103
+ closeStdin(): Promise<void>;
103
104
  kill(signal?: number): void;
104
105
  wait(): Promise<number>;
105
106
  readonly exitCode: number | null;
106
107
  }
107
108
  export interface ShellHandle {
108
109
  pid: number;
109
- write(data: Uint8Array | string): void;
110
+ write(data: Uint8Array | string): Promise<void>;
110
111
  onData: ((data: Uint8Array) => void) | null;
111
112
  resize(cols: number, rows: number): void;
112
113
  kill(signal?: number): void;
@@ -168,7 +169,7 @@ export interface Permissions {
168
169
  childProcess?: ChildProcessPermissions;
169
170
  process?: ProcessPermissions;
170
171
  env?: EnvPermissions;
171
- tool?: ToolPermissions;
172
+ binding?: BindingPermissions;
172
173
  }
173
174
  export interface ResourceBudgets {
174
175
  maxOutputBytes?: number;
@@ -229,6 +230,7 @@ export interface SystemDriver {
229
230
  network?: NetworkAdapter;
230
231
  commandExecutor?: CommandExecutor;
231
232
  permissions?: Permissions;
233
+ mounts: readonly NodeModulesMountConfig[];
232
234
  runtime: {
233
235
  process: ProcessConfig;
234
236
  os: OSConfig;
@@ -263,6 +265,13 @@ export interface NodeRuntimeDriverFactory {
263
265
  export interface KernelInterface {
264
266
  vfs: VirtualFileSystem;
265
267
  }
268
+ export interface KernelRecursiveDirEntry {
269
+ name: string;
270
+ path: string;
271
+ isDirectory: boolean;
272
+ isSymbolicLink: boolean;
273
+ size: number;
274
+ }
266
275
  export interface Kernel extends KernelInterface {
267
276
  mount(driver: KernelRuntimeDriver): Promise<void>;
268
277
  dispose(): Promise<void>;
@@ -278,11 +287,18 @@ export interface Kernel extends KernelInterface {
278
287
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
279
288
  mkdir(path: string): Promise<void>;
280
289
  readdir(path: string): Promise<string[]>;
290
+ readdirRecursive(path: string, options?: {
291
+ maxDepth?: number;
292
+ }): Promise<KernelRecursiveDirEntry[]>;
281
293
  stat(path: string): Promise<VirtualStat>;
282
294
  exists(path: string): Promise<boolean>;
283
295
  removeFile(path: string): Promise<void>;
284
296
  removeDir(path: string): Promise<void>;
297
+ removePath(path: string, options?: {
298
+ recursive?: boolean;
299
+ }): Promise<void>;
285
300
  rename(oldPath: string, newPath: string): Promise<void>;
301
+ movePath(oldPath: string, newPath: string): Promise<void>;
286
302
  readonly commands: ReadonlyMap<string, string>;
287
303
  readonly processes: ReadonlyMap<number, ProcessInfo>;
288
304
  readonly env: Record<string, string>;
@@ -304,17 +320,14 @@ export interface BindingTree {
304
320
  [key: string]: BindingFunction | BindingTree;
305
321
  }
306
322
  export type BindingFunction = (...args: unknown[]) => unknown;
307
- export interface ModuleAccessOptions {
308
- cwd?: string;
309
- }
310
323
  export interface NodeDriverOptions {
311
324
  filesystem?: VirtualFileSystem;
312
325
  networkAdapter?: NetworkAdapter;
313
326
  commandExecutor?: CommandExecutor;
314
327
  permissions?: Permissions;
328
+ mounts?: readonly NodeModulesMountConfig[];
315
329
  processConfig?: ProcessConfig;
316
330
  osConfig?: OSConfig;
317
- moduleAccess?: ModuleAccessOptions;
318
331
  }
319
332
  export interface DefaultNetworkAdapterOptions {
320
333
  loopbackExemptPorts?: number[];