@anthropic-ai/sandbox-runtime 0.0.1

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 (62) hide show
  1. package/README.md +497 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +75 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/index.d.ts +4 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +4 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/sandbox/http-proxy.d.ts +7 -0
  11. package/dist/sandbox/http-proxy.d.ts.map +1 -0
  12. package/dist/sandbox/http-proxy.js +118 -0
  13. package/dist/sandbox/http-proxy.js.map +1 -0
  14. package/dist/sandbox/linux-sandbox-utils.d.ts +60 -0
  15. package/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -0
  16. package/dist/sandbox/linux-sandbox-utils.js +333 -0
  17. package/dist/sandbox/linux-sandbox-utils.js.map +1 -0
  18. package/dist/sandbox/macos-sandbox-utils.d.ts +53 -0
  19. package/dist/sandbox/macos-sandbox-utils.d.ts.map +1 -0
  20. package/dist/sandbox/macos-sandbox-utils.js +496 -0
  21. package/dist/sandbox/macos-sandbox-utils.js.map +1 -0
  22. package/dist/sandbox/sandbox-manager.d.ts +34 -0
  23. package/dist/sandbox/sandbox-manager.d.ts.map +1 -0
  24. package/dist/sandbox/sandbox-manager.js +655 -0
  25. package/dist/sandbox/sandbox-manager.js.map +1 -0
  26. package/dist/sandbox/sandbox-schemas.d.ts +93 -0
  27. package/dist/sandbox/sandbox-schemas.d.ts.map +1 -0
  28. package/dist/sandbox/sandbox-schemas.js +231 -0
  29. package/dist/sandbox/sandbox-schemas.js.map +1 -0
  30. package/dist/sandbox/sandbox-utils.d.ts +49 -0
  31. package/dist/sandbox/sandbox-utils.d.ts.map +1 -0
  32. package/dist/sandbox/sandbox-utils.js +345 -0
  33. package/dist/sandbox/sandbox-utils.js.map +1 -0
  34. package/dist/sandbox/sandbox-violation-store.d.ts +19 -0
  35. package/dist/sandbox/sandbox-violation-store.d.ts.map +1 -0
  36. package/dist/sandbox/sandbox-violation-store.js +54 -0
  37. package/dist/sandbox/sandbox-violation-store.js.map +1 -0
  38. package/dist/sandbox/socks-proxy.d.ts +13 -0
  39. package/dist/sandbox/socks-proxy.d.ts.map +1 -0
  40. package/dist/sandbox/socks-proxy.js +95 -0
  41. package/dist/sandbox/socks-proxy.js.map +1 -0
  42. package/dist/utils/debug.d.ts +7 -0
  43. package/dist/utils/debug.d.ts.map +1 -0
  44. package/dist/utils/debug.js +22 -0
  45. package/dist/utils/debug.js.map +1 -0
  46. package/dist/utils/exec.d.ts +13 -0
  47. package/dist/utils/exec.d.ts.map +1 -0
  48. package/dist/utils/exec.js +38 -0
  49. package/dist/utils/exec.js.map +1 -0
  50. package/dist/utils/platform.d.ts +6 -0
  51. package/dist/utils/platform.d.ts.map +1 -0
  52. package/dist/utils/platform.js +16 -0
  53. package/dist/utils/platform.js.map +1 -0
  54. package/dist/utils/ripgrep.d.ts +16 -0
  55. package/dist/utils/ripgrep.d.ts.map +1 -0
  56. package/dist/utils/ripgrep.js +57 -0
  57. package/dist/utils/ripgrep.js.map +1 -0
  58. package/dist/utils/settings.d.ts +147 -0
  59. package/dist/utils/settings.d.ts.map +1 -0
  60. package/dist/utils/settings.js +244 -0
  61. package/dist/utils/settings.js.map +1 -0
  62. package/package.json +72 -0
