sandboxbox 2.2.6 → 2.2.7

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/CLAUDE.md CHANGED
@@ -12,6 +12,8 @@ Portable containerized environments using Podman with automatic WSL management a
12
12
 
13
13
  ### Podman Downloader (scripts/download-podman.js)
14
14
  - Cross-platform binary downloads from GitHub releases
15
+ - Architecture auto-detection: `process.arch === 'arm64' ? 'arm64' : 'amd64'`
16
+ - Platform support: Windows (amd64/arm64), macOS (amd64/arm64), Linux (amd64/arm64)
15
17
  - PowerShell ZIP extraction on Windows
16
18
  - Auto-detects existing installations
17
19
  - Auto-triggers on first use if Podman not found
@@ -81,7 +83,8 @@ if (process.platform === 'win32' && isBundled) {
81
83
  - **Simple Configuration**: Minimal backend setup only when needed
82
84
  - **Auto-Download**: Downloads platform-specific binaries automatically
83
85
  - **NPX Compatible**: Works via npx without global installation
84
- - **Windows Portable Binary**: Uses podman-remote-release-windows_amd64.zip with lightweight backend
86
+ - **Architecture Support**: Auto-detects and downloads correct binary (amd64 or arm64)
87
+ - **Cross-Platform**: Windows, macOS, Linux - all with amd64/arm64 support
85
88
 
86
89
  ## Isolation Architecture
87
90
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sandboxbox",
3
- "version": "2.2.6",
3
+ "version": "2.2.7",
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/commands.js CHANGED
@@ -3,7 +3,7 @@ import { execSync } from 'child_process';
3
3
  import { resolve, dirname } from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { color } from './colors.js';
6
- import { checkPodman, getPodmanPath } from './podman.js';
6
+ import { checkPodman, getPodmanPath, ensureBackend } from './podman.js';
7
7
  import { buildClaudeContainerCommand, createClaudeDockerfile } from './claude-workspace.js';
8
8
  import { createIsolatedEnvironment, setupCleanupHandlers, buildContainerMounts } from './isolation.js';
9
9
 
@@ -22,6 +22,8 @@ export function buildCommand(dockerfilePath) {
22
22
  const podmanPath = checkPodman();
23
23
  if (!podmanPath) return false;
24
24
 
25
+ ensureBackend(podmanPath);
26
+
25
27
  try {
26
28
  execSync(`"${podmanPath}" build -f "${dockerfilePath}" -t sandboxbox:latest .`, {
27
29
  stdio: 'inherit',
@@ -50,6 +52,8 @@ export function runCommand(projectDir, cmd = 'bash') {
50
52
  const podmanPath = checkPodman();
51
53
  if (!podmanPath) return false;
52
54
 
55
+ ensureBackend(podmanPath);
56
+
53
57
  try {
54
58
  const { tempProjectDir, cleanup } = createIsolatedEnvironment(projectDir);
55
59
  setupCleanupHandlers(cleanup);
@@ -82,6 +86,8 @@ export function shellCommand(projectDir) {
82
86
  const podmanPath = checkPodman();
83
87
  if (!podmanPath) return false;
84
88
 
89
+ ensureBackend(podmanPath);
90
+
85
91
  try {
86
92
  const { tempProjectDir, cleanup } = createIsolatedEnvironment(projectDir);
87
93
  setupCleanupHandlers(cleanup);
@@ -133,6 +139,8 @@ export function claudeCommand(projectDir, command = 'claude') {
133
139
  const buildPodman = checkPodman();
134
140
  if (!buildPodman) return false;
135
141
 
142
+ ensureBackend(buildPodman);
143
+
136
144
  try {
137
145
  const { tempProjectDir, cleanup } = createIsolatedEnvironment(projectDir);
138
146
  setupCleanupHandlers(cleanup);
@@ -178,6 +186,8 @@ function buildClaudeContainer() {
178
186
  const podmanPath = checkPodman();
179
187
  if (!podmanPath) return false;
180
188
 
189
+ ensureBackend(podmanPath);
190
+
181
191
  try {
182
192
  execSync(`"${podmanPath}" build -f "${dockerfilePath}" -t sandboxbox-local:latest .`, {
183
193
  stdio: 'inherit',
package/utils/podman.js CHANGED
@@ -2,6 +2,7 @@ import { existsSync } from 'fs';
2
2
  import { execSync } from 'child_process';
3
3
  import { resolve, dirname } from 'path';
4
4
  import { fileURLToPath } from 'url';
5
+ import { color } from './colors.js';
5
6
 
6
7
  const __filename = fileURLToPath(import.meta.url);
7
8
  const __dirname = dirname(__filename);
@@ -25,6 +26,42 @@ export function getPodmanPath() {
25
26
  return 'podman';
26
27
  }
27
28
 
29
+ export function ensureBackend(podmanPath) {
30
+ if (process.platform !== 'win32') return;
31
+
32
+ const execOptions = {
33
+ encoding: 'utf-8',
34
+ stdio: 'pipe',
35
+ shell: true
36
+ };
37
+
38
+ try {
39
+ execSync(`"${podmanPath}" info`, execOptions);
40
+ } catch (infoError) {
41
+ if (infoError.message.includes('Cannot connect to Podman')) {
42
+ console.log('\n🔧 Starting Podman backend (first run may take a few minutes)...');
43
+ try {
44
+ execSync(`"${podmanPath}" machine start`, {
45
+ stdio: 'inherit',
46
+ shell: true
47
+ });
48
+ } catch (startError) {
49
+ if (startError.message.includes('does not exist') || startError.message.includes('not found')) {
50
+ console.log('🔧 Creating Podman machine (rootless mode)...');
51
+ execSync(`"${podmanPath}" machine init --rootful=false`, {
52
+ stdio: 'inherit',
53
+ shell: true
54
+ });
55
+ execSync(`"${podmanPath}" machine start`, {
56
+ stdio: 'inherit',
57
+ shell: true
58
+ });
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+
28
65
  export function checkPodman() {
29
66
  const podmanPath = getPodmanPath();
30
67
  const isBundled = podmanPath.includes('bin');
@@ -60,49 +97,7 @@ export function checkPodman() {
60
97
 
61
98
  const newVersion = execSync(`"${newPodmanPath}" --version`, execOptions).trim();
62
99
  console.log(`\n✅ ${newVersion} (auto-downloaded)`);
63
-
64
- // Auto-setup minimal backend for Windows portable operation
65
- if (process.platform === 'win32' && isBundled) {
66
- try {
67
- execSync(`"${newPodmanPath}" info`, { ...execOptions, stdio: 'pipe' });
68
- } catch (infoError) {
69
- if (infoError.message.includes('Cannot connect to Podman')) {
70
- console.log('\n🔧 Setting up portable Podman backend...');
71
- try {
72
- // Try to start existing machine first
73
- execSync(`"${newPodmanPath}" machine start`, {
74
- stdio: 'inherit',
75
- shell: true,
76
- cwd: __dirname
77
- });
78
- console.log('\n✅ Portable Podman backend started!');
79
- } catch (startError) {
80
- if (startError.message.includes('does not exist') || startError.message.includes('not found')) {
81
- try {
82
- // Create new machine if none exists
83
- execSync(`"${newPodmanPath}" machine init --rootful=false`, {
84
- stdio: 'inherit',
85
- shell: true,
86
- cwd: __dirname
87
- });
88
- execSync(`"${newPodmanPath}" machine start`, {
89
- stdio: 'inherit',
90
- shell: true,
91
- cwd: __dirname
92
- });
93
- console.log('\n✅ Portable Podman backend created and started!');
94
- } catch (initError) {
95
- console.log('\n⚠️ Podman backend setup needed on first container run');
96
- }
97
- } else {
98
- console.log('\n⚠️ Podman backend setup needed on first container run');
99
- }
100
- }
101
- }
102
- }
103
- }
104
-
105
- console.log('\n✅ Portable Podman ready');
100
+ console.log('✅ Portable Podman ready');
106
101
 
107
102
  return newPodmanPath;
108
103
  } catch (downloadError) {