sandboxbox 3.0.48 → 3.0.49

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.
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * SandboxBox CLI - Process Containment Sandbox
5
+ * Lightweight process isolation for CLI tools
6
+ */
7
+
8
+ import { resolve } from 'path';
9
+ import { color } from './utils/colors.js';
10
+ import { showBanner, showHelp } from './utils/ui.js';
11
+ import { buildCommand, runCommand, shellCommand, claudeCommand, versionCommand } from './utils/commands/index.js';
12
+
13
+ async function main() {
14
+ const args = process.argv.slice(2);
15
+ showBanner();
16
+
17
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
18
+ showHelp();
19
+ process.exit(0);
20
+ }
21
+
22
+ const command = args[0].toLowerCase();
23
+ const commandArgs = args.slice(1);
24
+
25
+ try {
26
+ switch (command) {
27
+ case 'build':
28
+ const dockerfilePath = commandArgs[0];
29
+ if (!buildCommand(dockerfilePath)) process.exit(1);
30
+ break;
31
+
32
+ case 'run':
33
+ if (commandArgs.length === 0) {
34
+ console.log(color('red', '❌ Please specify a project directory'));
35
+ console.log(color('yellow', 'Usage: npx sandboxbox run <project-dir> [command]'));
36
+ process.exit(1);
37
+ }
38
+ const projectDir = resolve(process.cwd(), commandArgs[0]);
39
+ const cmd = commandArgs.slice(1).join(' ');
40
+ if (!(await runCommand(projectDir, cmd))) process.exit(1);
41
+ break;
42
+
43
+ case 'shell':
44
+ if (commandArgs.length === 0) {
45
+ console.log(color('red', '❌ Please specify a project directory'));
46
+ console.log(color('yellow', 'Usage: npx sandboxbox shell <project-dir>'));
47
+ process.exit(1);
48
+ }
49
+ const shellProjectDir = resolve(process.cwd(), commandArgs[0]);
50
+ if (!(await shellCommand(shellProjectDir))) process.exit(1);
51
+ break;
52
+
53
+ case 'claude':
54
+ if (commandArgs.length === 0) {
55
+ console.log(color('red', '❌ Please specify a project directory'));
56
+ console.log(color('yellow', 'Usage: npx sandboxbox claude <project-dir> [prompt] [--host] [--headless]'));
57
+ process.exit(1);
58
+ }
59
+
60
+ // Parse flags from command args
61
+ const claudeArgs = commandArgs.slice(1);
62
+ const flags = {
63
+ useHostSettings: claudeArgs.includes('--host'),
64
+ headlessMode: claudeArgs.includes('--headless')
65
+ };
66
+
67
+ // Remove flags from prompt
68
+ const promptArgs = claudeArgs.filter(arg => arg !== '--host' && arg !== '--headless');
69
+ const claudeProjectDir = resolve(process.cwd(), commandArgs[0]);
70
+ const claudePrompt = promptArgs.join(' ');
71
+
72
+ if (!(await claudeCommand(claudeProjectDir, claudePrompt, flags))) process.exit(1);
73
+ break;
74
+
75
+ case 'version':
76
+ if (!versionCommand()) process.exit(1);
77
+ break;
78
+
79
+ default:
80
+ console.log(color('red', `❌ Unknown command: ${command}`));
81
+ console.log(color('yellow', 'Use --help for usage information'));
82
+ process.exit(1);
83
+ }
84
+ } catch (error) {
85
+ console.log(color('red', `\n❌ Fatal error: ${error.message}`));
86
+ process.exit(1);
87
+ }
88
+ }
89
+
90
+ main();
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "sandboxbox",
3
+ "version": "3.0.46",
4
+ "description": "Lightweight process containment sandbox for CLI tools - Playwright, Claude Code, and more. Pure Node.js, no dependencies.",
5
+ "type": "module",
6
+ "main": "cli.js",
7
+ "bin": {
8
+ "sandboxbox": "cli.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node cli.js"
12
+ },
13
+ "keywords": [
14
+ "sandbox",
15
+ "process-isolation",
16
+ "playwright",
17
+ "claude-code",
18
+ "cli-tools",
19
+ "environment-isolation",
20
+ "cross-platform",
21
+ "windows",
22
+ "macos",
23
+ "linux",
24
+ "portable",
25
+ "npm",
26
+ "npx"
27
+ ],
28
+ "author": "",
29
+ "license": "MIT",
30
+ "dependencies": {},
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/AnEntrypoint/sandboxbox.git"
34
+ },
35
+ "homepage": "https://github.com/AnEntrypoint/sandboxbox#readme",
36
+ "bugs": {
37
+ "url": "https://github.com/AnEntrypoint/sandboxbox/issues"
38
+ }
39
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "https://schemas.modelcontextprotocol.io/0.1.0/mcp.json",
3
+ "pluginTimeout": 5000,
4
+ "alwaysThinkingEnabled": false,
5
+ "mcpServers": {
6
+ "glootie": {
7
+ "command": "npx",
8
+ "args": ["-y", "mcp-glootie@latest"]
9
+ },
10
+ "playwright": {
11
+ "command": "npx",
12
+ "args": ["-y", "@playwright/mcp@latest"]
13
+ },
14
+ "vexify": {
15
+ "command": "npx",
16
+ "args": ["-y", "vexify@latest", "mcp"]
17
+ }
18
+ },
19
+ "hooks": {
20
+ "SessionStart": [
21
+ {
22
+ "matcher": "*",
23
+ "hooks": [
24
+ {
25
+ "type": "command",
26
+ "command": "curl https://raw.githubusercontent.com/AnEntrypoint/glootie-cc/refs/heads/master/start.md"
27
+ },
28
+ {
29
+ "type": "command",
30
+ "command": "npx -y mcp-thorns@latest"
31
+ },
32
+ {
33
+ "type": "command",
34
+ "command": "npx -y wfgy@latest hook"
35
+ }
36
+ ]
37
+ }
38
+ ]
39
+ }
40
+ }
@@ -0,0 +1 @@
1
+ This is a test file created by Claude Code.
@@ -0,0 +1,129 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+
4
+ export class ClaudeOptimizer {
5
+ constructor(sandboxDir) {
6
+ this.sandboxDir = sandboxDir;
7
+ this.claudeDir = join(sandboxDir, '.claude');
8
+ }
9
+
10
+ // Optimize Claude settings for faster startup
11
+ optimizeSettings() {
12
+ const settingsPath = join(this.claudeDir, 'settings.json');
13
+
14
+ // Load existing settings or create optimized defaults
15
+ let settings = {};
16
+ if (existsSync(settingsPath)) {
17
+ try {
18
+ settings = JSON.parse(require('fs').readFileSync(settingsPath, 'utf8'));
19
+ } catch (e) {
20
+ // Silently create default settings
21
+ }
22
+ }
23
+
24
+ // Apply startup optimizations - preserve bundled hooks!
25
+ const optimizedSettings = {
26
+ ...settings,
27
+ // Reduce plugin timeouts
28
+ pluginTimeout: settings.pluginTimeout || 5000,
29
+ // Disable unnecessary features for faster startup
30
+ alwaysThinkingEnabled: settings.alwaysThinkingEnabled || false,
31
+ // Optimize plugin loading - preserve existing plugins
32
+ enabledPlugins: {
33
+ ...settings.enabledPlugins,
34
+ // Only enable essential plugins for performance
35
+ 'glootie-cc@anentrypoint-plugins': true
36
+ }
37
+ // Note: DO NOT override hooks - preserve bundled settings hooks!
38
+ };
39
+
40
+ // Ensure directory exists
41
+ mkdirSync(dirname(settingsPath), { recursive: true });
42
+
43
+ // Write optimized settings
44
+ writeFileSync(settingsPath, JSON.stringify(optimizedSettings, null, 2));
45
+
46
+ return optimizedSettings;
47
+ }
48
+
49
+ // Pre-warm plugin connections
50
+ async prewarmPlugins() {
51
+
52
+ const prewarmScript = `
53
+ # Pre-warm script for Claude plugins
54
+ echo "Pre-warming plugin connections..."
55
+
56
+ # Set environment for faster plugin discovery
57
+ export NODE_OPTIONS="--max-old-space-size=2048"
58
+ export CLAUDE_PLUGIN_TIMEOUT=5000
59
+
60
+ # Pre-warm glootie plugin
61
+ if command -v npx >/dev/null 2>&1; then
62
+ timeout 3s npx -y glootie-cc@anentrypoint-plugins --version >/dev/null 2>&1 &
63
+ fi
64
+
65
+ echo "Plugin pre-warming complete"
66
+ `;
67
+
68
+ const scriptPath = join(this.sandboxDir, '.claude', 'prewarm.sh');
69
+ writeFileSync(scriptPath, prewarmScript);
70
+
71
+ return scriptPath;
72
+ }
73
+
74
+ // Create optimized environment for Claude
75
+ createOptimizedEnv(baseEnv = {}) {
76
+ return {
77
+ ...baseEnv,
78
+ // Performance optimizations
79
+ NODE_OPTIONS: "--max-old-space-size=2048",
80
+ CLAUDE_PLUGIN_TIMEOUT: "5000",
81
+ CLAUDE_CACHE_DIR: join(this.sandboxDir, '.cache', 'claude'),
82
+ // Network optimizations
83
+ NODE_TLS_REJECT_UNAUTHORIZED: "0",
84
+ // Plugin optimizations
85
+ MCP_TIMEOUT: "5000",
86
+ MCP_CONNECTION_TIMEOUT: "3000",
87
+ // Fast startup flags
88
+ CLAUDE_FAST_STARTUP: "1",
89
+ CLAUDE_MINIMAL_MODE: "1"
90
+ };
91
+ }
92
+
93
+ // Generate startup timing profile
94
+ async profileStartup(claudeCommand) {
95
+ console.log('📊 Profiling Claude startup...');
96
+
97
+ const profileScript = `
98
+ #!/bin/bash
99
+ echo "Starting Claude startup profile..."
100
+ start_time=$(date +%s%3N)
101
+
102
+ # Run Claude with timing
103
+ timeout 30s ${claudeCommand} --help >/dev/null 2>&1 &
104
+ claude_pid=$!
105
+
106
+ # Monitor startup progress
107
+ while kill -0 $claude_pid 2>/dev/null; do
108
+ current_time=$(date +%s%3N)
109
+ elapsed=$((current_time - start_time))
110
+
111
+ if [ $elapsed -gt 10000 ]; then
112
+ echo "⚠️ Startup taking longer than 10s..."
113
+ kill $claude_pid 2>/dev/null
114
+ break
115
+ fi
116
+
117
+ sleep 0.5
118
+ done
119
+
120
+ wait $claude_pid
121
+ end_time=$(date +%s%3N)
122
+ total_time=$((end_time - start_time))
123
+
124
+ echo "Claude startup completed in ${total_time}ms"
125
+ `;
126
+
127
+ return profileScript;
128
+ }
129
+ }
@@ -0,0 +1,15 @@
1
+ // Color utilities for CLI output
2
+ export const colors = {
3
+ red: '\x1b[31m',
4
+ green: '\x1b[32m',
5
+ yellow: '\x1b[33m',
6
+ blue: '\x1b[34m',
7
+ magenta: '\x1b[35m',
8
+ cyan: '\x1b[36m',
9
+ white: '\x1b[37m',
10
+ reset: '\x1b[0m'
11
+ };
12
+
13
+ export function color(colorName, text) {
14
+ return `${colors[colorName]}${text}${colors.reset}`;
15
+ }