@kokorolx/ai-sandbox-wrapper 3.4.0 → 3.4.2

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/bin/ai-run CHANGED
@@ -823,8 +823,17 @@ if [[ "$TOOL" == "opencode" ]] && command -v jq &>/dev/null && [[ -f "$AI_SANDBO
823
823
  # Deterministic port per container name
824
824
  CONTAINER_HASH=$(echo "$CONTAINER_NAME_VALUE" | md5sum | cut -c1-4)
825
825
  HOST_CHROME_CDP_PORT=$((19222 + 0x$CONTAINER_HASH % 100))
826
- PLAYWRIGHT_MCP_NAME="playwright_port_${HOST_CHROME_CDP_PORT}"
827
- CHROME_DEVTOOLS_MCP_NAME="chrome-devtools_port_${HOST_CHROME_CDP_PORT}"
826
+
827
+ # Only register entries for MCP binaries actually present in the image
828
+ # (tracked in $AI_SANDBOX_CONFIG by setup.sh). Otherwise opencode would
829
+ # try to spawn a missing binary and fail. (is_mcp_installed is defined
830
+ # later in the file, so use jq inline here.)
831
+ if jq -e '.mcp.installed // [] | index("playwright") != null' "$AI_SANDBOX_CONFIG" &>/dev/null; then
832
+ PLAYWRIGHT_MCP_NAME="playwright_port_${HOST_CHROME_CDP_PORT}"
833
+ fi
834
+ if jq -e '.mcp.installed // [] | index("chrome-devtools") != null' "$AI_SANDBOX_CONFIG" &>/dev/null; then
835
+ CHROME_DEVTOOLS_MCP_NAME="chrome-devtools_port_${HOST_CHROME_CDP_PORT}"
836
+ fi
828
837
 
829
838
  # Reuse-if-alive: probe before launching
830
839
  if pmcp::probe_chrome "$HOST_CHROME_CDP_PORT"; then
package/bin/cli.js CHANGED
@@ -21,6 +21,7 @@ Usage:
21
21
 
22
22
  Commands:
23
23
  setup Run interactive setup (configure workspaces, select tools)
24
+ rebuild Rebuild Docker image using existing config (no menu required)
24
25
  update Interactive menu to manage config (workspaces, git, networks)
25
26
  clean Interactive cleanup for caches/configs
26
27
  clean cache [type] Clear shared package caches (npm, bun, pip, playwright-browsers)
@@ -51,6 +52,8 @@ Options:
51
52
 
52
53
  Examples:
53
54
  npx @kokorolx/ai-sandbox-wrapper setup
55
+ npx @kokorolx/ai-sandbox-wrapper rebuild
56
+ npx @kokorolx/ai-sandbox-wrapper rebuild --no-cache
54
57
  npx @kokorolx/ai-sandbox-wrapper update
55
58
  npx @kokorolx/ai-sandbox-wrapper config show --json
56
59
  npx @kokorolx/ai-sandbox-wrapper config tool claude
@@ -108,6 +111,69 @@ function runSetup() {
108
111
  });
109
112
  }
110
113
 
