sandboxbox 2.3.4 → 2.3.5

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 (2) hide show
  1. package/package.json +1 -1
  2. package/utils/podman.js +25 -133
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sandboxbox",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "description": "Portable container runner with Podman - Claude Code & Playwright support. Works on Windows, macOS, and Linux.",
5
5
  "type": "module",
6
6
  "main": "cli.js",
package/utils/podman.js CHANGED
@@ -27,8 +27,21 @@ export function getPodmanPath() {
27
27
  }
28
28
 
29
29
  export function setupBackendNonBlocking(podmanPath) {
30
- if (process.platform === 'linux') return true;
30
+ if (process.platform === 'linux') {
31
+ // Linux can run true rootless Podman
32
+ const execOptions = { encoding: 'utf-8', stdio: 'pipe', shell: true };
33
+ try {
34
+ execSync(`"${podmanPath}" info`, execOptions);
35
+ return true;
36
+ } catch (infoError) {
37
+ console.log(color('yellow', '\nšŸ”§ Starting Podman rootless service...'));
38
+ console.log(color('cyan', ' Run: podman system service --time=0 &'));
39
+ console.log(color('yellow', ' Or use systemd: sudo systemctl enable --now podman'));
40
+ return false;
41
+ }
42
+ }
31
43
 
44
+ // Windows/macOS: Show setup instructions (VM required, no way around it)
32
45
  const execOptions = { encoding: 'utf-8', stdio: 'pipe', shell: true };
33
46
 
34
47
  try {
@@ -39,140 +52,19 @@ export function setupBackendNonBlocking(podmanPath) {
39
52
  return false;
40
53
  }
41
54
 
42
- console.log(color('yellow', '\nšŸ”§ Initializing Podman backend (one-time setup, takes 2-3 minutes)...'));
43
-
44
- try {
45
- // Check existing machines with shorter timeout
46
- let machines = [];
47
- try {
48
- const machineListOutput = execSync(`"${podmanPath}" machine list --format json`, {
49
- ...execOptions,
50
- timeout: 3000 // 3 seconds timeout
51
- });
52
- machines = JSON.parse(machineListOutput || '[]');
53
- console.log(color('cyan', ` Found ${machines.length} existing machine(s)`));
54
- } catch (machineListError) {
55
- console.log(color('yellow', ' Could not list machines quickly, checking via info command...'));
56
- // Try to detect if machine exists by checking for specific error messages
57
- try {
58
- execSync(`"${podmanPath}" info`, {
59
- ...execOptions,
60
- timeout: 3000
61
- });
62
- console.log(color('green', ' Backend is already working!'));
63
- return true;
64
- } catch (infoError) {
65
- if (infoError.message.includes('127.0.0.1')) {
66
- console.log(color('cyan', ' Machine exists but not running, proceeding...'));
67
- } else {
68
- console.log(color('yellow', ' Assuming no machines exist'));
69
- }
70
- }
71
- }
55
+ console.log(color('yellow', '\nšŸ”§ Podman machine setup required (Windows/macOS limitation)'));
56
+ console.log(color('cyan', process.platform === 'win32'
57
+ ? ' Windows requires a VM backend for Podman containers'
58
+ : ' macOS requires a VM backend for Podman containers'));
72
59
 
73
- if (machines.length === 0) {
74
- console.log(color('cyan', ' Creating Podman machine...'));
75
- const initCmd = process.platform === 'win32'
76
- ? `"${podmanPath}" machine init --rootful=false`
77
- : `"${podmanPath}" machine init`;
78
-
79
- try {
80
- execSync(initCmd, {
81
- stdio: ['pipe', 'pipe', 'pipe'],
82
- shell: true,
83
- timeout: 120000 // 2 minutes
84
- });
85
- } catch (initError) {
86
- const errorOutput = initError.stdout?.toString() + initError.stderr?.toString();
87
- if (errorOutput?.includes('already exists') ||
88
- errorOutput?.includes('VM already exists') ||
89
- initError.message.includes('already exists')) {
90
- console.log(color('cyan', ' Machine already exists, proceeding...'));
91
- } else {
92
- console.log(color('red', ` Error output: ${errorOutput}`));
93
- throw initError;
94
- }
95
- }
96
- } else {
97
- console.log(color('cyan', ' Using existing machine'));
98
- }
99
-
100
- console.log(color('cyan', ' Checking machine status...'));
101
- try {
102
- const statusOutput = execSync(`"${podmanPath}" machine list`, {
103
- encoding: 'utf-8',
104
- stdio: 'pipe',
105
- shell: true,
106
- timeout: 3000 // 3 seconds timeout
107
- });
108
-
109
- if (statusOutput.includes('Running')) {
110
- console.log(color('green', ' Machine is already running'));
111
- } else {
112
- console.log(color('cyan', ' Starting Podman machine...'));
113
- startMachineWithRetry();
114
- }
115
- } catch (statusError) {
116
- console.log(color('cyan', ' Could not check status, attempting to start machine...'));
117
- startMachineWithRetry();
118
- }
60
+ console.log(color('yellow', '\nšŸ“‹ One-time setup (takes 2-3 minutes):'));
61
+ const setupCmd = process.platform === 'win32'
62
+ ? `podman machine init --rootful=false && podman machine start`
63
+ : `podman machine init && podman machine start`;
119
64
 
120
- // Give background process time to start, then verify once
121
- console.log(color('cyan', ' Giving background process time to start...'));
122
- const start = Date.now();
123
- while (Date.now() - start < 15000) {
124
- // Wait 15 seconds for background start
125
- }
126
-
127
- // Quick verification attempt
128
- console.log(color('cyan', ' Verifying backend connection...'));
129
- try {
130
- execSync(`"${podmanPath}" info`, {
131
- ...execOptions,
132
- timeout: 5000 // 5 second timeout
133
- });
134
- console.log(color('green', ' Backend is ready!'));
135
- } catch (verifyError) {
136
- console.log(color('yellow', ' Backend still starting. This is normal for first-time setup.'));
137
- console.log(color('cyan', ' If this persists, run manually:'));
138
- const manualCmd = process.platform === 'win32'
139
- ? `"${podmanPath}" machine init --rootful=false && "${podmanPath}" machine start`
140
- : `"${podmanPath}" machine init && "${podmanPath}" machine start`;
141
- console.log(color('cyan', ` ${manualCmd}`));
142
- console.log(color('yellow', ' Then try sandboxbox again.'));
143
- return false;
144
- }
145
-
146
- console.log(color('green', '\nāœ… Podman backend setup completed!\n'));
147
- return true;
148
-
149
- function startMachineWithRetry() {
150
- // Use completely silent background start
151
- console.log(color('cyan', ' Starting Podman machine silently in background...'));
152
-
153
- const startProcess = spawn(`"${podmanPath}" machine start`, {
154
- stdio: ['pipe', 'pipe', 'pipe'],
155
- shell: true,
156
- detached: true
157
- });
158
-
159
- startProcess.unref(); // Completely detach from parent
160
- console.log(color('yellow', ' Machine start initiated in background (may take 1-2 minutes)'));
161
- }
162
- } catch (setupError) {
163
- if (setupError.signal === 'SIGTERM') {
164
- console.log(color('red', '\nāŒ Setup timed out. Please run manually:'));
165
- } else {
166
- console.log(color('red', `\nāŒ Setup failed: ${setupError.message}`));
167
- console.log(color('red', ` Error details: ${setupError.stack}`));
168
- }
169
-
170
- const manualCmd = process.platform === 'win32'
171
- ? `"${podmanPath}" machine init --rootful=false && "${podmanPath}" machine start`
172
- : `"${podmanPath}" machine init && "${podmanPath}" machine start`;
173
- console.log(color('cyan', ` Manual setup: ${manualCmd}`));
174
- return false;
175
- }
65
+ console.log(color('cyan', ` ${setupCmd}`));
66
+ console.log(color('yellow', '\nšŸ’” After setup, sandboxbox will work instantly forever\n'));
67
+ return false;
176
68
  }
177
69
  }
178
70