sandboxbox 2.0.4 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -1,278 +1,342 @@
1
1
  #!/usr/bin/env node
2
-
3
- /**
4
- * SandboxBox CLI - Portable Container Runner with Podman
5
- *
6
- * Cross-platform container runner using Podman
7
- * Works on Windows, macOS, and Linux
8
- *
9
- * Simple usage:
10
- * npx sandboxbox build # Build container from Dockerfile
11
- * npx sandboxbox run <project> # Run project in container
12
- * npx sandboxbox shell <project> # Interactive shell
13
- */
14
-
15
- import { readFileSync, existsSync } from 'fs';
16
- import { execSync } from 'child_process';
17
- import { fileURLToPath } from 'url';
18
- import { dirname, resolve } from 'path';
19
-
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = dirname(__filename);
22
-
23
- // Colors for output
24
- const colors = {
25
- red: '\x1b[31m',
26
- green: '\x1b[32m',
27
- yellow: '\x1b[33m',
28
- blue: '\x1b[34m',
29
- magenta: '\x1b[35m',
30
- cyan: '\x1b[36m',
31
- white: '\x1b[37m',
32
- reset: '\x1b[0m'
33
- };
34
-
35
- function color(colorName, text) {
36
- return `${colors[colorName]}${text}${colors.reset}`;
37
- }
38
-
39
- function showBanner() {
40
- console.log(color('cyan', 'šŸ“¦ SandboxBox - Portable Container Runner'));
41
- console.log(color('cyan', '═════════════════════════════════════════════════'));
42
- console.log('');
43
- }
44
-
45
- function showHelp() {
46
- console.log(color('yellow', 'Usage:'));
47
- console.log(' npx sandboxbox <command> [options]');
48
- console.log('');
49
- console.log(color('yellow', 'Commands:'));
50
- console.log(' build [dockerfile] Build container from Dockerfile (default: ./Dockerfile)');
51
- console.log(' run <project-dir> [cmd] Run project in container');
52
- console.log(' shell <project-dir> Start interactive shell in container');
53
- console.log(' version Show version information');
54
- console.log('');
55
- console.log(color('yellow', 'Examples:'));
56
- console.log(' npx sandboxbox build');
57
- console.log(' npx sandboxbox build ./Dockerfile.custom');
58
- console.log(' npx sandboxbox run ./my-project');
59
- console.log(' npx sandboxbox run ./my-project "npm test"');
60
- console.log(' npx sandboxbox shell ./my-project');
61
- console.log('');
62
- console.log(color('yellow', 'Requirements:'));
63
- console.log(' - Podman (https://podman.io/getting-started/installation)');
64
- console.log(' - Works on Windows, macOS, and Linux!');
65
- console.log('');
66
- console.log(color('magenta', 'šŸš€ Fast startup • True isolation • Cross-platform'));
67
- }
68
-
69
- function getPodmanPath() {
70
- // Check for bundled podman first
71
- const platform = process.platform;
72
- const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
73
- let bundledPodman;
74
-
75
- if (platform === 'win32') {
76
- bundledPodman = resolve(__dirname, 'bin', 'podman.exe');
77
- } else if (platform === 'darwin') {
78
- bundledPodman = resolve(__dirname, 'bin', 'podman');
79
- } else {
80
- bundledPodman = resolve(__dirname, 'bin', `podman-remote-static-linux_${arch}`);
81
- }
82
-
83
- if (existsSync(bundledPodman)) {
84
- return bundledPodman;
85
- }
86
- // Fall back to system podman
87
- return 'podman';
88
- }
89
-
90
- function checkPodman() {
91
- const podmanPath = getPodmanPath();
92
- const isBundled = podmanPath.includes('bin');
93
-
94
- try {
95
- const version = execSync(`"${podmanPath}" --version`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
96
- console.log(color('green', `āœ… ${version}${isBundled ? ' (bundled)' : ''}`));
97
- return podmanPath;
98
- } catch (error) {
99
- // If no bundled Podman and system Podman not found, try to download
100
- if (!isBundled && !existsSync(podmanPath)) {
101
- console.log(color('red', 'āŒ Podman not found'));
102
- console.log(color('yellow', '\nšŸ“¦ Auto-downloading Podman...'));
103
-
104
- try {
105
- // Run the download script directly
106
- const scriptPath = resolve(__dirname, 'scripts', 'download-podman.js');
107
- execSync(`node "${scriptPath}"`, { stdio: 'inherit', cwd: __dirname });
108
-
109
- // Try again with downloaded Podman
110
- const newPodmanPath = getPodmanPath();
111
- const version = execSync(`"${newPodmanPath}" --version`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
112
- console.log(color('green', `\nāœ… ${version} (auto-downloaded)`));
113
- return newPodmanPath;
114
- } catch (downloadError) {
115
- console.log(color('red', `\nāŒ Auto-download failed: ${downloadError.message}`));
116
- console.log(color('yellow', '\nšŸ’” Please install Podman manually:'));
117
- }
118
- } else {
119
- console.log(color('red', 'āŒ Podman not found'));
120
- console.log(color('yellow', '\nšŸ’” Please install Podman manually:'));
121
- }
122
-
123
- console.log('');
124
- if (process.platform === 'win32') {
125
- console.log(color('cyan', ' Windows:'));
126
- console.log(' winget install RedHat.Podman');
127
- } else if (process.platform === 'darwin') {
128
- console.log(color('cyan', ' macOS:'));
129
- console.log(' brew install podman');
130
- console.log(' podman machine init && podman machine start');
131
- } else {
132
- console.log(color('cyan', ' Linux:'));
133
- console.log(' sudo apt-get install podman # Ubuntu/Debian');
134
- console.log(' sudo dnf install podman # Fedora');
135
- }
136
- console.log('');
137
- return null;
138
- }
139
- }
140
-
141
- async function main() {
142
- const args = process.argv.slice(2);
143
-
144
- showBanner();
145
-
146
- if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
147
- showHelp();
148
- process.exit(0);
149
- }
150
-
151
- const command = args[0].toLowerCase();
152
- const commandArgs = args.slice(1);
153
-
154
- switch (command) {
155
- case 'build':
156
- const dockerfilePath = commandArgs[0] || './Dockerfile';
157
-
158
- if (!existsSync(dockerfilePath)) {
159
- console.log(color('red', `āŒ Dockerfile not found: ${dockerfilePath}`));
160
- process.exit(1);
161
- }
162
-
163
- console.log(color('blue', 'šŸ—ļø Building container...'));
164
- console.log(color('yellow', `Dockerfile: ${dockerfilePath}\n`));
165
-
166
- const buildPodman = checkPodman();
167
- if (!buildPodman) process.exit(1);
168
-
169
- try {
170
- console.log('');
171
- execSync(`"${buildPodman}" build -f "${dockerfilePath}" -t sandboxbox:latest .`, {
172
- stdio: 'inherit',
173
- cwd: __dirname
174
- });
175
- console.log('');
176
- console.log(color('green', 'āœ… Container built successfully!'));
177
- console.log(color('cyan', '\nšŸ’” Next steps:'));
178
- console.log(' npx sandboxbox run ./my-project');
179
- } catch (error) {
180
- console.log(color('red', `\nāŒ Build failed: ${error.message}`));
181
- process.exit(1);
182
- }
183
- break;
184
-
185
- case 'run':
186
- if (commandArgs.length === 0) {
187
- console.log(color('red', 'āŒ Please specify a project directory'));
188
- console.log(color('yellow', 'Usage: npx sandboxbox run <project-dir> [command]'));
189
- process.exit(1);
190
- }
191
-
192
- const projectDir = resolve(commandArgs[0]);
193
- const cmd = commandArgs[1] || 'bash';
194
-
195
- if (!existsSync(projectDir)) {
196
- console.log(color('red', `āŒ Project directory not found: ${projectDir}`));
197
- process.exit(1);
198
- }
199
-
200
- console.log(color('blue', 'šŸš€ Running project in container...'));
201
- console.log(color('yellow', `Project: ${projectDir}`));
202
- console.log(color('yellow', `Command: ${cmd}\n`));
203
-
204
- const runPodman = checkPodman();
205
- if (!runPodman) process.exit(1);
206
-
207
- try {
208
- console.log('');
209
- execSync(`"${runPodman}" run --rm -it -v "${projectDir}:/workspace" -w /workspace sandboxbox:latest ${cmd}`, {
210
- stdio: 'inherit'
211
- });
212
- console.log('');
213
- console.log(color('green', 'āœ… Container execution completed!'));
214
- } catch (error) {
215
- console.log(color('red', `\nāŒ Run failed: ${error.message}`));
216
- process.exit(1);
217
- }
218
- break;
219
-
220
- case 'shell':
221
- if (commandArgs.length === 0) {
222
- console.log(color('red', 'āŒ Please specify a project directory'));
223
- console.log(color('yellow', 'Usage: npx sandboxbox shell <project-dir>'));
224
- process.exit(1);
225
- }
226
-
227
- const shellProjectDir = resolve(commandArgs[0]);
228
-
229
- if (!existsSync(shellProjectDir)) {
230
- console.log(color('red', `āŒ Project directory not found: ${shellProjectDir}`));
231
- process.exit(1);
232
- }
233
-
234
- console.log(color('blue', '🐚 Starting interactive shell...'));
235
- console.log(color('yellow', `Project: ${shellProjectDir}\n`));
236
-
237
- const shellPodman = checkPodman();
238
- if (!shellPodman) process.exit(1);
239
-
240
- try {
241
- console.log('');
242
- execSync(`"${shellPodman}" run --rm -it -v "${shellProjectDir}:/workspace" -w /workspace sandboxbox:latest /bin/bash`, {
243
- stdio: 'inherit'
244
- });
245
- } catch (error) {
246
- console.log(color('red', `\nāŒ Shell failed: ${error.message}`));
247
- process.exit(1);
248
- }
249
- break;
250
-
251
- case 'version':
252
- try {
253
- const packageJson = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf-8'));
254
- console.log(color('green', `SandboxBox v${packageJson.version}`));
255
- console.log(color('cyan', 'Portable containers with Claude Code & Playwright'));
256
- if (checkPodman()) {
257
- console.log('');
258
- }
259
- } catch (error) {
260
- console.log(color('red', 'āŒ Could not read version'));
261
- }
262
- break;
263
-
264
- default:
265
- console.log(color('red', `āŒ Unknown command: ${command}`));
266
- console.log(color('yellow', 'Use --help for usage information'));
267
- process.exit(1);
268
- }
269
- }
270
-
271
- // Run if called directly
272
- main().catch(error => {
273
- console.error(color('red', 'āŒ SandboxBox failed:'));
274
- console.error(color('red', error.message));
275
- console.error('');
276
- console.error(color('yellow', 'šŸ’” Try: npx sandboxbox --help'));
277
- process.exit(1);
278
- });
2
+
3
+ /**
4
+ * SandboxBox CLI - Portable Container Runner with Podman
5
+ *
6
+ * Cross-platform container runner using Podman
7
+ * Works on Windows, macOS, and Linux
8
+ *
9
+ * Simple usage:
10
+ * npx sandboxbox build # Build container from Dockerfile
11
+ * npx sandboxbox run <project> # Run project in container
12
+ * npx sandboxbox shell <project> # Interactive shell
13
+ */
14
+
15
+ import { readFileSync, existsSync } from 'fs';
16
+ import { execSync } from 'child_process';
17
+ import { fileURLToPath } from 'url';
18
+ import { dirname, resolve } from 'path';
19
+
20
+ const __filename = fileURLToPath(import.meta.url);
21
+ const __dirname = dirname(__filename);
22
+
23
+ // Colors for output
24
+ const colors = {
25
+ red: '\x1b[31m',
26
+ green: '\x1b[32m',
27
+ yellow: '\x1b[33m',
28
+ blue: '\x1b[34m',
29
+ magenta: '\x1b[35m',
30
+ cyan: '\x1b[36m',
31
+ white: '\x1b[37m',
32
+ reset: '\x1b[0m'
33
+ };
34
+
35
+ function color(colorName, text) {
36
+ return `${colors[colorName]}${text}${colors.reset}`;
37
+ }
38
+
39
+ function showBanner() {
40
+ console.log(color('cyan', 'šŸ“¦ SandboxBox - Portable Container Runner'));
41
+ console.log(color('cyan', '═════════════════════════════════════════════════'));
42
+ console.log('');
43
+ }
44
+
45
+ function showHelp() {
46
+ console.log(color('yellow', 'Usage:'));
47
+ console.log(' npx sandboxbox <command> [options]');
48
+ console.log('');
49
+ console.log(color('yellow', 'Commands:'));
50
+ console.log(' build [dockerfile] Build container from Dockerfile (default: ./Dockerfile)');
51
+ console.log(' run <project-dir> [cmd] Run project in container');
52
+ console.log(' shell <project-dir> Start interactive shell in container');
53
+ console.log(' version Show version information');
54
+ console.log('');
55
+ console.log(color('yellow', 'Examples:'));
56
+ console.log(' npx sandboxbox build');
57
+ console.log(' npx sandboxbox build ./Dockerfile.custom');
58
+ console.log(' npx sandboxbox run ./my-project');
59
+ console.log(' npx sandboxbox run ./my-project "npm test"');
60
+ console.log(' npx sandboxbox shell ./my-project');
61
+ console.log('');
62
+ console.log(color('yellow', 'Requirements:'));
63
+ console.log(' - Podman (https://podman.io/getting-started/installation)');
64
+ console.log(' - Works on Windows, macOS, and Linux!');
65
+ console.log('');
66
+ console.log(color('magenta', 'šŸš€ Fast startup • True isolation • Cross-platform'));
67
+ }
68
+
69
+ function getPodmanPath() {
70
+ // Check for bundled podman first
71
+ const platform = process.platform;
72
+ const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
73
+ let bundledPodman;
74
+
75
+ if (platform === 'win32') {
76
+ bundledPodman = resolve(__dirname, 'bin', 'podman.exe');
77
+ } else if (platform === 'darwin') {
78
+ bundledPodman = resolve(__dirname, 'bin', 'podman');
79
+ } else {
80
+ bundledPodman = resolve(__dirname, 'bin', `podman-remote-static-linux_${arch}`);
81
+ }
82
+
83
+ if (existsSync(bundledPodman)) {
84
+ return bundledPodman;
85
+ }
86
+ // Fall back to system podman
87
+ return 'podman';
88
+ }
89
+
90
+ function checkPodman() {
91
+ const podmanPath = getPodmanPath();
92
+ const isBundled = podmanPath.includes('bin');
93
+
94
+ try {
95
+ // For Windows bundled binary, ensure proper path handling
96
+ const execOptions = {
97
+ encoding: 'utf-8',
98
+ stdio: 'pipe',
99
+ shell: process.platform === 'win32' // Use shell on Windows for better compatibility
100
+ };
101
+
102
+ const version = execSync(`"${podmanPath}" --version`, execOptions).trim();
103
+ console.log(color('green', `āœ… ${version}${isBundled ? ' (bundled)' : ''}`));
104
+
105
+ // Check if Podman machine is running (Windows only)
106
+ if (process.platform === 'win32' && isBundled) {
107
+ try {
108
+ execSync(`"${podmanPath}" info`, { ...execOptions, stdio: 'pipe' });
109
+ } catch (infoError) {
110
+ if (infoError.message.includes('Cannot connect to Podman')) {
111
+ console.log(color('yellow', '\nšŸ”§ Podman machine not running, auto-initializing...'));
112
+
113
+ try {
114
+ // Try to start existing machine first
115
+ try {
116
+ execSync(`"${podmanPath}" machine start`, {
117
+ stdio: 'inherit',
118
+ cwd: __dirname,
119
+ shell: process.platform === 'win32'
120
+ });
121
+ console.log(color('green', '\nāœ… Podman machine started successfully in rootless mode!'));
122
+ } catch (startError) {
123
+ if (startError.message.includes('not found') || startError.message.includes('does not exist')) {
124
+ // Machine doesn't exist, initialize it
125
+ execSync(`"${podmanPath}" machine init`, {
126
+ stdio: 'inherit',
127
+ cwd: __dirname,
128
+ shell: process.platform === 'win32'
129
+ });
130
+
131
+ // Start the newly initialized machine
132
+ execSync(`"${podmanPath}" machine start`, {
133
+ stdio: 'inherit',
134
+ cwd: __dirname,
135
+ shell: process.platform === 'win32'
136
+ });
137
+
138
+ console.log(color('green', '\nāœ… Podman machine initialized and started successfully in rootless mode!'));
139
+ } else {
140
+ throw startError;
141
+ }
142
+ }
143
+ } catch (machineError) {
144
+ console.log(color('red', `\nāŒ Failed to initialize Podman machine: ${machineError.message}`));
145
+ console.log(color('yellow', '\nšŸ’” Please run manually:'));
146
+ console.log(' podman machine init && podman machine start');
147
+ return null;
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ return podmanPath;
154
+ } catch (error) {
155
+ // If no bundled Podman and system Podman not found, try to download
156
+ if (!isBundled) {
157
+ console.log(color('red', 'āŒ Podman not found'));
158
+ console.log(color('yellow', '\nšŸ“¦ Auto-downloading Podman...'));
159
+
160
+ try {
161
+ // Run the download script directly
162
+ const scriptPath = resolve(__dirname, 'scripts', 'download-podman.js');
163
+ execSync(`node "${scriptPath}"`, { stdio: 'inherit', cwd: __dirname, shell: process.platform === 'win32' });
164
+
165
+ // Try again with downloaded Podman
166
+ const newPodmanPath = getPodmanPath();
167
+ const execOptions = {
168
+ encoding: 'utf-8',
169
+ stdio: 'pipe',
170
+ shell: process.platform === 'win32'
171
+ };
172
+ const version = execSync(`"${newPodmanPath}" --version`, execOptions).trim();
173
+ console.log(color('green', `\nāœ… ${version} (auto-downloaded)`));
174
+ return newPodmanPath;
175
+ } catch (downloadError) {
176
+ console.log(color('red', `\nāŒ Auto-download failed: ${downloadError.message}`));
177
+ console.log(color('yellow', '\nšŸ’” Please install Podman manually:'));
178
+ }
179
+ } else {
180
+ console.log(color('red', 'āŒ Podman not found'));
181
+ console.log(color('yellow', '\nšŸ’” Please install Podman manually:'));
182
+ }
183
+
184
+ console.log('');
185
+ if (process.platform === 'win32') {
186
+ console.log(color('cyan', ' Windows:'));
187
+ console.log(' winget install RedHat.Podman');
188
+ } else if (process.platform === 'darwin') {
189
+ console.log(color('cyan', ' macOS:'));
190
+ console.log(' brew install podman');
191
+ console.log(' podman machine init && podman machine start');
192
+ } else {
193
+ console.log(color('cyan', ' Linux:'));
194
+ console.log(' sudo apt-get install podman # Ubuntu/Debian');
195
+ console.log(' sudo dnf install podman # Fedora');
196
+ }
197
+ console.log('');
198
+ return null;
199
+ }
200
+ }
201
+
202
+ async function main() {
203
+ const args = process.argv.slice(2);
204
+
205
+ showBanner();
206
+
207
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
208
+ showHelp();
209
+ process.exit(0);
210
+ }
211
+
212
+ const command = args[0].toLowerCase();
213
+ const commandArgs = args.slice(1);
214
+
215
+ switch (command) {
216
+ case 'build':
217
+ const dockerfilePath = commandArgs[0] || './Dockerfile';
218
+
219
+ if (!existsSync(dockerfilePath)) {
220
+ console.log(color('red', `āŒ Dockerfile not found: ${dockerfilePath}`));
221
+ process.exit(1);
222
+ }
223
+
224
+ console.log(color('blue', 'šŸ—ļø Building container...'));
225
+ console.log(color('yellow', `Dockerfile: ${dockerfilePath}\n`));
226
+
227
+ const buildPodman = checkPodman();
228
+ if (!buildPodman) process.exit(1);
229
+
230
+ try {
231
+ console.log('');
232
+ execSync(`"${buildPodman}" build -f "${dockerfilePath}" -t sandboxbox:latest .`, {
233
+ stdio: 'inherit',
234
+ cwd: __dirname,
235
+ shell: process.platform === 'win32'
236
+ });
237
+ console.log('');
238
+ console.log(color('green', 'āœ… Container built successfully!'));
239
+ console.log(color('cyan', '\nšŸ’” Next steps:'));
240
+ console.log(' npx sandboxbox run ./my-project');
241
+ } catch (error) {
242
+ console.log(color('red', `\nāŒ Build failed: ${error.message}`));
243
+ process.exit(1);
244
+ }
245
+ break;
246
+
247
+ case 'run':
248
+ if (commandArgs.length === 0) {
249
+ console.log(color('red', 'āŒ Please specify a project directory'));
250
+ console.log(color('yellow', 'Usage: npx sandboxbox run <project-dir> [command]'));
251
+ process.exit(1);
252
+ }
253
+
254
+ const projectDir = resolve(commandArgs[0]);
255
+ const cmd = commandArgs[1] || 'bash';
256
+
257
+ if (!existsSync(projectDir)) {
258
+ console.log(color('red', `āŒ Project directory not found: ${projectDir}`));
259
+ process.exit(1);
260
+ }
261
+
262
+ console.log(color('blue', 'šŸš€ Running project in container...'));
263
+ console.log(color('yellow', `Project: ${projectDir}`));
264
+ console.log(color('yellow', `Command: ${cmd}\n`));
265
+
266
+ const runPodman = checkPodman();
267
+ if (!runPodman) process.exit(1);
268
+
269
+ try {
270
+ console.log('');
271
+ execSync(`"${runPodman}" run --rm -it -v "${projectDir}:/workspace" -w /workspace sandboxbox:latest ${cmd}`, {
272
+ stdio: 'inherit',
273
+ shell: process.platform === 'win32'
274
+ });
275
+ console.log('');
276
+ console.log(color('green', 'āœ… Container execution completed!'));
277
+ } catch (error) {
278
+ console.log(color('red', `\nāŒ Run failed: ${error.message}`));
279
+ process.exit(1);
280
+ }
281
+ break;
282
+
283
+ case 'shell':
284
+ if (commandArgs.length === 0) {
285
+ console.log(color('red', 'āŒ Please specify a project directory'));
286
+ console.log(color('yellow', 'Usage: npx sandboxbox shell <project-dir>'));
287
+ process.exit(1);
288
+ }
289
+
290
+ const shellProjectDir = resolve(commandArgs[0]);
291
+
292
+ if (!existsSync(shellProjectDir)) {
293
+ console.log(color('red', `āŒ Project directory not found: ${shellProjectDir}`));
294
+ process.exit(1);
295
+ }
296
+
297
+ console.log(color('blue', '🐚 Starting interactive shell...'));
298
+ console.log(color('yellow', `Project: ${shellProjectDir}\n`));
299
+
300
+ const shellPodman = checkPodman();
301
+ if (!shellPodman) process.exit(1);
302
+
303
+ try {
304
+ console.log('');
305
+ execSync(`"${shellPodman}" run --rm -it -v "${shellProjectDir}:/workspace" -w /workspace sandboxbox:latest /bin/bash`, {
306
+ stdio: 'inherit',
307
+ shell: process.platform === 'win32'
308
+ });
309
+ } catch (error) {
310
+ console.log(color('red', `\nāŒ Shell failed: ${error.message}`));
311
+ process.exit(1);
312
+ }
313
+ break;
314
+
315
+ case 'version':
316
+ try {
317
+ const packageJson = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf-8'));
318
+ console.log(color('green', `SandboxBox v${packageJson.version}`));
319
+ console.log(color('cyan', 'Portable containers with Claude Code & Playwright'));
320
+ if (checkPodman()) {
321
+ console.log('');
322
+ }
323
+ } catch (error) {
324
+ console.log(color('red', 'āŒ Could not read version'));
325
+ }
326
+ break;
327
+
328
+ default:
329
+ console.log(color('red', `āŒ Unknown command: ${command}`));
330
+ console.log(color('yellow', 'Use --help for usage information'));
331
+ process.exit(1);
332
+ }
333
+ }
334
+
335
+ // Run if called directly
336
+ main().catch(error => {
337
+ console.error(color('red', 'āŒ SandboxBox failed:'));
338
+ console.error(color('red', error.message));
339
+ console.error('');
340
+ console.error(color('yellow', 'šŸ’” Try: npx sandboxbox --help'));
341
+ process.exit(1);
342
+ });
@@ -0,0 +1 @@
1
+ {"name": "test", "scripts": {"test": "echo Hello"}}