sandboxbox 2.3.2 → 2.3.4

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 +104 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sandboxbox",
3
- "version": "2.3.2",
3
+ "version": "2.3.4",
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
@@ -42,8 +42,33 @@ export function setupBackendNonBlocking(podmanPath) {
42
42
  console.log(color('yellow', '\nšŸ”§ Initializing Podman backend (one-time setup, takes 2-3 minutes)...'));
43
43
 
44
44
  try {
45
- const machineListOutput = execSync(`"${podmanPath}" machine list --format json`, execOptions);
46
- const machines = JSON.parse(machineListOutput || '[]');
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
+ }
47
72
 
48
73
  if (machines.length === 0) {
49
74
  console.log(color('cyan', ' Creating Podman machine...'));
@@ -51,27 +76,95 @@ export function setupBackendNonBlocking(podmanPath) {
51
76
  ? `"${podmanPath}" machine init --rootful=false`
52
77
  : `"${podmanPath}" machine init`;
53
78
 
54
- execSync(initCmd, {
55
- stdio: 'inherit',
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',
56
105
  shell: true,
57
- timeout: 120000 // 2 minutes
106
+ timeout: 3000 // 3 seconds timeout
58
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
+ }
119
+
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
59
125
  }
60
126
 
61
- console.log(color('cyan', ' Starting Podman machine...'));
62
- execSync(`"${podmanPath}" machine start`, {
63
- stdio: 'inherit',
64
- shell: true,
65
- timeout: 60000 // 1 minute
66
- });
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
+ }
67
145
 
68
146
  console.log(color('green', '\nāœ… Podman backend setup completed!\n'));
69
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
+ }
70
162
  } catch (setupError) {
71
163
  if (setupError.signal === 'SIGTERM') {
72
164
  console.log(color('red', '\nāŒ Setup timed out. Please run manually:'));
73
165
  } else {
74
166
  console.log(color('red', `\nāŒ Setup failed: ${setupError.message}`));
167
+ console.log(color('red', ` Error details: ${setupError.stack}`));
75
168
  }
76
169
 
77
170
  const manualCmd = process.platform === 'win32'