114
+ function runRebuild() {
115
+ const buildScript = path.join(packageRoot, 'lib', 'build-sandbox.sh');
116
+
117
+ if (!fs.existsSync(buildScript)) {
118
+ console.error('❌ Error: lib/build-sandbox.sh not found at', buildScript);
119
+ process.exit(1);
120
+ }
121
+
122
+ const config = readConfig();
123
+ const toolsInstalled = (config.tools && config.tools.installed) || [];
124
+ const mcpInstalled = (config.mcp && config.mcp.installed) || [];
125
+
126
+ if (toolsInstalled.length === 0) {
127
+ console.error('❌ No tools found in ~/.ai-sandbox/config.json');
128
+ console.error(' Run `npx @kokorolx/ai-sandbox-wrapper setup` first.');
129
+ process.exit(1);
130
+ }
131
+
132
+ const hasMcp = (name) => mcpInstalled.includes(name);
133
+ const useHostChrome = !!(config.mcp && config.mcp.chromePath);
134
+
135
+ const buildEnv = {
136
+ ...process.env,
137
+ TOOLS: toolsInstalled.join(','),
138
+ INSTALL_PLAYWRIGHT_MCP: hasMcp('playwright') ? '1' : '0',
139
+ INSTALL_CHROME_DEVTOOLS_MCP: hasMcp('chrome-devtools') ? '1' : '0',
140
+ INSTALL_PLAYWRIGHT_HOST: useHostChrome ? '1' : '0',
141
+ INSTALL_RTK: '0',
142
+ INSTALL_SPEC_KIT: '0',
143
+ INSTALL_UX_UI_PROMAX: '0',
144
+ INSTALL_OPENSPEC: '0',
145
+ INSTALL_PLAYWRIGHT: '0',
146
+ INSTALL_RUBY: '0'
147
+ };
148
+ if (flags.noCache) {
149
+ buildEnv.DOCKER_NO_CACHE = '1';
150
+ }
151
+
152
+ console.log('🔨 Rebuilding Docker image with current config...');
153
+ console.log(` Tools: ${toolsInstalled.join(', ')}`);
154
+ if (mcpInstalled.length > 0) {
155
+ console.log(` MCP: ${mcpInstalled.join(', ')}`);
156
+ }
157
+ if (flags.noCache) {
158
+ console.log(' --no-cache: skipping Docker layer cache');
159
+ }
160
+
161
+ const child = spawn('bash', [buildScript], {
162
+ cwd: packageRoot,
163
+ stdio: 'inherit',
164
+ env: buildEnv
165
+ });
166
+
167
+ child.on('error', (err) => {
168
+ console.error('❌ Error running rebuild:', err.message);
169
+ process.exit(1);
170
+ });
171
+
172
+ child.on('close', (code) => {
173
+ process.exit(code || 0);
174
+ });
175
+ }
176
+
111
177
  function expandHome(inputPath) {
112
178
  if (!inputPath) {
113
179
  return inputPath;
@@ -1313,6 +1379,9 @@ switch (command) {
1313
1379
  case undefined:
1314
1380
  runSetup();
1315
1381
  break;
1382
+ case 'rebuild':
1383
+ runRebuild();
1384
+ break;
1316
1385
  case 'help':
1317
1386
  case '--help':
1318
1387
  case '-h':
@@ -1,6 +1,3 @@
1
- # Build RTK from source (multi-stage: only binary is kept, Rust toolchain discarded)
2
- FROM rust:bookworm AS rtk-builder
3
- RUN cargo install --git https://github.com/rtk-ai/rtk --locked
4
1
 
5
2
  FROM node:22-bookworm-slim
6
3
 
@@ -26,30 +23,6 @@ RUN npm install -g typescript typescript-language-server pyright vscode-langserv
26
23
  RUN node --version && npm --version && pnpm --version && tsc --version
27
24
 
28
25
  # Install additional tools (if selected)
29
- RUN PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin pipx install specify-cli --pip-args="git+https://github.com/github/spec-kit.git" && \
30
- chmod +x /usr/local/bin/specify && \
31
- ln -sf /usr/local/bin/specify /usr/local/bin/specify-cli
32
- RUN mkdir -p /usr/local/lib/uipro-cli && \
33
- cd /usr/local/lib/uipro-cli && \
34
- npm init -y && \
35
- npm install uipro-cli && \
36
- ln -sf /usr/local/lib/uipro-cli/node_modules/.bin/uipro /usr/local/bin/uipro && \
37
- ln -sf /usr/local/bin/uipro /usr/local/bin/uipro-cli && \
38
- chmod -R 755 /usr/local/lib/uipro-cli && \
39
- chmod +x /usr/local/bin/uipro
40
- RUN mkdir -p /usr/local/lib/openspec && \
41
- cd /usr/local/lib/openspec && \
42
- npm init -y && \
43
- npm install @fission-ai/openspec && \
44
- ln -sf /usr/local/lib/openspec/node_modules/.bin/openspec /usr/local/bin/openspec && \
45
- chmod -R 755 /usr/local/lib/openspec && \
46
- chmod +x /usr/local/bin/openspec
47
- # Install RTK - token optimizer for AI coding agents (built from source)
48
- COPY --from=rtk-builder /usr/local/cargo/bin/rtk /usr/local/bin/rtk
49
- # Install RTK OpenCode skills (auto-discovered by OpenCode agents)
50
- RUN mkdir -p /home/agent/.config/opencode/skills/rtk /home/agent/.config/opencode/skills/rtk-setup
51
- COPY skills/rtk/SKILL.md /home/agent/.config/opencode/skills/rtk/SKILL.md
52
- COPY skills/rtk-setup/SKILL.md /home/agent/.config/opencode/skills/rtk-setup/SKILL.md
53
26
  RUN apt-get update && apt-get install -y --no-install-recommends \
54
27
  libglib2.0-0 \
55
28
  libnspr4 \
@@ -83,13 +56,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
83
56
  ENV PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers
84
57
  RUN mkdir -p /opt/playwright-browsers && \
85
58
  npm install -g @playwright/mcp@latest && \
86
- npx playwright-core install --no-shell chromium && \
87
- npx playwright-core install-deps chromium && \
88
- chmod -R 777 /opt/playwright-browsers && \
89
- ln -sf $(ls -d /opt/playwright-browsers/chromium-*/chrome-linux/chrome | sort -V | tail -1) /opt/chromium
59
+ touch /opt/.mcp-playwright-installed
90
60
  ENV CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS=1
91
61
  RUN npm install -g chrome-devtools-mcp@latest && \
92
62
  touch /opt/.mcp-chrome-devtools-installed
63
+ RUN touch /opt/.mcp-playwright-installed
93
64
 
94
65
  # Create workspace
95
66
  WORKDIR /workspace
@@ -1,6 +1,3 @@
1
- # Build RTK from source (multi-stage: only binary is kept, Rust toolchain discarded)
2
- FROM rust:bookworm AS rtk-builder
3
- RUN cargo install --git https://github.com/rtk-ai/rtk --locked
4
1
 
5
2
  FROM node:22-bookworm-slim
6
3
 
@@ -26,30 +23,6 @@ RUN npm install -g typescript typescript-language-server pyright vscode-langserv
26
23
  RUN node --version && npm --version && pnpm --version && tsc --version
27
24
 
28
25
  # Install additional tools (if selected)
29
- RUN PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin pipx install specify-cli --pip-args="git+https://github.com/github/spec-kit.git" && \
30
- chmod +x /usr/local/bin/specify && \
31
- ln -sf /usr/local/bin/specify /usr/local/bin/specify-cli
32
- RUN mkdir -p /usr/local/lib/uipro-cli && \
33
- cd /usr/local/lib/uipro-cli && \
34
- npm init -y && \
35
- npm install uipro-cli && \
36
- ln -sf /usr/local/lib/uipro-cli/node_modules/.bin/uipro /usr/local/bin/uipro && \
37
- ln -sf /usr/local/bin/uipro /usr/local/bin/uipro-cli && \
38
- chmod -R 755 /usr/local/lib/uipro-cli && \
39
- chmod +x /usr/local/bin/uipro
40
- RUN mkdir -p /usr/local/lib/openspec && \
41
- cd /usr/local/lib/openspec && \
42
- npm init -y && \
43
- npm install @fission-ai/openspec && \
44
- ln -sf /usr/local/lib/openspec/node_modules/.bin/openspec /usr/local/bin/openspec && \
45
- chmod -R 755 /usr/local/lib/openspec && \
46
- chmod +x /usr/local/bin/openspec
47
- # Install RTK - token optimizer for AI coding agents (built from source)
48
- COPY --from=rtk-builder /usr/local/cargo/bin/rtk /usr/local/bin/rtk
49
- # Install RTK OpenCode skills (auto-discovered by OpenCode agents)
50
- RUN mkdir -p /home/agent/.config/opencode/skills/rtk /home/agent/.config/opencode/skills/rtk-setup
51
- COPY skills/rtk/SKILL.md /home/agent/.config/opencode/skills/rtk/SKILL.md
52
- COPY skills/rtk-setup/SKILL.md /home/agent/.config/opencode/skills/rtk-setup/SKILL.md
53
26
  RUN apt-get update && apt-get install -y --no-install-recommends \
54
27
  libglib2.0-0 \
55
28
  libnspr4 \
@@ -83,13 +56,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
83
56
  ENV PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers
84
57
  RUN mkdir -p /opt/playwright-browsers && \
85
58
  npm install -g @playwright/mcp@latest && \
86
- npx playwright-core install --no-shell chromium && \
87
- npx playwright-core install-deps chromium && \
88
- chmod -R 777 /opt/playwright-browsers && \
89
- ln -sf $(ls -d /opt/playwright-browsers/chromium-*/chrome-linux/chrome | sort -V | tail -1) /opt/chromium
59
+ touch /opt/.mcp-playwright-installed
90
60
  ENV CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS=1
91
61
  RUN npm install -g chrome-devtools-mcp@latest && \
92
62
  touch /opt/.mcp-chrome-devtools-installed
63
+ RUN touch /opt/.mcp-playwright-installed
93
64
 
94
65
  # Create workspace
95
66
  WORKDIR /workspace
@@ -106,12 +77,13 @@ RUN curl -fsSL https://opencode.ai/install | bash && \
106
77
  mv /root/.opencode/bin/opencode /usr/local/bin/opencode && \
107
78
  rm -rf /root/.opencode
108
79
 
109
- # === claude ===
80
+ # === codex ===
110
81
  USER root
111
- RUN export HOME=/root && curl -fsSL https://claude.ai/install.sh | bash && \
112
- mkdir -p /usr/local/share && \
113
- mv /root/.local/share/claude /usr/local/share/claude && \
114
- ln -sf /usr/local/share/claude/versions/$(ls /usr/local/share/claude/versions | head -1) /usr/local/bin/claude
82
+ RUN mkdir -p /usr/local/lib/codex && \
83
+ cd /usr/local/lib/codex && \
84
+ bun init -y && \
85
+ bun add @openai/codex && \
86
+ ln -s /usr/local/lib/codex/node_modules/.bin/codex /usr/local/bin/codex
115
87
  USER agent
116
88
 
117
89
  USER agent
@@ -88,20 +88,25 @@ pmcp::register() {
88
88
  echo " ➕ pmcp: registered $key"
89
89
  }
90
90
 
91
- # Register both playwright-mcp and chrome-devtools-mcp for a host Chrome on
91
+ # Register playwright-mcp and/or chrome-devtools-mcp for a host Chrome on
92
92
  # a given CDP port. Sweeps dead entries of both prefixes first, then writes
93
- # the new entries. MUST be called inside a flock.
94
- # Args: $1 = cfg, $2 = port, $3 = playwright key, $4 = chrome-devtools key
93
+ # the requested entries. Pass empty string for a key to skip that one.
94
+ # MUST be called inside a flock.
95
+ # Args: $1 = cfg, $2 = port, $3 = playwright key (or ""), $4 = chrome-devtools key (or "")
95
96
  pmcp::register_host_chrome() {
96
97
  local cfg="$1" port="$2" pw_key="$3" cd_key="$4"
97
98
  local url="http://$PMCP_DOCKER_HOST_IP:$port"
98
99
 
99
100
  pmcp::sweep_dead "$cfg" "playwright_"
100
101
  pmcp::sweep_dead "$cfg" "chrome-devtools_"
101
- pmcp::register "$cfg" "$pw_key" \
102
- "[\"playwright-mcp\",\"--cdp-endpoint\",\"$url\"]"
103
- pmcp::register "$cfg" "$cd_key" \
104
- "[\"chrome-devtools-mcp\",\"--browserUrl\",\"$url\"]"
102
+ if [[ -n "$pw_key" ]]; then
103
+ pmcp::register "$cfg" "$pw_key" \
104
+ "[\"playwright-mcp\",\"--cdp-endpoint\",\"$url\"]"
105
+ fi
106
+ if [[ -n "$cd_key" ]]; then
107
+ pmcp::register "$cfg" "$cd_key" \
108
+ "[\"chrome-devtools-mcp\",\"--browserUrl\",\"$url\"]"
109
+ fi
105
110
  }
106
111
 
107
112
  # Sweep dead playwright_* entries and append a new one. MUST be called inside
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kokorolx/ai-sandbox-wrapper",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "description": "Docker-based security sandbox for AI coding agents. Isolate Claude, Gemini, Aider, and other AI tools from your host system.",
5
5
  "keywords": [
6
6
  "ai",
package/setup.sh CHANGED
@@ -382,14 +382,14 @@ if [[ ${#CONTAINERIZED_TOOLS[@]} -gt 0 || ${#ADDITIONAL_TOOLS[@]} -gt 0 ]]; then
382
382
  fi
383
383
 
384
384
  if [[ $NEEDS_BASE_IMAGE -eq 1 ]]; then
385
- INSTALL_SPEC_KIT=0
386
- INSTALL_UX_UI_PROMAX=0
387
- INSTALL_OPENSPEC=0
388
- INSTALL_PLAYWRIGHT=0
389
- INSTALL_RUBY=0
390
- INSTALL_CHROME_DEVTOOLS_MCP=0
391
- INSTALL_PLAYWRIGHT_MCP=0
392
- INSTALL_RTK=0
385
+ INSTALL_SPEC_KIT="${INSTALL_SPEC_KIT:-0}"
386
+ INSTALL_UX_UI_PROMAX="${INSTALL_UX_UI_PROMAX:-0}"
387
+ INSTALL_OPENSPEC="${INSTALL_OPENSPEC:-0}"
388
+ INSTALL_PLAYWRIGHT="${INSTALL_PLAYWRIGHT:-0}"
389
+ INSTALL_RUBY="${INSTALL_RUBY:-0}"
390
+ INSTALL_CHROME_DEVTOOLS_MCP="${INSTALL_CHROME_DEVTOOLS_MCP:-0}"
391
+ INSTALL_PLAYWRIGHT_MCP="${INSTALL_PLAYWRIGHT_MCP:-0}"
392
+ INSTALL_RTK="${INSTALL_RTK:-0}"
393
393
 
394
394
  for addon in "${ADDITIONAL_TOOLS[@]}"; do
395
395
  case "$addon" in