vagrant-claude-sandbox 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b41524c843f1c62cda68ca45015a524bfbdade5bd81d5fba9ca1b9d700cae84
4
- data.tar.gz: dea52ec2514c2f0fdafa87374b5ff25b4b82381d2673d96968c72c6ee0e0b5ef
3
+ metadata.gz: a0c3f6d76bc6a8854641197815ae4e7a1b5685a322576d72969d8e00b82b39d7
4
+ data.tar.gz: 67eb291fdbefa65b04a48d684e89658955c7819d9f49df469a27d1b8b035cd38
5
5
  SHA512:
6
- metadata.gz: 5df48ce7440d827876072a884ae460e4b4fdf25e88b0455799fa3ce1ab7272c30a1b2ad6f2055b36dee52acbc328c74e4dc73a822b2e2af0066b9dec453c0265
7
- data.tar.gz: b6af4d17d0f8260223250ebbbf8ee5bd38dcf6f84bd929cbbdf3e0a72f6275d09fb97619a0ca9dfa94cf0c99ef38c822917fc9d17b51f86cf27425d6d78b1875
6
+ metadata.gz: 0da4554053ffc441c32e1f97e0be973aead1bc98b8a77d62956987b4f4f9413709e935c48731bea51740f52f20ef78f44331ca422ad86c3c082173776af26d68
7
+ data.tar.gz: bf1b40b5839f36a84180436c120af389eb7b3d92aadacf3172520e2f5b8ec01a4396230f7c237fb1450a79f0400ed171becf14716914fdc0be18d492d816641b
data/README.md CHANGED
@@ -1,20 +1,20 @@
1
1
  # Vagrant Claude Sandbox
2
2
 
3
- A Vagrant plugin for running Claude Code in an isolated VM sandbox.
3
+ A Vagrant plugin for running Claude Code in an isolated sandbox environment.
4
4
 
5
5
  ## Features
6
6
 
7
- - Ubuntu 24.04 LTS with Docker, Node.js, git pre-installed
7
+ - Fast container-based sandbox using Docker
8
+ - Ubuntu 24.04 LTS with Node.js and git pre-installed
8
9
  - Automatic Claude Code CLI installation
9
- - Synced workspace folder and Claude config
10
- - **Full Claude plugins and skills support** - automatically loads your installed plugins and skills with fixed paths
11
- - `claude-yolo` wrapper (runs Claude with `--dangerously-skip-permissions`)
12
- - Customizable VM resources
10
+ - Synced workspace folder and Claude config (plugins and skills work automatically)
11
+ - Customizable resources (memory, CPUs)
12
+ - Optional VirtualBox provider for full VM isolation
13
13
 
14
14
  ## Prerequisites
15
15
 
