sandboxbox 2.5.4 ā 3.0.0
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 +49 -45
- package/package.json +10 -9
- package/testproject/Dockerfile +3 -0
- package/utils/commands/claude.js +27 -83
- package/utils/commands/container.js +31 -266
- package/utils/commands/index.js +2 -5
- package/utils/sandbox.js +104 -0
- package/scripts/download-podman.js +0 -103
- package/scripts/podman-config.js +0 -20
- package/scripts/podman-extract.js +0 -117
- package/utils/claude-workspace.js +0 -69
- package/utils/isolation.js +0 -222
- package/utils/podman.js +0 -228
package/utils/podman.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'fs';
|
|
2
|
-
import { execSync, spawn } from 'child_process';
|
|
3
|
-
import { resolve, dirname } from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
import { color } from './colors.js';
|
|
6
|
-
|
|
7
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
-
const __dirname = dirname(__filename);
|
|
9
|
-
|
|
10
|
-
export function getPodmanPath() {
|
|
11
|
-
const platform = process.platform;
|
|
12
|
-
const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
|
|
13
|
-
let bundledPodman;
|
|
14
|
-
|
|
15
|
-
if (platform === 'win32') {
|
|
16
|
-
bundledPodman = resolve(__dirname, '..', 'bin', 'podman.exe');
|
|
17
|
-
} else if (platform === 'darwin') {
|
|
18
|
-
bundledPodman = resolve(__dirname, '..', 'bin', 'podman');
|
|
19
|
-
} else {
|
|
20
|
-
bundledPodman = resolve(__dirname, '..', 'bin', `podman-remote-static-linux_${arch}`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (existsSync(bundledPodman)) {
|
|
24
|
-
return bundledPodman;
|
|
25
|
-
}
|
|
26
|
-
return 'podman';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function setupBackendNonBlocking(podmanPath) {
|
|
30
|
-
if (process.platform === 'linux') {
|
|
31
|
-
// Linux can run true rootless Podman
|
|
32
|
-
const execOptions = { encoding: 'utf-8', stdio: 'pipe', shell: true, windowsHide: process.platform === 'win32' };
|
|
33
|
-
try {
|
|
34
|
-
execSync(`"${podmanPath}" info`, execOptions);
|
|
35
|
-
return true;
|
|
36
|
-
} catch (infoError) {
|
|
37
|
-
console.log(color('yellow', '\nš§ Starting Podman rootless service...'));
|
|
38
|
-
// Try to start service automatically
|
|
39
|
-
try {
|
|
40
|
-
execSync('podman system service --time=0 &', { stdio: 'ignore', shell: true });
|
|
41
|
-
return true;
|
|
42
|
-
} catch (serviceError) {
|
|
43
|
-
console.log(color('cyan', ' Run: podman system service --time=0 &'));
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Windows: Implement completely silent automated setup
|
|
50
|
-
if (process.platform === 'win32') {
|
|
51
|
-
const execOptions = { encoding: 'utf-8', stdio: 'pipe', shell: true, windowsHide: process.platform === 'win32' };
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
execSync(`"${podmanPath}" info`, execOptions);
|
|
55
|
-
return true;
|
|
56
|
-
} catch (infoError) {
|
|
57
|
-
if (!infoError.message.includes('Cannot connect to Podman')) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
console.log(color('yellow', '\nš§ Setting up Podman automatically (silent mode)...'));
|
|
62
|
-
|
|
63
|
-
// Start machine setup in background without blocking
|
|
64
|
-
setupMachineBackground(podmanPath);
|
|
65
|
-
return true; // Continue even if setup is in progress
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// macOS: Similar automated approach
|
|
70
|
-
if (process.platform === 'darwin') {
|
|
71
|
-
const execOptions = { encoding: 'utf-8', stdio: 'pipe', shell: true, windowsHide: process.platform === 'win32' };
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
execSync(`"${podmanPath}" info`, execOptions);
|
|
75
|
-
return true;
|
|
76
|
-
} catch (infoError) {
|
|
77
|
-
if (!infoError.message.includes('Cannot connect to Podman')) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
console.log(color('yellow', '\nš§ Setting up Podman automatically...'));
|
|
82
|
-
setupMachineBackground(podmanPath);
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function setupMachineBackground(podmanPath) {
|
|
91
|
-
console.log(color('cyan', ' Starting machine setup in background...'));
|
|
92
|
-
|
|
93
|
-
const initCmd = process.platform === 'win32'
|
|
94
|
-
? `"${podmanPath}" machine init --rootful=false`
|
|
95
|
-
: `"${podmanPath}" machine init`;
|
|
96
|
-
|
|
97
|
-
// Windows-specific: Use completely hidden process execution
|
|
98
|
-
const spawnOptions = process.platform === 'win32' ? {
|
|
99
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
100
|
-
shell: true,
|
|
101
|
-
detached: true,
|
|
102
|
-
windowsHide: true, // Hide the console window on Windows
|
|
103
|
-
cwd: process.cwd() // Ensure working directory is set
|
|
104
|
-
} : {
|
|
105
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
106
|
-
shell: true,
|
|
107
|
-
detached: true
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const initProcess = spawn(initCmd, spawnOptions);
|
|
111
|
-
|
|
112
|
-
// Handle init process completion/errors
|
|
113
|
-
initProcess.on('error', (error) => {
|
|
114
|
-
console.log(color('red', ` Init process error: ${error.message}`));
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
initProcess.on('exit', (code) => {
|
|
118
|
-
if (code === 0) {
|
|
119
|
-
console.log(color('green', ' Machine initialization completed, starting in 10 seconds...'));
|
|
120
|
-
|
|
121
|
-
// Start machine after init completes
|
|
122
|
-
setTimeout(() => {
|
|
123
|
-
const startCmd = `"${podmanPath}" machine start`;
|
|
124
|
-
const startProcess = spawn(startCmd, spawnOptions);
|
|
125
|
-
|
|
126
|
-
startProcess.on('error', (error) => {
|
|
127
|
-
console.log(color('red', ` Start process error: ${error.message}`));
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
startProcess.on('exit', (startCode) => {
|
|
131
|
-
if (startCode === 0) {
|
|
132
|
-
console.log(color('green', ' Podman machine started successfully!'));
|
|
133
|
-
} else {
|
|
134
|
-
console.log(color('red', ` Machine start failed with code: ${startCode}`));
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
startProcess.unref();
|
|
139
|
-
}, 10000); // Wait 10 seconds before starting
|
|
140
|
-
} else {
|
|
141
|
-
console.log(color('red', ` Machine initialization failed with code: ${code}`));
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
initProcess.unref();
|
|
146
|
-
|
|
147
|
-
console.log(color('yellow', ' Setup initiated in background (may take 2-3 minutes)'));
|
|
148
|
-
console.log(color('cyan', ' Container operations will work when setup completes\n'));
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export function checkBackend(podmanPath) {
|
|
152
|
-
if (process.platform === 'linux') return true;
|
|
153
|
-
|
|
154
|
-
const execOptions = { encoding: 'utf-8', stdio: 'pipe', shell: true, windowsHide: process.platform === 'win32' };
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
execSync(`"${podmanPath}" info`, execOptions);
|
|
158
|
-
return true;
|
|
159
|
-
} catch (infoError) {
|
|
160
|
-
if (infoError.message.includes('Cannot connect to Podman')) {
|
|
161
|
-
console.log(color('red', '\nā Podman backend not running'));
|
|
162
|
-
console.log(color('yellow', '\nš One-time setup required:'));
|
|
163
|
-
console.log(color('cyan', process.platform === 'win32'
|
|
164
|
-
? ' Run: podman machine init --rootful=false && podman machine start'
|
|
165
|
-
: ' Run: podman machine init && podman machine start'));
|
|
166
|
-
console.log(color('yellow', '\nā±ļø This takes 2-3 minutes, then works instantly forever.\n'));
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
throw infoError;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export function checkPodman() {
|
|
174
|
-
const podmanPath = getPodmanPath();
|
|
175
|
-
const isBundled = podmanPath.includes('bin');
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
const execOptions = {
|
|
179
|
-
encoding: 'utf-8',
|
|
180
|
-
stdio: 'pipe',
|
|
181
|
-
shell: process.platform === 'win32'
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const version = execSync(`"${podmanPath}" --version`, { encoding: 'utf-8', stdio: 'pipe', shell: process.platform === 'win32', windowsHide: process.platform === 'win32' }).trim();
|
|
185
|
-
console.log(color('green', `ā
${version}${isBundled ? ' (bundled)' : ''}`));
|
|
186
|
-
return podmanPath;
|
|
187
|
-
} catch (error) {
|
|
188
|
-
console.log('ā Podman not found');
|
|
189
|
-
console.log('\nš¦ Auto-downloading Podman...');
|
|
190
|
-
|
|
191
|
-
try {
|
|
192
|
-
const scriptPath = resolve(__dirname, '..', 'scripts', 'download-podman.js');
|
|
193
|
-
execSync(`node "${scriptPath}"`, { stdio: 'inherit', cwd: __dirname, shell: process.platform === 'win32', windowsHide: process.platform === 'win32' });
|
|
194
|
-
|
|
195
|
-
const newPodmanPath = getPodmanPath();
|
|
196
|
-
if (!existsSync(newPodmanPath) && newPodmanPath !== 'podman') {
|
|
197
|
-
throw new Error('Download completed but binary not found');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const execOptions = {
|
|
201
|
-
encoding: 'utf-8',
|
|
202
|
-
stdio: 'pipe',
|
|
203
|
-
shell: process.platform === 'win32'
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const newVersion = execSync(`"${newPodmanPath}" --version`, { encoding: 'utf-8', stdio: 'pipe', shell: process.platform === 'win32', windowsHide: process.platform === 'win32' }).trim();
|
|
207
|
-
console.log(`\nā
${newVersion} (auto-downloaded)`);
|
|
208
|
-
console.log('ā
Portable Podman ready');
|
|
209
|
-
|
|
210
|
-
return newPodmanPath;
|
|
211
|
-
} catch (downloadError) {
|
|
212
|
-
console.log(`\nā Auto-download failed: ${downloadError.message}`);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
console.log('\nš” Please install Podman manually:');
|
|
216
|
-
if (process.platform === 'win32') {
|
|
217
|
-
console.log(' winget install RedHat.Podman');
|
|
218
|
-
} else if (process.platform === 'darwin') {
|
|
219
|
-
console.log(' brew install podman');
|
|
220
|
-
console.log(' podman machine init && podman machine start');
|
|
221
|
-
} else {
|
|
222
|
-
console.log(' sudo apt-get install podman # Ubuntu/Debian');
|
|
223
|
-
console.log(' sudo dnf install podman # Fedora');
|
|
224
|
-
}
|
|
225
|
-
console.log('');
|
|
226
|
-
return null;
|
|
227
|
-
}
|
|
228
|
-
}
|