@@ -0,0 +1,345 @@
1
+ import { homedir } from 'os';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+ import { getPlatform } from '../utils/platform.js';
5
+ import { ripGrep } from '../utils/ripgrep.js';
6
+ /**
7
+ * Dangerous files that should be protected from writes.
8
+ * These files can be used for code execution or data exfiltration.
9
+ */
10
+ const DANGEROUS_FILES = [
11
+ '.gitconfig',
12
+ '.gitmodules',
13
+ '.bashrc',
14
+ '.bash_profile',
15
+ '.zshrc',
16
+ '.zprofile',
17
+ '.profile',
18
+ '.ripgreprc',
19
+ '.mcp.json',
20
+ ];
21
+ /**
22
+ * Dangerous directories that should be protected from writes.
23
+ * These directories contain sensitive configuration or executable files.
24
+ */
25
+ const DANGEROUS_DIRECTORIES = ['.git', '.vscode', '.idea'];
26
+ /**
27
+ * Normalizes a path for case-insensitive comparison.
28
+ * This prevents bypassing security checks using mixed-case paths on case-insensitive
29
+ * filesystems (macOS/Windows) like `.cLauDe/Settings.locaL.json`.
30
+ *
31
+ * We always normalize to lowercase regardless of platform for consistent security.
32
+ * @param path The path to normalize
33
+ * @returns The lowercase path for safe comparison
34
+ */
35
+ function normalizeCaseForComparison(pathStr) {
36
+ return pathStr.toLowerCase();
37
+ }
38
+ /**
39
+ * Check if a path pattern contains glob characters
40
+ */
41
+ export function containsGlobChars(pathPattern) {
42
+ return (pathPattern.includes('*') ||
43
+ pathPattern.includes('?') ||
44
+ pathPattern.includes('[') ||
45
+ pathPattern.includes(']'));
46
+ }
47
+ /**
48
+ * Remove trailing /** glob suffix from a path pattern
49
+ * Used to normalize path patterns since /** just means "directory and everything under it"
50
+ */
51
+ export function removeTrailingGlobSuffix(pathPattern) {
52
+ return pathPattern.replace(/\/\*\*$/, '');
53
+ }
54
+ /**
55
+ * Normalize a path for use in sandbox configurations
56
+ * Handles:
57
+ * - Tilde (~) expansion for home directory
58
+ * - Relative paths (./foo, ../foo, etc.) converted to absolute
59
+ * - Absolute paths remain unchanged
60
+ * - Symlinks are resolved to their real paths for non-glob patterns
61
+ * - Glob patterns preserve wildcards after path normalization
62
+ *
63
+ * Returns the absolute path with symlinks resolved (or normalized glob pattern)
64
+ */
65
+ export function normalizePathForSandbox(pathPattern) {
66
+ const cwd = process.cwd();
67
+ let normalizedPath = pathPattern;
68
+ // Expand ~ to home directory
69
+ if (pathPattern === '~') {
70
+ normalizedPath = homedir();
71
+ }
72
+ else if (pathPattern.startsWith('~/')) {
73
+ normalizedPath = homedir() + pathPattern.slice(1);
74
+ }
75
+ else if (pathPattern.startsWith('./') || pathPattern.startsWith('../')) {
76
+ // Convert relative to absolute based on current working directory
77
+ normalizedPath = path.resolve(cwd, pathPattern);
78
+ }
79
+ else if (!path.isAbsolute(pathPattern)) {
80
+ // Handle other relative paths (e.g., ".", "..", "foo/bar")
81
+ normalizedPath = path.resolve(cwd, pathPattern);
82
+ }
83
+ // For glob patterns, don't try to resolve symlinks (they don't exist as literal paths)
84
+ if (containsGlobChars(normalizedPath)) {
85
+ return normalizedPath;
86
+ }
87
+ // Resolve symlinks to real paths to avoid bwrap issues
88
+ try {
89
+ normalizedPath = fs.realpathSync(normalizedPath);
90
+ }
91
+ catch {
92
+ // If path doesn't exist or can't be resolved, keep the normalized path
93
+ }
94
+ return normalizedPath;
95
+ }
96
+ /**
97
+ * Get recommended system paths that should be writable for commands to work properly
98
+ *
99
+ * WARNING: These default paths are intentionally broad for compatibility but may
100
+ * allow access to files from other processes. In highly security-sensitive
101
+ * environments, you should configure more restrictive write paths.
102
+ */
103
+ export function getDefaultWritePaths() {
104
+ const homeDir = homedir();
105
+ const recommendedPaths = [
106
+ '/dev/stdout',
107
+ '/dev/stderr',
108
+ '/dev/null',
109
+ '/dev/tty',
110
+ '/dev/dtracehelper',
111
+ '/dev/autofs_nowait',
112
+ path.join(homeDir, '.npm/_logs'),
113
+ '.',
114
+ ];
115
+ return recommendedPaths;
116
+ }
117
+ /**
118
+ * Get mandatory deny paths within allowed write areas
119
+ * This uses ripgrep to scan the filesystem for dangerous files and directories
120
+ * Returns absolute paths that must be blocked from writes
121
+ */
122
+ export async function getMandatoryDenyWithinAllow() {
123
+ const denyPaths = [];
124
+ const cwd = process.cwd();
125
+ // Always deny writes to settings.json files
126
+ // Block in home directory
127
+ denyPaths.push(path.join(homedir(), '.claude', 'settings.json'));
128
+ // Block in current directory
129
+ denyPaths.push(path.resolve(cwd, '.claude', 'settings.json'));
130
+ denyPaths.push(path.resolve(cwd, '.claude', 'settings.local.json'));
131
+ // Use shared constants for dangerous files
132
+ const dangerousFiles = [...DANGEROUS_FILES];
133
+ // Use shared constants plus additional Claude-specific directories
134
+ // Note: We don't include .git as a whole directory since we need it to be writable for git operations
135
+ // Instead, we'll block specific dangerous paths within .git (hooks and config) below
136
+ const dangerousDirectories = [
137
+ ...DANGEROUS_DIRECTORIES.filter(d => d !== '.git'),
138
+ '.claude/commands',
139
+ '.claude/agents',
140
+ ];
141
+ // Create an AbortController for ripgrep operations
142
+ const abortController = new AbortController();
143
+ // Add absolute paths for dangerous files in CWD
144
+ for (const fileName of dangerousFiles) {
145
+ // Always include the potential path in CWD (even if file doesn't exist yet)
146
+ const cwdFilePath = path.resolve(cwd, fileName);
147
+ denyPaths.push(cwdFilePath);
148
+ // Find all existing instances of this file in CWD and subdirectories using ripgrep
149
+ try {
150
+ // Use ripgrep to find files with exact name match (case-insensitive)
151
+ // -g/--glob: Include/exclude files matching this glob pattern
152
+ // --files: List files that would be searched
153
+ // --hidden: Search hidden files
154
+ // --iglob: Case-insensitive glob matching to catch .Bashrc, .BASHRC, etc.
155
+ const matches = await ripGrep([
156
+ '--files',
157
+ '--hidden',
158
+ '--iglob',
159
+ fileName,
160
+ '-g',
161
+ '!**/node_modules/**',
162
+ ], cwd, abortController.signal);
163
+ // Convert relative paths to absolute paths
164
+ const absoluteMatches = matches.map(match => path.resolve(cwd, match));
165
+ denyPaths.push(...absoluteMatches);
166
+ }
167
+ catch (error) {
168
+ // If ripgrep fails, we cannot safely determine all dangerous files
169
+ throw new Error(`Failed to scan for dangerous file "${fileName}": ${error instanceof Error ? error.message : String(error)}`);
170
+ }
171
+ }
172
+ // Add absolute paths for dangerous directories in CWD
173
+ for (const dirName of dangerousDirectories) {
174
+ // Always include the potential path in CWD (even if directory doesn't exist yet)
175
+ const cwdDirPath = path.resolve(cwd, dirName);
176
+ denyPaths.push(cwdDirPath);
177
+ // Find all existing instances of this directory in CWD and subdirectories using ripgrep
178
+ try {
179
+ // Use ripgrep to find directories (case-insensitive)
180
+ // Note: ripgrep lists files, so we need to find files within these directories
181
+ // and then extract the directory paths
182
+ const pattern = `**/${dirName}/**`;
183
+ const matches = await ripGrep([
184
+ '--files',
185
+ '--hidden',
186
+ '--iglob',
187
+ pattern,
188
+ '-g',
189
+ '!**/node_modules/**',
190
+ ], cwd, abortController.signal);
191
+ // Extract directory paths from file paths
192
+ const dirPaths = new Set();
193
+ for (const match of matches) {
194
+ const absolutePath = path.resolve(cwd, match);
195
+ // Find the dangerous directory in the path (case-insensitive)
196
+ const segments = absolutePath.split(path.sep);
197
+ const normalizedDirName = normalizeCaseForComparison(dirName);
198
+ // Find the directory using case-insensitive comparison
199
+ const dirIndex = segments.findIndex(segment => normalizeCaseForComparison(segment) === normalizedDirName);
200
+ if (dirIndex !== -1) {
201
+ // Reconstruct path up to and including the dangerous directory
202
+ const dirPath = segments.slice(0, dirIndex + 1).join(path.sep);
203
+ dirPaths.add(dirPath);
204
+ }
205
+ }
206
+ denyPaths.push(...dirPaths);
207
+ }
208
+ catch (error) {
209
+ // If ripgrep fails, we cannot safely determine all dangerous directories
210
+ throw new Error(`Failed to scan for dangerous directory "${dirName}": ${error instanceof Error ? error.message : String(error)}`);
211
+ }
212
+ }
213
+ // Special handling for dangerous .git paths
214
+ // We block specific paths within .git that can be used for code execution
215
+ const dangerousGitPaths = [
216
+ '.git/hooks', // Block all hook files to prevent code execution via git hooks
217
+ '.git/config', // Block config file to prevent dangerous config options like core.fsmonitor
218
+ ];
219
+ for (const gitPath of dangerousGitPaths) {
220
+ // Add the path in the current working directory
221
+ const absoluteGitPath = path.resolve(cwd, gitPath);
222
+ denyPaths.push(absoluteGitPath);
223
+ // Also find .git directories in subdirectories and block their hooks/config
224
+ // This handles nested repositories (case-insensitive)
225
+ try {
226
+ // Find all .git directories by looking for .git/HEAD files (case-insensitive)
227
+ const gitHeadFiles = await ripGrep([
228
+ '--files',
229
+ '--hidden',
230
+ '--iglob',
231
+ '**/.git/HEAD',
232
+ '-g',
233
+ '!**/node_modules/**',
234
+ ], cwd, abortController.signal);
235
+ for (const gitHeadFile of gitHeadFiles) {
236
+ // Get the .git directory path
237
+ const gitDir = path.dirname(gitHeadFile);
238
+ // Add the dangerous path within this .git directory
239
+ if (gitPath === '.git/hooks') {
240
+ const hooksPath = path.join(gitDir, 'hooks');
241
+ denyPaths.push(hooksPath);
242
+ }
243
+ else if (gitPath === '.git/config') {
244
+ const configPath = path.join(gitDir, 'config');
245
+ denyPaths.push(configPath);
246
+ }
247
+ }
248
+ }
249
+ catch (error) {
250
+ // If ripgrep fails, we cannot safely determine all .git repositories
251
+ throw new Error(`Failed to scan for .git directories: ${error instanceof Error ? error.message : String(error)}`);
252
+ }
253
+ }
254
+ // Remove duplicates and return
255
+ return Array.from(new Set(denyPaths));
256
+ }
257
+ /**
258
+ * Generate proxy environment variables for sandboxed processes
259
+ */
260
+ export function generateProxyEnvVars(httpProxyPort, socksProxyPort) {
261
+ const envVars = [`SANDBOX_RUNTIME=1`];
262
+ // If no proxy ports provided, return empty array
263
+ if (!httpProxyPort && !socksProxyPort) {
264
+ return envVars;
265
+ }
266
+ // Always set NO_PROXY to exclude localhost and private networks from proxying
267
+ const noProxyAddresses = [
268
+ 'localhost',
269
+ '127.0.0.1',
270
+ '::1',
271
+ '*.local',
272
+ '.local',
273
+ '169.254.0.0/16', // Link-local
274
+ '10.0.0.0/8', // Private network
275
+ '172.16.0.0/12', // Private network
276
+ '192.168.0.0/16', // Private network
277
+ ].join(',');
278
+ envVars.push(`NO_PROXY=${noProxyAddresses}`);
279
+ envVars.push(`no_proxy=${noProxyAddresses}`);
280
+ if (httpProxyPort) {
281
+ envVars.push(`HTTP_PROXY=http://localhost:${httpProxyPort}`);
282
+ envVars.push(`HTTPS_PROXY=http://localhost:${httpProxyPort}`);
283
+ // Lowercase versions for compatibility with some tools
284
+ envVars.push(`http_proxy=http://localhost:${httpProxyPort}`);
285
+ envVars.push(`https_proxy=http://localhost:${httpProxyPort}`);
286
+ }
287
+ if (socksProxyPort) {
288
+ // Use socks5h:// for proper DNS resolution through proxy
289
+ envVars.push(`ALL_PROXY=socks5h://localhost:${socksProxyPort}`);
290
+ envVars.push(`all_proxy=socks5h://localhost:${socksProxyPort}`);
291
+ // Configure Git to use SSH through SOCKS proxy (platform-aware)
292
+ if (getPlatform() === 'macos') {
293
+ // macOS has nc available
294
+ envVars.push(`GIT_SSH_COMMAND="ssh -o ProxyCommand='nc -X 5 -x localhost:${socksProxyPort} %h %p'"`);
295
+ }
296
+ // FTP proxy support (use socks5h for DNS resolution through proxy)
297
+ envVars.push(`FTP_PROXY=socks5h://localhost:${socksProxyPort}`);
298
+ envVars.push(`ftp_proxy=socks5h://localhost:${socksProxyPort}`);
299
+ // rsync proxy support
300
+ envVars.push(`RSYNC_PROXY=localhost:${socksProxyPort}`);
301
+ // Database tools NOTE: Most database clients don't have built-in proxy support
302
+ // You typically need to use SSH tunneling or a SOCKS wrapper like tsocks/proxychains
303
+ // Docker CLI uses HTTP for the API
304
+ // This makes Docker use the HTTP proxy for registry operations
305
+ envVars.push(`DOCKER_HTTP_PROXY=http://localhost:${httpProxyPort || socksProxyPort}`);
306
+ envVars.push(`DOCKER_HTTPS_PROXY=http://localhost:${httpProxyPort || socksProxyPort}`);
307
+ // Kubernetes kubectl - uses standard HTTPS_PROXY
308
+ // kubectl respects HTTPS_PROXY which we already set above
309
+ // AWS CLI - uses standard HTTPS_PROXY (v2 supports it well)
310
+ // AWS CLI v2 respects HTTPS_PROXY which we already set above
311
+ // Google Cloud SDK - has specific proxy settings
312
+ // Use HTTPS proxy to match other HTTP-based tools
313
+ if (httpProxyPort) {
314
+ envVars.push(`CLOUDSDK_PROXY_TYPE=https`);
315
+ envVars.push(`CLOUDSDK_PROXY_ADDRESS=localhost`);
316
+ envVars.push(`CLOUDSDK_PROXY_PORT=${httpProxyPort}`);
317
+ }
318
+ // Azure CLI - uses HTTPS_PROXY
319
+ // Azure CLI respects HTTPS_PROXY which we already set above
320
+ // Terraform - uses standard HTTP/HTTPS proxy vars
321
+ // Terraform respects HTTP_PROXY/HTTPS_PROXY which we already set above
322
+ // gRPC-based tools - use standard proxy vars
323
+ envVars.push(`GRPC_PROXY=socks5h://localhost:${socksProxyPort}`);
324
+ envVars.push(`grpc_proxy=socks5h://localhost:${socksProxyPort}`);
325
+ }
326
+ // WARNING: Do not set HTTP_PROXY/HTTPS_PROXY to SOCKS URLs when only SOCKS proxy is available
327
+ // Most HTTP clients do not support SOCKS URLs in these variables and will fail, and we want
328
+ // to avoid overriding the client otherwise respecting the ALL_PROXY env var which points to SOCKS.
329
+ return envVars;
330
+ }
331
+ /**
332
+ * Encode a command for sandbox monitoring
333
+ * Truncates to 100 chars and base64 encodes to avoid parsing issues
334
+ */
335
+ export function encodeSandboxedCommand(command) {
336
+ const truncatedCommand = command.slice(0, 100);
337
+ return Buffer.from(truncatedCommand).toString('base64');
338
+ }
339
+ /**
340
+ * Decode a base64-encoded command from sandbox monitoring
341
+ */
342
+ export function decodeSandboxedCommand(encodedCommand) {
343
+ return Buffer.from(encodedCommand, 'base64').toString('utf8');
344
+ }
345
+ //# sourceMappingURL=sandbox-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-utils.js","sourceRoot":"","sources":["../../src/sandbox/sandbox-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type SandboxViolationEvent } from './macos-sandbox-utils.js';
2
+ /**
3
+ * In-memory tail for sandbox violations
4
+ */
5
+ export declare class SandboxViolationStore {
6
+ private violations;
7
+ private totalCount;
8
+ private readonly maxSize;
9
+ private listeners;
10
+ addViolation(violation: SandboxViolationEvent): void;
11
+ getViolations(limit?: number): SandboxViolationEvent[];
12
+ getCount(): number;
13
+ getTotalCount(): number;
14
+ getViolationsForCommand(command: string): SandboxViolationEvent[];
15
+ clear(): void;
16
+ subscribe(listener: (violations: SandboxViolationEvent[]) => void): () => void;
17
+ private notifyListeners;
18
+ }
19
+ //# sourceMappingURL=sandbox-violation-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-violation-store.d.ts","sourceRoot":"","sources":["../../src/sandbox/sandbox-violation-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAGrE;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAM;IAC9B,OAAO,CAAC,SAAS,CACN;IAEX,YAAY,CAAC,SAAS,EAAE,qBAAqB,GAAG,IAAI;IASpD,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,qBAAqB,EAAE;IAOtD,QAAQ,IAAI,MAAM;IAIlB,aAAa,IAAI,MAAM;IAIvB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE;IAKjE,KAAK,IAAI,IAAI;IAMb,SAAS,CACP,QAAQ,EAAE,CAAC,UAAU,EAAE,qBAAqB,EAAE,KAAK,IAAI,GACtD,MAAM,IAAI;IAQb,OAAO,CAAC,eAAe;CAKxB"}
@@ -0,0 +1,54 @@
1
+ import { encodeSandboxedCommand } from './sandbox-utils.js';
2
+ /**
3
+ * In-memory tail for sandbox violations
4
+ */
5
+ export class SandboxViolationStore {
6
+ constructor() {
7
+ this.violations = [];
8
+ this.totalCount = 0;
9
+ this.maxSize = 100;
10
+ this.listeners = new Set();
11
+ }
12
+ addViolation(violation) {
13
+ this.violations.push(violation);
14
+ this.totalCount++;
15
+ if (this.violations.length > this.maxSize) {
16
+ this.violations = this.violations.slice(-this.maxSize);
17
+ }
18
+ this.notifyListeners();
19
+ }
20
+ getViolations(limit) {
21
+ if (limit === undefined) {
22
+ return [...this.violations];
23
+ }
24
+ return this.violations.slice(-limit);
25
+ }
26
+ getCount() {
27
+ return this.violations.length;
28
+ }
29
+ getTotalCount() {
30
+ return this.totalCount;
31
+ }
32
+ getViolationsForCommand(command) {
33
+ const commandBase64 = encodeSandboxedCommand(command);
34
+ return this.violations.filter(v => v.encodedCommand === commandBase64);
35
+ }
36
+ clear() {
37
+ this.violations = [];
38
+ // Don't reset totalCount when clearing
39
+ this.notifyListeners();
40
+ }
41
+ subscribe(listener) {
42
+ this.listeners.add(listener);
43
+ listener(this.getViolations());
44
+ return () => {
45
+ this.listeners.delete(listener);
46
+ };
47
+ }
48
+ notifyListeners() {
49
+ // Always notify with all violations so listeners can track the full count
50
+ const violations = this.getViolations();
51
+ this.listeners.forEach(listener => listener(violations));
52
+ }
53
+ }
54
+ //# sourceMappingURL=sandbox-violation-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-violation-store.js","sourceRoot":"","sources":["../../src/sandbox/sandbox-violation-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAE3D;;GAEG;AACH,MAAM,OAAO,qBAAqB;IAAlC;QACU,eAAU,GAA4B,EAAE,CAAA;QACxC,eAAU,GAAG,CAAC,CAAA;QACL,YAAO,GAAG,GAAG,CAAA;QACtB,cAAS,GACf,IAAI,GAAG,EAAE,CAAA;IAoDb,CAAC;IAlDC,YAAY,CAAC,SAAgC;QAC3C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC/B,IAAI,CAAC,UAAU,EAAE,CAAA;QACjB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACxD,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAA;IACxB,CAAC;IAED,aAAa,CAAC,KAAc;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAA;IAC/B,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,uBAAuB,CAAC,OAAe;QACrC,MAAM,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;QACrD,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,aAAa,CAAC,CAAA;IACxE,CAAC;IAED,KAAK;QACH,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACpB,uCAAuC;QACvC,IAAI,CAAC,eAAe,EAAE,CAAA;IACxB,CAAC;IAED,SAAS,CACP,QAAuD;QAEvD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC5B,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;QAC9B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACjC,CAAC,CAAA;IACH,CAAC;IAEO,eAAe;QACrB,0EAA0E;QAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACvC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAA;IAC1D,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { Socks5Server } from '@pondwader/socks5-server';
2
+ export interface SocksProxyServerOptions {
3
+ filter(port: number, host: string): Promise<boolean> | boolean;
4
+ }
5
+ export interface SocksProxyWrapper {
6
+ server: Socks5Server;
7
+ getPort(): number | undefined;
8
+ listen(port: number, hostname: string): Promise<number>;
9
+ close(): Promise<void>;
10
+ unref(): void;
11
+ }
12
+ export declare function createSocksProxyServer(options: SocksProxyServerOptions): SocksProxyWrapper;
13
+ //# sourceMappingURL=socks-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-proxy.d.ts","sourceRoot":"","sources":["../../src/sandbox/socks-proxy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAI5D,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,IAAI,MAAM,GAAG,SAAS,CAAA;IAC7B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,iBAAiB,CAqGnB"}
@@ -0,0 +1,95 @@
1
+ import { createServer } from '@pondwader/socks5-server';
2
+ import { logForDebugging } from '../utils/debug.js';
3
+ export function createSocksProxyServer(options) {
4
+ const socksServer = createServer();
5
+ socksServer.setRulesetValidator(async (conn) => {
6
+ try {
7
+ const hostname = conn.destAddress;
8
+ const port = conn.destPort;
9
+ logForDebugging(`Connection request to ${hostname}:${port}`);
10
+ const allowed = await options.filter(port, hostname);
11
+ if (!allowed) {
12
+ logForDebugging(`Connection blocked to ${hostname}:${port}`, {
13
+ level: 'error',
14
+ });
15
+ return false;
16
+ }
17
+ logForDebugging(`Connection allowed to ${hostname}:${port}`);
18
+ return true;
19
+ }
20
+ catch (error) {
21
+ logForDebugging(`Error validating connection: ${error}`, {
22
+ level: 'error',
23
+ });
24
+ return false;
25
+ }
26
+ });
27
+ return {
28
+ server: socksServer,
29
+ getPort() {
30
+ // Access the internal server to get the port
31
+ // We need to use type assertion here as the server property is private
32
+ try {
33
+ const serverInternal = socksServer?.server;
34
+ if (serverInternal && typeof serverInternal?.address === 'function') {
35
+ const address = serverInternal.address();
36
+ if (address && typeof address === 'object' && 'port' in address) {
37
+ return address.port;
38
+ }
39
+ }
40
+ }
41
+ catch (error) {
42
+ // Server might not be listening yet or property access failed
43
+ logForDebugging(`Error getting port: ${error}`, { level: 'error' });
44
+ }
45
+ return undefined;
46
+ },
47
+ listen(port, hostname) {
48
+ return new Promise((resolve, reject) => {
49
+ const listeningCallback = () => {
50
+ const actualPort = this.getPort();
51
+ if (actualPort) {
52
+ logForDebugging(`SOCKS proxy listening on ${hostname}:${actualPort}`);
53
+ resolve(actualPort);
54
+ }
55
+ else {
56
+ reject(new Error('Failed to get SOCKS proxy server port'));
57
+ }
58
+ };
59
+ socksServer.listen(port, hostname, listeningCallback);
60
+ });
61
+ },
62
+ async close() {
63
+ return new Promise((resolve, reject) => {
64
+ socksServer.close(error => {
65
+ if (error) {
66
+ // Only reject for actual errors, not for "already closed" states
67
+ // Check for common "already closed" error patterns
68
+ const errorMessage = error.message?.toLowerCase() || '';
69
+ const isAlreadyClosed = errorMessage.includes('not running') ||
70
+ errorMessage.includes('already closed') ||
71
+ errorMessage.includes('not listening');
72
+ if (!isAlreadyClosed) {
73
+ reject(error);
74
+ return;
75
+ }
76
+ }
77
+ resolve();
78
+ });
79
+ });
80
+ },
81
+ unref() {
82
+ // Access the internal server to call unref
83
+ try {
84
+ const serverInternal = socksServer?.server;
85
+ if (serverInternal && typeof serverInternal?.unref === 'function') {
86
+ serverInternal.unref();
87
+ }
88
+ }
89
+ catch (error) {
90
+ logForDebugging(`Error calling unref: ${error}`, { level: 'error' });
91
+ }
92
+ },
93
+ };
94
+ }
95
+ //# sourceMappingURL=socks-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-proxy.js","sourceRoot":"","sources":["../../src/sandbox/socks-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Simple debug logging for standalone sandbox
3
+ */
4
+ export declare function logForDebugging(message: string, options?: {
5
+ level?: 'info' | 'error' | 'warn';
6
+ }): void;
7
+ //# sourceMappingURL=debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;CAAE,GAC9C,IAAI,CAmBN"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Simple debug logging for standalone sandbox
3
+ */
4
+ export function logForDebugging(message, options) {
5
+ // Only log if DEBUG environment variable is set
6
+ if (!process.env.DEBUG) {
7
+ return;
8
+ }
9
+ const level = options?.level || 'info';
10
+ const prefix = '[SandboxDebug]';
11
+ switch (level) {
12
+ case 'error':
13
+ console.error(`${prefix} ${message}`);
14
+ break;
15
+ case 'warn':
16
+ console.warn(`${prefix} ${message}`);
17
+ break;
18
+ default:
19
+ console.log(`${prefix} ${message}`);
20
+ }
21
+ }
22
+ //# sourceMappingURL=debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,OAA+C;IAE/C,gDAAgD;IAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACvB,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,MAAM,CAAA;IACtC,MAAM,MAAM,GAAG,gBAAgB,CAAA;IAE/B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAA;YACrC,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAA;YACpC,MAAK;QACP;YACE,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAA;IACvC,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Simple wrapper around execFile that doesn't throw on non-zero exit codes
3
+ * Simplified version for standalone sandbox use
4
+ */
5
+ export declare function execFileNoThrow(file: string, args: string[], options?: {
6
+ timeout?: number;
7
+ cwd?: string;
8
+ }): Promise<{
9
+ stdout: string;
10
+ stderr: string;
11
+ code: number;
12
+ }>;
13
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA4B3D"}