sandboxbox 2.0.4 → 2.0.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/0.60 ADDED
File without changes
package/CLAUDE.md ADDED
@@ -0,0 +1,138 @@
1
+ # SandboxBox Technical Documentation
2
+
3
+ ## Architecture Overview
4
+ SandboxBox provides portable containerized development environments using Podman with automatic WSL machine management and Claude Code integration.
5
+
6
+ ## Core Components
7
+
8
+ ### CLI (cli.js)
9
+ - Main entry point with automatic Podman machine management
10
+ - Commands: build, run, shell, version, help
11
+ - Auto-detects and starts Podman machine when needed
12
+ - Shell execution with Windows compatibility (`shell: process.platform === 'win32'`)
13
+
14
+ ### Podman Downloader (scripts/download-podman.js)
15
+ - Cross-platform binary downloads from GitHub releases
16
+ - PowerShell ZIP extraction on Windows (no external dependencies)
17
+ - Automatic version detection and binary path resolution
18
+
19
+ ### Container Images
20
+ - **sandboxbox-auth**: Full development environment with Claude Code
21
+ - **sandboxbox-local**: Local repository workspace (symlink approach)
22
+
23
+ ## Windows Compatibility Fixes
24
+
25
+ ### Critical PowerShell ZIP Extraction
26
+ ```javascript
27
+ // scripts/download-podman.js:81
28
+ execSync(`powershell -Command "${psCommand}"`, {
29
+ stdio: 'pipe',
30
+ cwd: __dirname,
31
+ shell: true // REQUIRED for PowerShell commands
32
+ });
33
+ ```
34
+
35
+ ### Shell Execution Pattern
36
+ All `execSync()` calls must include:
37
+ ```javascript
38
+ {
39
+ stdio: 'pipe',
40
+ shell: process.platform === 'win32' // Windows compatibility
41
+ }
42
+ ```
43
+
44
+ ### Auto Podman Machine Management
45
+ ```javascript
46
+ // cli.js checkPodman() function
47
+ if (process.platform === 'win32' && isBundled) {
48
+ try {
49
+ execSync(`"${podmanPath}" info`, { ...execOptions, stdio: 'pipe' });
50
+ } catch (infoError) {
51
+ if (infoError.message.includes('Cannot connect to Podman')) {
52
+ // Auto-start existing machine
53
+ execSync(`"${podmanPath}" machine start`, { stdio: 'inherit' });
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## Claude Code Integration
60
+
61
+ ### Authentication Transfer
62
+ Mount complete Claude session data:
63
+ ```bash
64
+ -v "$HOME/.claude:/root/.claude"
65
+ ```
66
+
67
+ ### Environment Variables
68
+ Key variables to transfer:
69
+ ```bash
70
+ ANTHROPIC_AUTH_TOKEN
71
+ CLAUDECODE=1
72
+ ANTHROPIC_BASE_URL
73
+ ```
74
+
75
+ ### Git Identity Transfer
76
+ ```bash
77
+ -v "$HOME/.gitconfig:/root/.gitconfig:ro"
78
+ -v "$HOME/.ssh:/root/.ssh:ro"
79
+ ```
80
+
81
+ ## Local Repository Workflow
82
+
83
+ ### Architecture
84
+ - Container mounts local repo as `/project:rw`
85
+ - Creates symlink `/workspace/project` → `/project`
86
+ - Works directly with local repository (no cloning needed)
87
+ - Changes persist to host folder automatically
88
+
89
+ ### Container Command
90
+ ```bash
91
+ podman run --rm \
92
+ -v "/path/to/repo:/project:rw" \
93
+ -v "$HOME/.claude:/root/.claude" \
94
+ -v "$HOME/.gitconfig:/root/.gitconfig:ro" \
95
+ -v "$HOME/.ssh:/root/.ssh" \
96
+ -e "ANTHROPIC_AUTH_TOKEN=..." \
97
+ -e "CLAUDECODE=1" \
98
+ sandboxbox-local:latest
99
+ ```
100
+
101
+ ### Dockerfile.local-workspace
102
+ ```dockerfile
103
+ # Creates symlink to mounted repository
104
+ ln -sf "$REPO_PATH" "$WORKSPACE_DIR"
105
+ cd "$WORKSPACE_DIR"
106
+ exec claude # Changes save directly to local repo
107
+ ```
108
+
109
+ ## Complete Workflow Example
110
+
111
+ 1. **Setup**: Build sandboxbox-local image
112
+ 2. **Mount**: Local repository as `/project:rw`
113
+ 3. **Auth Transfer**: Mount `.claude`, `.gitconfig`, `.ssh`
114
+ 4. **Edit**: Claude Code modifies files in `/workspace/project` (symlink to `/project`)
115
+ 5. **Commit**: Changes made directly to local repository
116
+ 6. **Persist**: No additional push/pull needed - changes already in host folder
117
+
118
+ ## Troubleshooting
119
+
120
+ ### "unzip command not found"
121
+ **Solution**: Use PowerShell ZIP extraction with `shell: true`
122
+
123
+ ### "Cannot connect to Podman"
124
+ **Solution**: Automatic machine start in checkPodman() function
125
+
126
+ ### Build context issues
127
+ **Solution**: Use direct Podman build, then tag for SandboxBox
128
+
129
+ ### Git identity errors
130
+ **Solution**: Mount `.gitconfig:ro` for user identity transfer
131
+
132
+ ### Path resolution issues
133
+ **Solution**: Use explicit REPO_PATH environment variable
134
+
135
+ ## Version Management
136
+ - Publish new version when fixing critical Windows issues
137
+ - Clear npm cache: `npm cache clean --force`
138
+ - Use specific version: `npx sandboxbox@latest`
package/Dockerfile CHANGED
@@ -1,95 +1,95 @@
1
- FROM node:20
2
-
3
- ARG TZ
4
- ENV TZ="$TZ"
5
-
6
- ARG CLAUDE_CODE_VERSION=latest
7
-
8
- # Install basic development tools and iptables/ipset
9
- RUN apt-get update && apt-get install -y --no-install-recommends \
10
- less \
11
- git \
12
- procps \
13
- sudo \
14
- fzf \
15
- zsh \
16
- man-db \
17
- unzip \
18
- gnupg2 \
19
- gh \
20
- iptables \
21
- ipset \
22
- iproute2 \
23
- dnsutils \
24
- aggregate \
25
- jq \
26
- nano \
27
- vim \
28
- && apt-get clean && rm -rf /var/lib/apt/lists/*
29
-
30
- # Ensure default node user has access to /usr/local/share
31
- RUN mkdir -p /usr/local/share/npm-global && \
32
- chown -R node:node /usr/local/share
33
-
34
- ARG USERNAME=node
35
-
36
- # Persist bash history.
37
- RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
38
- && mkdir -p /commandhistory \
39
- && touch /commandhistory/.bash_history \
40
- && chown -R $USERNAME /commandhistory
41
-
42
- # Set `DEVCONTAINER` environment variable to help with orientation
43
- ENV DEVCONTAINER=true
44
-
45
- # Create workspace and config directories and set permissions
46
- RUN mkdir -p /workspace /home/node/.claude && \
47
- chown -R node:node /workspace /home/node/.claude
48
-
49
- WORKDIR /workspace
50
-
51
- ARG GIT_DELTA_VERSION=0.18.2
52
- RUN ARCH=$(dpkg --print-architecture) && \
53
- wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
54
- sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
55
- rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
56
-
57
- # Set up non-root user
58
- USER node
59
-
60
- # Install global packages
61
- ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
62
- ENV PATH=$PATH:/usr/local/share/npm-global/bin
63
-
64
- # Set the default shell to zsh rather than sh
65
- ENV SHELL=/bin/zsh
66
-
67
- # Set the default editor and visual
68
- ENV EDITOR=nano
69
- ENV VISUAL=nano
70
-
71
- # Default powerline10k theme
72
- ARG ZSH_IN_DOCKER_VERSION=1.2.0
73
- RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
74
- -p git \
75
- -p fzf \
76
- -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
77
- -a "source /usr/share/doc/fzf/examples/completion.zsh" \
78
- -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
79
- -x
80
-
81
- # Install Claude
82
- RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
83
-
84
- # Install playwright deps
85
- RUN npx --yes playwright install-deps
86
-
87
- RUN npm i -g @playwright/mcp
88
-
89
- # Copy and set up firewall script
90
- COPY init-firewall.sh /usr/local/bin/
91
- USER root
92
- RUN chmod +x /usr/local/bin/init-firewall.sh && \
93
- echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
94
- chmod 0440 /etc/sudoers.d/node-firewall
1
+ FROM node:20
2
+
3
+ ARG TZ
4
+ ENV TZ="$TZ"
5
+
6
+ ARG CLAUDE_CODE_VERSION=latest
7
+
8
+ # Install basic development tools and iptables/ipset
9
+ RUN apt-get update && apt-get install -y --no-install-recommends \
10
+ less \
11
+ git \
12
+ procps \
13
+ sudo \
14
+ fzf \
15
+ zsh \
16
+ man-db \
17
+ unzip \
18
+ gnupg2 \
19
+ gh \
20
+ iptables \
21
+ ipset \
22
+ iproute2 \
23
+ dnsutils \
24
+ aggregate \
25
+ jq \
26
+ nano \
27
+ vim \
28
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
29
+
30
+ # Ensure default node user has access to /usr/local/share
31
+ RUN mkdir -p /usr/local/share/npm-global && \
32
+ chown -R node:node /usr/local/share
33
+
34
+ ARG USERNAME=node
35
+
36
+ # Persist bash history.
37
+ RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
38
+ && mkdir -p /commandhistory \
39
+ && touch /commandhistory/.bash_history \
40
+ && chown -R $USERNAME /commandhistory
41
+
42
+ # Set `DEVCONTAINER` environment variable to help with orientation
43
+ ENV DEVCONTAINER=true
44
+
45
+ # Create workspace and config directories and set permissions
46
+ RUN mkdir -p /workspace /home/node/.claude && \
47
+ chown -R node:node /workspace /home/node/.claude
48
+
49
+ WORKDIR /workspace
50
+
51
+ ARG GIT_DELTA_VERSION=0.18.2
52
+ RUN ARCH=$(dpkg --print-architecture) && \
53
+ wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
54
+ sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
55
+ rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
56
+
57
+ # Set up non-root user
58
+ USER node
59
+
60
+ # Install global packages
61
+ ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
62
+ ENV PATH=$PATH:/usr/local/share/npm-global/bin
63
+
64
+ # Set the default shell to zsh rather than sh
65
+ ENV SHELL=/bin/zsh
66
+
67
+ # Set the default editor and visual
68
+ ENV EDITOR=nano
69
+ ENV VISUAL=nano
70
+
71
+ # Default powerline10k theme
72
+ ARG ZSH_IN_DOCKER_VERSION=1.2.0
73
+ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
74
+ -p git \
75
+ -p fzf \
76
+ -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
77
+ -a "source /usr/share/doc/fzf/examples/completion.zsh" \
78
+ -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
79
+ -x
80
+
81
+ # Install Claude
82
+ RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
83
+
84
+ # Install playwright deps
85
+ RUN npx --yes playwright install-deps
86
+
87
+ RUN npm i -g @playwright/mcp
88
+
89
+ # Copy and set up firewall script
90
+ COPY init-firewall.sh /usr/local/bin/
91
+ USER root
92
+ RUN chmod +x /usr/local/bin/init-firewall.sh && \
93
+ echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
94
+ chmod 0440 /etc/sudoers.d/node-firewall
95
95
  USER node
@@ -0,0 +1,56 @@
1
+ FROM node:20
2
+
3
+ # Install basic development tools
4
+ RUN apt-get update && apt-get install -y --no-install-recommends \
5
+ git \
6
+ curl \
7
+ bash \
8
+ sudo \
9
+ nano \
10
+ vim \
11
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
12
+
13
+ # Create workspace directory
14
+ WORKDIR /workspace
15
+
16
+ # Install Claude Code globally
17
+ RUN npm install -g @anthropic-ai/claude-code@latest
18
+
19
+ # Create startup script for local workspace (no cloning needed)
20
+ RUN echo '#!/bin/bash\n\
21
+ set -e\n\
22
+ \n\
23
+ # Get repository path from environment or default\n\
24
+ REPO_PATH=${REPO_PATH:-"/project"}\n\
25
+ WORKSPACE_DIR="/workspace/project"\n\
26
+ \n\
27
+ echo "🚀 Starting SandboxBox with Claude Code..."\n\
28
+ echo "📁 Working with local repository: $REPO_PATH"\n\
29
+ echo "🎯 Workspace: $WORKSPACE_DIR"\n\
30
+ \n\
31
+ # Create symbolic link to the mounted repository\n\
32
+ if [ -d "$REPO_PATH" ] && [ -d "$REPO_PATH/.git" ]; then\n\
33
+ echo "📂 Creating workspace symlink to local repository..."\n\
34
+ ln -sf "$REPO_PATH" "$WORKSPACE_DIR"\n\
35
+ cd "$WORKSPACE_DIR"\n\
36
+ echo "✅ Workspace linked successfully!"\n\
37
+ echo "📋 Current status:"\n\
38
+ git status\n\
39
+ echo "📁 Repository contents:"\n\
40
+ ls -la\n\
41
+ echo ""\n\
42
+ echo "🔧 Starting Claude Code..."\n\
43
+ echo "💡 Tip: Changes will be saved directly to the local repository"\n\
44
+ echo "💡 Use Ctrl+C to exit Claude Code"\n\
45
+ exec claude\n\
46
+ else\n\
47
+ echo "❌ Error: $REPO_PATH is not a valid git repository"\n\
48
+ echo "Please ensure the path contains a .git directory"\n\
49
+ echo "Contents of $REPO_PATH:"\n\
50
+ ls -la "$REPO_PATH" 2>/dev/null || echo "Directory not accessible"\n\
51
+ exit 1\n\
52
+ fi' > /usr/local/bin/start-local-sandbox.sh && \
53
+ chmod +x /usr/local/bin/start-local-sandbox.sh
54
+
55
+ # Set default command
56
+ CMD ["/usr/local/bin/start-local-sandbox.sh"]