16
16
  - [Vagrant](https://www.vagrantup.com/downloads) >= 2.2.0
17
- - [VirtualBox](https://www.virtualbox.org/wiki/Downloads) >= 6.1
17
+ - [Docker](https://docs.docker.com/get-docker/) (default provider)
18
18
 
19
19
  ## Installation
20
20
 
@@ -32,12 +32,17 @@ Vagrant.configure("2") do |config|
32
32
  end
33
33
  ```
34
34
 
35
- Start the VM:
35
+ Start the sandbox:
36
36
 
37
37
  ```bash
38
38
  vagrant up
39
- vagrant ssh
40
- claude-yolo # Inside VM
39
+ vagrant claude # Launch Claude CLI with Chrome integration
40
+ ```
41
+
42
+ Access a normal shell:
43
+
44
+ ```bash
45
+ vagrant ssh # Regular shell session
41
46
  ```
42
47
 
43
48
  ### Custom Configuration
@@ -52,31 +57,121 @@ Vagrant.configure("2") do |config|
52
57
  end
53
58
  ```
54
59
 
60
+ ### Mounting Additional Directories
61
+
62
+ Mount additional directories using Vagrant's `synced_folder` directive:
63
+
64
+ ```ruby
65
+ Vagrant.configure("2") do |config|
66
+ config.claude_sandbox.apply_to!(config) do |sandbox|
67
+ sandbox.memory = 8192
68
+ sandbox.cpus = 4
69
+ end
70
+
71
+ config.vm.synced_folder "~/Projects/my-project", "/my-project"
72
+ end
73
+ ```
74
+
75
+ **Note:** The workspace (`/agent-workspace`) and Claude config (`~/.claude/`) are mounted automatically.
76
+
55
77
  ### Options
56
78
 
57
79
  | Option | Default | Description |
58
80
  |--------|---------|-------------|
81
+ | `provider` | `"docker"` | Provider: `"docker"` or `"virtualbox"` |
59
82
  | `memory` | `4096` | RAM in MB |
60
83
  | `cpus` | `2` | Number of CPUs |
61
- | `box` | `"bento/ubuntu-24.04"` | Vagrant box |
62
- | `workspace_path` | `"/agent-workspace"` | Workspace path in VM |
84
+ | `workspace_path` | `"/agent-workspace"` | Workspace path in container/VM |
63
85
  | `claude_config_path` | `"~/.claude/"` | Host Claude config path |
64
- | `skip_claude_cli_install` | `false` | Skip Claude CLI installation |
65
86
  | `additional_packages` | `[]` | Extra apt packages |
87
+ | `skip_claude_cli_install` | `false` | Skip Claude CLI installation |
88
+ | `ubuntu_mirror` | `nil` | Ubuntu package mirror URL (uses official mirror by default) |
89
+
90
+ ## VirtualBox Provider
91
+
92
+ For full VM isolation or Docker-in-Docker capabilities:
93
+
94
+ ```ruby
95
+ Vagrant.configure("2") do |config|
96
+ config.claude_sandbox.provider = "virtualbox"
97
+ config.claude_sandbox.apply_to!(config)
98
+ end
99
+ ```
100
+
101
+ **When to use VirtualBox:**
102
+ - You need Docker available inside the sandbox
103
+ - You need full VM isolation (kernel-level)
104
+ - You're running on a system without Docker
66
105
 
67
- ## Plugin and Skills Support
106
+ **Prerequisites:**
107
+ - [VirtualBox](https://www.virtualbox.org/wiki/Downloads) >= 6.1
108
+
109
+ ### Ubuntu Mirror Configuration
68
110
 
69
- This plugin automatically copies your `~/.claude/` directory to the VM and fixes absolute paths in plugin configuration files. This means:
111
+ By default, the plugin uses Ubuntu's official mirror (`http://ports.ubuntu.com/ubuntu-ports`). If package updates are slow in your region, you can configure a faster mirror:
112
+
113
+ ```ruby
114
+ Vagrant.configure("2") do |config|
115
+ # Choose a mirror close to your location for faster updates
116
+ config.claude_sandbox.ubuntu_mirror = "http://ftp.jaist.ac.jp/pub/Linux/ubuntu-ports" # Japan
117
+ config.claude_sandbox.apply_to!(config)
118
+ end
119
+ ```
120
+
121
+ **Trusted mirrors for ARM (ubuntu-ports):**
122
+ - Official Ubuntu: `http://ports.ubuntu.com/ubuntu-ports` (default, safest)
123
+ - JAIST (Japan): `http://ftp.jaist.ac.jp/pub/Linux/ubuntu-ports` (university mirror)
124
+ - Kakao (Korea): `http://mirror.kakao.com/ubuntu-ports` (major tech company)
125
+
126
+ **Security note:** Only use mirrors from trusted sources. The official Ubuntu mirror is always the safest option.
127
+
128
+ ## Development and Testing
129
+
130
+ ### Running Tests
131
+
132
+ The project includes comprehensive unit and integration tests:
133
+
134
+ ```bash
135
+ # Install development dependencies
136
+ bundle install
70
137
 
71
- - All your installed Claude plugins will work in the VM
72
- - All your custom skills will be available
73
- - Plugin paths are automatically updated from host paths to VM paths
138
+ # Run unit tests
139
+ bundle exec rake spec
74
140
 
75
- The plugin configuration files that are updated:
76
- - `~/.claude/plugins/installed_plugins.json`
77
- - `~/.claude/plugins/known_marketplaces.json`
141
+ # Run integration tests
142
+ ./test-plugin.sh docker --skip-extended # Quick test
78
143
 
79
- This ensures that plugins and skills that reference local file paths will work correctly inside the VM environment.
144
+ # Run all tests
145
+ bundle exec rake test
146
+ ```
147
+
148
+ See [TESTING.md](TESTING.md) for detailed testing instructions.
149
+
150
+ ### Contributing
151
+
152
+ 1. Fork the repository
153
+ 2. Create a feature branch
154
+ 3. Add tests for your changes
155
+ 4. Ensure all tests pass: `bundle exec rake test`
156
+ 5. Submit a pull request
157
+
158
+ ## Troubleshooting
159
+
160
+ ### Docker "Permission denied" Error
161
+
162
+ **This is now handled automatically by the plugin!**
163
+
164
+ The plugin automatically detects and fixes PATH conflicts that could cause "Permission denied" errors with the Docker provider. If you have a directory named `docker` in your PATH before the actual Docker executable, the plugin will reorder your PATH to prioritize common Docker binary locations.
165
+
166
+ You should see a message during `vagrant up` if a conflict was detected and fixed:
167
+ ```
168
+ Detected Docker PATH conflict - automatically reordered PATH
169
+ ```
170
+
171
+ If you're still experiencing issues, you can manually fix the PATH as a fallback:
172
+ ```bash
173
+ PATH=/usr/local/bin:$PATH vagrant up
174
+ ```
80
175
 
81
176
  ## Credits
82
177
 
@@ -0,0 +1,33 @@
1
+ FROM ubuntu:24.04
2
+
3
+ ENV DEBIAN_FRONTEND=noninteractive
4
+
5
+ # Install SSH and basic packages
6
+ RUN apt-get update && apt-get install -y \
7
+ openssh-server \
8
+ sudo \
9
+ curl \
10
+ git \
11
+ && rm -rf /var/lib/apt/lists/*
12
+
13
+ # Configure SSH
14
+ RUN mkdir /var/run/sshd
15
+ RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
16
+ RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
17
+
18
+ # Create vagrant user (Vagrant expects this)
19
+ RUN useradd -m -s /bin/bash vagrant && \
20
+ echo "vagrant:vagrant" | chpasswd && \
21
+ echo "vagrant ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
22
+
23
+ # Set up SSH key directory and install Vagrant insecure key
24
+ RUN mkdir -p /home/vagrant/.ssh && \
25
+ chmod 700 /home/vagrant/.ssh && \
26
+ curl -fsSL https://raw.githubusercontent.com/hashicorp/vagrant/main/keys/vagrant.pub \
27
+ -o /home/vagrant/.ssh/authorized_keys && \
28
+ chmod 600 /home/vagrant/.ssh/authorized_keys && \
29
+ chown -R vagrant:vagrant /home/vagrant/.ssh
30
+
31
+ EXPOSE 22
32
+
33
+ CMD ["/usr/sbin/sshd", "-D"]
@@ -0,0 +1,41 @@
1
+ module VagrantPlugins
2
+ module ClaudeSandbox
3
+ class Command < Vagrant.plugin("2", :command)
4
+ def self.synopsis
5
+ "SSH into the VM and launch Claude CLI"
6
+ end
7
+
8
+ def execute
9
+ options = {}
10
+ opts = OptionParser.new do |o|
11
+ o.banner = "Usage: vagrant claude [-- extra ssh args]"
12
+ o.separator ""
13
+ o.separator self.class.synopsis
14
+ o.separator ""
15
+ o.separator "This will SSH into the VM, cd to the workspace, and launch Claude CLI"
16
+ o.separator "with Chrome integration enabled."
17
+ end
18
+
19
+ # Parse the options
20
+ argv = parse_options(opts)
21
+ return if !argv
22
+
23
+ # Get the machine
24
+ with_target_vms(argv, single_target: true) do |machine|
25
+ # Get workspace path from config
26
+ config = machine.config.claude_sandbox
27
+ workspace_path = config.workspace_path || "/agent-workspace"
28
+
29
+ # Build the command to run
30
+ command = "cd #{workspace_path}; . ~/.nvm/nvm.sh && exec claude --dangerously-skip-permissions --chrome"
31
+
32
+ # Execute SSH with the command
33
+ machine.action(:ssh_run, ssh_run_command: command, ssh_opts: { extra_args: ["-t"] })
34
+ end
35
+
36
+ # Success
37
+ 0
38
+ end
39
+ end
40
+ end
41
+ end
@@ -8,6 +8,9 @@ module VagrantPlugins
8
8
  attr_accessor :claude_config_path
9
9
  attr_accessor :skip_claude_cli_install
10
10
  attr_accessor :additional_packages
11
+ attr_accessor :provider # "virtualbox" or "docker"
12
+ attr_accessor :docker_image # Docker image (default: build from Dockerfile)
13
+ attr_accessor :ubuntu_mirror # Ubuntu mirror URL (default: nil, uses official mirror)
11
14
 
12
15
  def initialize
13
16
  @memory = UNSET_VALUE
@@ -17,6 +20,9 @@ module VagrantPlugins
17
20
  @claude_config_path = UNSET_VALUE
18
21
  @skip_claude_cli_install = UNSET_VALUE
19
22
  @additional_packages = UNSET_VALUE
23
+ @provider = UNSET_VALUE
24
+ @docker_image = UNSET_VALUE
25
+ @ubuntu_mirror = UNSET_VALUE
20
26
  end
21
27
 
22
28
  def finalize!
@@ -27,6 +33,9 @@ module VagrantPlugins
27
33
  @claude_config_path = File.expand_path("~/.claude/") if @claude_config_path == UNSET_VALUE
28
34
  @skip_claude_cli_install = false if @skip_claude_cli_install == UNSET_VALUE
29
35
  @additional_packages = [] if @additional_packages == UNSET_VALUE
36
+ @provider = "virtualbox" if @provider == UNSET_VALUE
37
+ @docker_image = nil if @docker_image == UNSET_VALUE
38
+ @ubuntu_mirror = nil if @ubuntu_mirror == UNSET_VALUE
30
39
  end
31
40
 
32
41
  def validate(machine)
@@ -44,6 +53,10 @@ module VagrantPlugins
44
53
  errors << "additional_packages must be an array"
45
54
  end
46
55
 
56
+ if @provider != UNSET_VALUE && !["virtualbox", "docker"].include?(@provider)
57
+ errors << "provider must be 'virtualbox' or 'docker'"
58
+ end
59
+
47
60
  { "Claude Sandbox" => errors }
48
61
  end
49
62
 
@@ -52,9 +65,24 @@ module VagrantPlugins
52
65
  # Ensure values are finalized before use
53
66
  finalize!
54
67
 
55
- # Set the box
56
- root_config.vm.box = @box
68
+ # Common configuration
69
+ apply_common_config!(root_config)
70
+
71
+ # Always configure both providers
72
+ # Vagrant will choose the appropriate one based on:
73
+ # 1. --provider flag from command line
74
+ # 2. Existing .vagrant directory state
75
+ # 3. Default provider (VirtualBox)
76
+ apply_virtualbox_config!(root_config)
77
+ apply_docker_config!(root_config)
57
78
 
79
+ # Provisioning (with provider awareness)
80
+ apply_provisioning!(root_config)
81
+ end
82
+
83
+ private
84
+
85
+ def apply_common_config!(root_config)
58
86
  # Configure synced folder for workspace
59
87
  root_config.vm.synced_folder ".", @workspace_path,
60
88
  create: true,
@@ -68,33 +96,70 @@ module VagrantPlugins
68
96
  destination: "/tmp/claude-config"
69
97
  end
70
98
 
71
- # Configure provider (VirtualBox)
72
- root_config.vm.provider "virtualbox" do |vb|
99
+ # Configure SSH port with auto-correction for conflicts
100
+ root_config.vm.network :forwarded_port, guest: 22, host: 2200, id: "ssh", auto_correct: true
101
+ end
102
+
103
+ def apply_virtualbox_config!(root_config)
104
+ root_config.vm.provider "virtualbox" do |vb, override|
105
+ # Set box only for VirtualBox provider
106
+ override.vm.box = @box
73
107
  vb.memory = @memory
74
108
  vb.cpus = @cpus
75
109
  vb.customize ["modifyvm", :id, "--audio", "none"]
76
110
  vb.customize ["modifyvm", :id, "--usb", "off"]
77
111
  end
112
+ end
113
+
114
+ def apply_docker_config!(root_config)
115
+ root_config.vm.provider "docker" do |d|
116
+ if @docker_image
117
+ d.image = @docker_image
118
+ else
119
+ d.build_dir = File.expand_path("../../docker", __FILE__)
120
+ end
121
+ d.has_ssh = true
122
+ d.remains_running = true
123
+ d.create_args = ["--memory=#{@memory}m", "--cpus=#{@cpus}"]
124
+ end
125
+ end
78
126
 
79
- # Provision the VM
127
+ def apply_provisioning!(root_config)
80
128
  unless @skip_claude_cli_install
81
129
  root_config.vm.provision "shell",
82
130
  inline: generate_provision_script,
83
131
  env: {"HOST_CLAUDE_PATH" => @claude_config_path}
84
132
  end
85
-
86
- # Configure SSH to auto-cd to workspace
87
- root_config.ssh.extra_args = ["-t", "cd #{@workspace_path}; bash --login"]
88
133
  end
89
134
 
90
- private
91
-
92
135
  def generate_provision_script
93
136
  additional_packages = @additional_packages.join(" ")
137
+ skip_docker = @provider == "docker"
138
+
139
+ docker_install_script = skip_docker ? "" : <<-DOCKER
140
+ # Install Docker
141
+ if ! command -v docker &> /dev/null; then
142
+ echo "Installing Docker..."
143
+ curl -fsSL https://get.docker.com -o get-docker.sh
144
+ sh get-docker.sh
145
+ usermod -aG docker vagrant
146
+ rm get-docker.sh
147
+ else
148
+ echo "Docker already installed"
149
+ fi
150
+ DOCKER
151
+
152
+ mirror_config = @ubuntu_mirror ? <<-MIRROR
153
+ # Switch to faster Ubuntu mirror
154
+ echo "Configuring Ubuntu mirror: #{@ubuntu_mirror}"
155
+ sed -i 's|http://ports.ubuntu.com/ubuntu-ports|#{@ubuntu_mirror}|g' /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null || true
156
+ sed -i 's|http://ports.ubuntu.com/ubuntu-ports|#{@ubuntu_mirror}|g' /etc/apt/sources.list 2>/dev/null || true
157
+ MIRROR
158
+ : ""
94
159
 
95
160
  script = <<-SHELL
96
161
  set -e
97
-
162
+ #{mirror_config}
98
163
  echo "Updating package lists..."
99
164
  apt-get update
100
165
 
@@ -109,30 +174,33 @@ module VagrantPlugins
109
174
  unzip \
110
175
  #{additional_packages}
111
176
 
112
- # Install Docker
113
- if ! command -v docker &> /dev/null; then
114
- echo "Installing Docker..."
115
- curl -fsSL https://get.docker.com -o get-docker.sh
116
- sh get-docker.sh
117
- usermod -aG docker vagrant
118
- rm get-docker.sh
119
- else
120
- echo "Docker already installed"
121
- fi
177
+ #{docker_install_script}
178
+
179
+ # Install nvm for the vagrant user
180
+ if [ ! -d "/home/vagrant/.nvm" ]; then
181
+ echo "Installing nvm..."
182
+ # Install nvm as vagrant user
183
+ sudo -u vagrant bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash'
184
+
185
+ # Load nvm in this script
186
+ export NVM_DIR="/home/vagrant/.nvm"
187
+ [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
122
188
 
123
- # Install Node.js and npm
124
- if ! command -v node &> /dev/null; then
125
- echo "Installing Node.js..."
126
- curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
127
- apt-get install -y nodejs
189
+ # Install Node.js LTS version
190
+ echo "Installing Node.js LTS via nvm..."
191
+ sudo -u vagrant bash -c '. /home/vagrant/.nvm/nvm.sh && nvm install --lts && nvm use --lts'
128
192
  else
129
- echo "Node.js already installed"
193
+ echo "nvm already installed"
130
194
  fi
131
195
 
196
+ # Ensure nvm is loaded for subsequent commands
197
+ export NVM_DIR="/home/vagrant/.nvm"
198
+ [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
199
+
132
200
  # Install Claude Code CLI
133
- if ! command -v claude &> /dev/null; then
201
+ if ! sudo -u vagrant bash -c '. /home/vagrant/.nvm/nvm.sh && command -v claude' &> /dev/null; then
134
202
  echo "Installing Claude Code CLI..."
135
- npm install -g @anthropic-ai/claude-code --no-audit
203
+ sudo -u vagrant bash -c '. /home/vagrant/.nvm/nvm.sh && npm install -g @anthropic-ai/claude-code --no-audit'
136
204
  else
137
205
  echo "Claude Code CLI already installed"
138
206
  fi
@@ -155,16 +223,7 @@ module VagrantPlugins
155
223
  echo "Claude plugins and skills loaded successfully!"
156
224
  fi
157
225
 
158
- # Create claude-yolo wrapper
159
- echo "Creating claude-yolo command..."
160
- cat > /usr/local/bin/claude-yolo << 'EOF'
161
- #!/bin/bash
162
- claude --dangerously-skip-permissions "$@"
163
- EOF
164
- chmod +x /usr/local/bin/claude-yolo
165
-
166
226
  echo "Claude sandbox environment setup complete!"
167
- echo "You can now run 'claude-yolo' to start Claude Code with permissions disabled"
168
227
  SHELL
169
228
 
170
229
  script
@@ -0,0 +1,73 @@
1
+ module VagrantPlugins
2
+ module ClaudeSandbox
3
+ class PathFixer
4
+ def self.fix_docker_path!
5
+ # Always check for PATH conflicts and fix them
6
+ # This is necessary because commands like 'vagrant destroy' don't have --provider flag
7
+ # but still need the correct PATH to interact with Docker containers
8
+
9
+ # Check if there's a PATH conflict
10
+ path_dirs = ENV['PATH'].split(':')
11
+ docker_binary_path = find_docker_binary
12
+
13
+ return unless docker_binary_path
14
+
15
+ docker_dir = File.dirname(docker_binary_path)
16
+
17
+ # Check if there's a directory named 'docker' appearing before the real docker binary
18
+ conflict_detected = false
19
+ path_dirs.each_with_index do |dir, index|
20
+ # If we find the real docker directory, stop checking
21
+ break if dir == docker_dir
22
+
23
+ # Check if this directory has a 'docker' subdirectory or file that would conflict
24
+ potential_conflict = File.join(dir, 'docker')
25
+ if File.exist?(potential_conflict) && File.directory?(potential_conflict)
26
+ conflict_detected = true
27
+ break
28
+ end
29
+ end
30
+
31
+ if conflict_detected
32
+ # Reorder PATH to put common Docker binary locations first
33
+ prioritized_paths = ['/usr/local/bin', '/usr/bin', docker_dir].uniq
34
+ other_paths = path_dirs - prioritized_paths
35
+ new_path = (prioritized_paths + other_paths).join(':')
36
+
37
+ ENV['PATH'] = new_path
38
+ # Only show message for commands that actually use Docker
39
+ if using_docker_related_command?
40
+ puts "Detected Docker PATH conflict - automatically reordered PATH"
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def self.using_docker_related_command?
48
+ # Check if this is a Docker-related command
49
+ ARGV.include?('--provider=docker') ||
50
+ ARGV.include?('--provider docker') ||
51
+ ENV['VAGRANT_DEFAULT_PROVIDER'] == 'docker' ||
52
+ ARGV.include?('up') ||
53
+ ARGV.include?('destroy') ||
54
+ ARGV.include?('halt') ||
55
+ ARGV.include?('reload') ||
56
+ ARGV.include?('ssh')
57
+ end
58
+
59
+ def self.find_docker_binary
60
+ # Try common Docker installation paths
61
+ ['/usr/local/bin/docker', '/usr/bin/docker', '/opt/homebrew/bin/docker'].each do |path|
62
+ return path if File.executable?(path)
63
+ end
64
+
65
+ # Fall back to using 'which' if available
66
+ result = `which docker 2>/dev/null`.strip
67
+ result.empty? ? nil : result
68
+ rescue
69
+ nil
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,8 @@
1
+ require_relative "path_fixer"
2
+
3
+ # Fix Docker PATH issues immediately when plugin loads (before Vagrant initialization)
4
+ VagrantPlugins::ClaudeSandbox::PathFixer.fix_docker_path!
5
+
1
6
  module VagrantPlugins
2
7
  module ClaudeSandbox
3
8
  class Plugin < Vagrant.plugin("2")
@@ -8,6 +13,11 @@ module VagrantPlugins
8
13
  require_relative "config"
9
14
  Config
10
15
  end
16
+
17
+ command "claude" do
18
+ require_relative "command"
19
+ Command
20
+ end
11
21
  end
12
22
  end
13
23
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module ClaudeSandbox
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-claude-sandbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-22 00:00:00.000000000 Z
11
+ date: 2026-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '13.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
26
+ version: '13.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '13.0'
33
+ version: '3.12'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '13.0'
40
+ version: '3.12'
41
41
  description: Provides a pre-configured sandbox environment for running Claude Code
42
42
  in an isolated VM with full plugin and skills support
43
43
  email:
@@ -47,8 +47,11 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - LICENSE
49
49
  - README.md
50
+ - lib/docker/Dockerfile
50
51
  - lib/vagrant-claude-sandbox.rb
52
+ - lib/vagrant-claude-sandbox/command.rb
51
53
  - lib/vagrant-claude-sandbox/config.rb
54
+ - lib/vagrant-claude-sandbox/path_fixer.rb
52
55
  - lib/vagrant-claude-sandbox/plugin.rb
53
56
  - lib/vagrant-claude-sandbox/version.rb
54
57
  homepage: https://github.com/bgrgicak/vagrant-claude-sandbox