@kokorolx/ai-sandbox-wrapper 1.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.
Files changed (45) hide show
  1. package/README.md +540 -0
  2. package/bin/ai-debug +116 -0
  3. package/bin/ai-network +144 -0
  4. package/bin/ai-run +631 -0
  5. package/bin/cli.js +83 -0
  6. package/bin/setup-ssh-config +328 -0
  7. package/dockerfiles/AGENTS.md +92 -0
  8. package/dockerfiles/aider/Dockerfile +5 -0
  9. package/dockerfiles/amp/Dockerfile +10 -0
  10. package/dockerfiles/auggie/Dockerfile +12 -0
  11. package/dockerfiles/base/Dockerfile +73 -0
  12. package/dockerfiles/claude/Dockerfile +11 -0
  13. package/dockerfiles/codebuddy/Dockerfile +12 -0
  14. package/dockerfiles/codex/Dockerfile +9 -0
  15. package/dockerfiles/droid/Dockerfile +8 -0
  16. package/dockerfiles/gemini/Dockerfile +9 -0
  17. package/dockerfiles/jules/Dockerfile +12 -0
  18. package/dockerfiles/kilo/Dockerfile +25 -0
  19. package/dockerfiles/opencode/Dockerfile +10 -0
  20. package/dockerfiles/qoder/Dockerfile +12 -0
  21. package/dockerfiles/qwen/Dockerfile +10 -0
  22. package/dockerfiles/shai/Dockerfile +9 -0
  23. package/lib/AGENTS.md +58 -0
  24. package/lib/generate-ai-run.sh +19 -0
  25. package/lib/install-aider.sh +30 -0
  26. package/lib/install-amp.sh +39 -0
  27. package/lib/install-auggie.sh +36 -0
  28. package/lib/install-base.sh +139 -0
  29. package/lib/install-claude.sh +42 -0
  30. package/lib/install-codebuddy.sh +36 -0
  31. package/lib/install-codeserver.sh +171 -0
  32. package/lib/install-codex.sh +40 -0
  33. package/lib/install-droid.sh +27 -0
  34. package/lib/install-gemini.sh +39 -0
  35. package/lib/install-jules.sh +36 -0
  36. package/lib/install-kilo.sh +57 -0
  37. package/lib/install-opencode.sh +39 -0
  38. package/lib/install-qoder.sh +37 -0
  39. package/lib/install-qwen.sh +40 -0
  40. package/lib/install-shai.sh +33 -0
  41. package/lib/install-tool.sh +40 -0
  42. package/lib/install-vscode.sh +219 -0
  43. package/lib/ssh-key-selector.sh +189 -0
  44. package/package.json +46 -0
  45. package/setup.sh +530 -0
@@ -0,0 +1,25 @@
1
+ FROM node:22-slim
2
+
3
+ # Install dependencies
4
+ RUN apt-get update && apt-get install -y --no-install-recommends \
5
+ git \
6
+ curl \
7
+ ssh \
8
+ ca-certificates \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Install Kilo Code CLI as root
12
+ RUN npm install -g @kilocode/cli
13
+
14
+ # Create workspace
15
+ WORKDIR /workspace
16
+
17
+ # Create worker user
18
+ RUN useradd -m -u 1001 -d /home/agent agent && \
19
+ chown -R agent:agent /workspace
20
+
21
+ USER agent
22
+ ENV HOME=/home/agent
23
+
24
+ # Kilo uses 'kilocode' as entrypoint
25
+ ENTRYPOINT ["kilocode"]
@@ -0,0 +1,10 @@
1
+ FROM ai-base:latest
2
+
3
+ USER root
4
+ # Install OpenCode using official native installer
5
+ RUN curl -fsSL https://opencode.ai/install | bash && \
6
+ mv /home/agent/.opencode/bin/opencode /usr/local/bin/opencode && \
7
+ rm -rf /home/agent/.opencode
8
+
9
+ USER agent
10
+ ENTRYPOINT ["opencode"]
@@ -0,0 +1,12 @@
1
+ FROM ai-base:latest
2
+ USER root
3
+
4
+ # Install Qoder CLI to a non-shadowed path
5
+ RUN mkdir -p /usr/local/lib/qoder && \
6
+ cd /usr/local/lib/qoder && \
7
+ bun init -y && \
8
+ bun add @qoder-ai/qodercli && \
9
+ ln -s /usr/local/lib/qoder/node_modules/.bin/qodercli /usr/local/bin/qoder
10
+
11
+ USER agent
12
+ ENTRYPOINT ["qoder"]
@@ -0,0 +1,10 @@
1
+ FROM ai-base:latest
2
+ USER root
3
+ # Install qwen-code in a dedicated directory and symlink to /usr/local/bin
4
+ RUN mkdir -p /usr/local/lib/qwen && \
5
+ cd /usr/local/lib/qwen && \
6
+ bun init -y && \
7
+ bun add @qwen-code/qwen-code@latest tiktoken && \
8
+ ln -s /usr/local/lib/qwen/node_modules/.bin/qwen /usr/local/bin/qwen
9
+ USER agent
10
+ ENTRYPOINT ["qwen"]
@@ -0,0 +1,9 @@
1
+ FROM ai-base:latest
2
+ USER root
3
+
4
+ # Install SHAI native binary and relocate to /usr/local/bin
5
+ RUN curl -fsSL https://raw.githubusercontent.com/ovh/shai/main/install.sh | bash && \
6
+ mv /home/agent/.local/bin/shai /usr/local/bin/shai
7
+
8
+ USER agent
9
+ ENTRYPOINT ["shai"]
package/lib/AGENTS.md ADDED
@@ -0,0 +1,58 @@
1
+ # Lib/ - Tool Installation Scripts
2
+
3
+ **Purpose:** Installation and configuration scripts for 15+ AI coding tools
4
+
5
+ ## Overview
6
+
7
+ Bash scripts that install and configure each supported AI tool inside Docker containers. Each script handles tool-specific setup, environment variables, and Docker image requirements.
8
+
9
+ ## Structure
10
+
11
+ ```
12
+ lib/
13
+ โ”œโ”€โ”€ install-base.sh # Bun runtime base image
14
+ โ”œโ”€โ”€ install-{tool}.sh # 14 tool-specific installers
15
+ โ”œโ”€โ”€ generate-ai-run.sh # Generates ai-run wrapper script
16
+ โ”œโ”€โ”€ install-tool.sh # Template for new tools
17
+ โ”œโ”€โ”€ ssh-key-selector.sh # Interactive SSH key chooser
18
+ โ”œโ”€โ”€ install-codeserver.sh # VSCode Server setup
19
+ โ””โ”€โ”€ install-vscode.sh # Desktop VSCode (X11)
20
+ ```
21
+
22
+ ## Where to Look
23
+
24
+ | Task | Script | Notes |
25
+ |------|--------|-------|
26
+ | Add new tool | `install-tool.sh` | Copy template, customize |
27
+ | Modify tool install | `install-{tool}.sh` | Update Docker image, env vars |
28
+ | SSH handling | `ssh-key-selector.sh` | User prompts for key selection |
29
+ | Wrapper generation | `generate-ai-run.sh` | Creates bin/ai-run |
30
+
31
+ ## Tool Inventory
32
+
33
+ | Tool | Script | Type |
34
+ |------|--------|------|
35
+ | Claude | `install-claude.sh` | CLI binary |
36
+ | Gemini | `install-gemini.sh` | npm/Bun |
37
+ | Aider | `install-aider.sh` | Python |
38
+ | Opencode | `install-opencode.sh` | Go binary |
39
+ | Kilo | `install-kilo.sh` | npm/Bun |
40
+ | Codex | `install-codex.sh` | npm/Bun |
41
+ | Amp | `install-amp.sh` | npm/Bun |
42
+ | Qwen | `install-qwen.sh` | npm/Bun |
43
+ | Droid | `install-droid.sh` | Custom |
44
+ | Jules | `install-jules.sh` | npm/Bun |
45
+ | Qoder | `install-qoder.sh` | npm/Bun |
46
+ | Auggie | `install-auggie.sh` | npm/Bun |
47
+ | CodeBuddy | `install-codebuddy.sh` | npm/Bun |
48
+ | SHAI | `install-shai.sh` | npm/Bun |
49
+ | CodeServer | `install-codeserver.sh` | VSCode browser |
50
+ | VSCode | `install-vscode.sh` | Desktop X11 |
51
+
52
+ ## Conventions
53
+
54
+ - Scripts use `set -e` for fail-fast
55
+ - Environment variables use `AI_` prefix
56
+ - Tool configs mounted to `/home/agent/` in container
57
+ - API keys read from `~/.ai-env`
58
+ - Docker images named `ai-{tool}:latest`
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Get the project root directory
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+ PROJECT_BIN="$PROJECT_ROOT/bin"
8
+
9
+ # The ai-run script already exists in bin/ai-run (version controlled)
10
+ # We just need to ensure it's executable and symlinked
11
+
12
+ chmod +x "$PROJECT_BIN/ai-run"
13
+
14
+ # Create symlink in user's bin directory
15
+ mkdir -p "$HOME/bin"
16
+ ln -sf "$PROJECT_BIN/ai-run" "$HOME/bin/ai-run"
17
+
18
+ echo "โœ… ai-run script at $PROJECT_BIN/ai-run"
19
+ echo "โœ… Symlinked to $HOME/bin/ai-run"
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Aider installer: Python-based AI coding assistant
5
+ TOOL="aider"
6
+
7
+ echo "Installing $TOOL (Python-based AI pair programmer)..."
8
+
9
+ # Create directories
10
+ mkdir -p "dockerfiles/$TOOL"
11
+ mkdir -p "$HOME/.ai-cache/$TOOL"
12
+ mkdir -p "$HOME/.ai-home/$TOOL"
13
+
14
+ # Create Dockerfile (extends base image which has Python)
15
+ cat <<'EOF' > "dockerfiles/$TOOL/Dockerfile"
16
+ FROM ai-base:latest
17
+ USER agent
18
+ # Install aider via aider-install
19
+ RUN python3 -m pip install --break-system-packages aider-install && aider-install
20
+ ENTRYPOINT ["aider"]
21
+ EOF
22
+
23
+ # Build image
24
+ echo "Building Docker image for $TOOL..."
25
+ docker build -t "ai-$TOOL:latest" "dockerfiles/$TOOL"
26
+
27
+ echo "โœ… $TOOL installed"
28
+ echo ""
29
+ echo "Usage: ai-run aider [options]"
30
+ echo "Example: ai-run aider --model gpt-4"
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Amp installer: Sourcegraph's AI coding assistant
5
+ TOOL="amp"
6
+
7
+ echo "Installing $TOOL (Sourcegraph Amp)..."
8
+
9
+ # Create directories
10
+ mkdir -p "dockerfiles/$TOOL"
11
+ mkdir -p "$HOME/.ai-cache/$TOOL"
12
+ mkdir -p "$HOME/.ai-home/$TOOL"
13
+
14
+ # Create Dockerfile (extends base image for faster builds)
15
+ cat <<'EOF' > "dockerfiles/$TOOL/Dockerfile"
16
+ FROM ai-base:latest
17
+ USER root
18
+ # Install Amp globally into a persistent directory (not shadowed by home)
19
+ RUN mkdir -p /usr/local/lib/amp && \
20
+ cd /usr/local/lib/amp && \
21
+ bun init -y && \
22
+ bun add @sourcegraph/amp && \
23
+ ln -s /usr/local/lib/amp/node_modules/.bin/amp /usr/local/bin/amp
24
+ USER agent
25
+ ENTRYPOINT ["amp"]
26
+ EOF
27
+
28
+ # Build image
29
+ echo "Building Docker image for $TOOL..."
30
+ docker build -t "ai-$TOOL:latest" "dockerfiles/$TOOL"
31
+
32
+ echo "โœ… $TOOL installed"
33
+ echo ""
34
+ echo "Features:"
35
+ echo " โœ“ Sourcegraph AI coding assistant"
36
+ echo " โœ“ Code understanding and generation"
37
+ echo " โœ“ Multi-file editing"
38
+ echo ""
39
+ echo "Usage: ai-run amp"
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Auggie CLI installer: Augment Code's AI assistant
5
+ TOOL="auggie"
6
+
7
+ echo "Installing $TOOL (Augment Auggie CLI)..."
8
+
9
+ # Create directories
10
+ mkdir -p "dockerfiles/$TOOL"
11
+ mkdir -p "$HOME/.ai-cache/$TOOL"
12
+ mkdir -p "$HOME/.ai-home/$TOOL"
13
+
14
+ # Create Dockerfile
15
+ cat <<'EOF' > "dockerfiles/$TOOL/Dockerfile"
16
+ FROM ai-base:latest
17
+ USER root
18
+
19
+ # Install Auggie CLI to a non-shadowed path
20
+ RUN mkdir -p /usr/local/lib/auggie && \
21
+ cd /usr/local/lib/auggie && \
22
+ bun init -y && \
23
+ bun add @augmentcode/auggie && \
24
+ ln -s /usr/local/lib/auggie/node_modules/.bin/auggie /usr/local/bin/auggie
25
+
26
+ USER agent
27
+ ENTRYPOINT ["auggie"]
28
+ EOF
29
+
30
+ # Build image
31
+ echo "Building Docker image for $TOOL..."
32
+ docker build -t "ai-$TOOL:latest" "dockerfiles/$TOOL"
33
+
34
+ echo "โœ… $TOOL installed"
35
+ echo ""
36
+ echo "Usage: ai-run auggie"
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Build base Docker image with Bun runtime (2x faster than Node.js)
5
+ mkdir -p "dockerfiles/base"
6
+
7
+ ADDITIONAL_TOOLS_INSTALL=""
8
+
9
+ if [[ "${INSTALL_SPEC_KIT:-0}" -eq 1 ]]; then
10
+ echo "๐Ÿ“ฆ spec-kit will be installed in base image"
11
+ ADDITIONAL_TOOLS_INSTALL+='RUN pipx install specify-cli --pip-args="git+https://github.com/github/spec-kit.git"
12
+ '
13
+ fi
14
+
15
+ if [[ "${INSTALL_UX_UI_PROMAX:-0}" -eq 1 ]]; then
16
+ echo "๐Ÿ“ฆ ux-ui-promax will be installed in base image"
17
+ ADDITIONAL_TOOLS_INSTALL+='RUN bun install -g uipro-cli
18
+ '
19
+ fi
20
+
21
+ if [[ "${INSTALL_OPENSPEC:-0}" -eq 1 ]]; then
22
+ echo "๐Ÿ“ฆ OpenSpec will be installed in base image"
23
+ ADDITIONAL_TOOLS_INSTALL+='RUN mkdir -p /usr/local/lib/openspec && \
24
+ cd /usr/local/lib/openspec && \
25
+ bun init -y && \
26
+ bun add @fission-ai/openspec && \
27
+ ln -sf /usr/local/lib/openspec/node_modules/.bin/openspec /usr/local/bin/openspec
28
+ '
29
+ fi
30
+
31
+ if [[ "${INSTALL_PLAYWRIGHT:-0}" -eq 1 ]]; then
32
+ echo "๐Ÿ“ฆ Playwright will be installed in base image"
33
+ ADDITIONAL_TOOLS_INSTALL+='# Install Playwright system dependencies
34
+ RUN apt-get update && apt-get install -y --no-install-recommends \
35
+ libglib2.0-0 \
36
+ libnspr4 \
37
+ libnss3 \
38
+ libdbus-1-3 \
39
+ libatk1.0-0 \
40
+ libatk-bridge2.0-0 \
41
+ libcups2 \
42
+ libxcb1 \
43
+ libxkbcommon0 \
44
+ libatspi2.0-0 \
45
+ libx11-6 \
46
+ libxcomposite1 \
47
+ libxdamage1 \
48
+ libxext6 \
49
+ libxfixes3 \
50
+ libxrandr2 \
51
+ libgbm1 \
52
+ libcairo2 \
53
+ libpango-1.0-0 \
54
+ libasound2 \
55
+ && rm -rf /var/lib/apt/lists/*
56
+ # Install Playwright and browsers via npm (avoids pnpm global bin issues)
57
+ RUN npm install -g playwright && npx playwright install
58
+ '
59
+ fi
60
+
61
+ if [[ "${INSTALL_RUBY:-0}" -eq 1 ]]; then
62
+ echo "๐Ÿ“ฆ Ruby 3.3.0 + Rails 8.0.2 will be installed in base image"
63
+ ADDITIONAL_TOOLS_INSTALL+='# Install Ruby build dependencies
64
+ RUN apt-get update && apt-get install -y --no-install-recommends \
65
+ libssl-dev \
66
+ libreadline-dev \
67
+ zlib1g-dev \
68
+ libyaml-dev \
69
+ libffi-dev \
70
+ libgdbm-dev \
71
+ libncurses5-dev \
72
+ && rm -rf /var/lib/apt/lists/*
73
+
74
+ # Install rbenv and ruby-build
75
+ RUN git clone https://github.com/rbenv/rbenv.git /usr/local/rbenv && \
76
+ git clone https://github.com/rbenv/ruby-build.git /usr/local/rbenv/plugins/ruby-build
77
+
78
+ ENV RBENV_ROOT=/usr/local/rbenv
79
+ ENV PATH=$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH
80
+
81
+ # Install Ruby 3.3.0
82
+ RUN rbenv install 3.3.0 && rbenv global 3.3.0 && rbenv rehash
83
+
84
+ # Install Rails 8.0.2 and Bundler
85
+ RUN gem install rails -v 8.0.2 && gem install bundler && rbenv rehash
86
+ '
87
+ fi
88
+
89
+ cat > "dockerfiles/base/Dockerfile" <<EOF
90
+ FROM oven/bun:latest
91
+
92
+ # Install common dependencies (Bun + Node.js + Python for full package manager support)
93
+ RUN apt-get update && apt-get install -y --no-install-recommends \\
94
+ git \\
95
+ curl \\
96
+ ssh \\
97
+ ca-certificates \\
98
+ python3 \\
99
+ python3-pip \\
100
+ python3-venv \\
101
+ python3-dev \\
102
+ python3-setuptools \\
103
+ build-essential \\
104
+ libopenblas-dev \\
105
+ pipx \\
106
+ && curl -LsSf https://astral.sh/uv/install.sh | UV_INSTALL_DIR=/usr/local/bin sh \\
107
+ && rm -rf /var/lib/apt/lists/* \\
108
+ && pipx ensurepath
109
+
110
+ # Install Node.js LTS (includes npm) via NodeSource
111
+ RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \\
112
+ && apt-get install -y nodejs \\
113
+ && rm -rf /var/lib/apt/lists/*
114
+
115
+ # Install pnpm globally via npm
116
+ RUN npm install -g pnpm
117
+
118
+ # Install TypeScript and LSP tools for AI coding assistants
119
+ RUN npm install -g typescript typescript-language-server
120
+
121
+ # Verify installations
122
+ RUN node --version && npm --version && pnpm --version && bun --version && tsc --version
123
+
124
+ # Install additional tools (if selected)
125
+ ${ADDITIONAL_TOOLS_INSTALL}
126
+ # Create workspace
127
+ WORKDIR /workspace
128
+
129
+ # Non-root user for security
130
+ RUN useradd -m -u 1001 -d /home/agent agent && \\
131
+ chown -R agent:agent /workspace
132
+ USER agent
133
+ ENV HOME=/home/agent
134
+ EOF
135
+
136
+ echo "Building base Docker image with Bun runtime..."
137
+ docker build -t "ai-base:latest" "dockerfiles/base"
138
+ echo "โœ… Base image built (ai-base:latest)"
139
+
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Claude Code installer: Anthropic's AI coding agent (Native Binary)
5
+ TOOL="claude"
6
+
7
+ echo "Installing $TOOL (Anthropic Claude Code - Native Binary)..."
8
+
9
+ # Create directories
10
+ mkdir -p "dockerfiles/$TOOL"
11
+ mkdir -p "$HOME/.ai-cache/$TOOL"
12
+ mkdir -p "$HOME/.ai-home/$TOOL"
13
+
14
+ # Create Dockerfile using official native installer (no npm needed)
15
+ cat <<'EOF' > "dockerfiles/$TOOL/Dockerfile"
16
+ FROM ai-base:latest
17
+
18
+ USER root
19
+ # Install Claude Code using official native installer
20
+ RUN curl -fsSL https://claude.ai/install.sh | bash && \
21
+ mkdir -p /usr/local/share && \
22
+ mv /home/agent/.local/share/claude /usr/local/share/claude && \
23
+ ln -sf /usr/local/share/claude/versions/$(ls /usr/local/share/claude/versions | head -1) /usr/local/bin/claude
24
+
25
+ USER agent
26
+ ENTRYPOINT ["claude"]
27
+ EOF
28
+
29
+ # Build image
30
+ echo "Building Docker image for $TOOL (native binary)..."
31
+ docker build -t "ai-$TOOL:latest" "dockerfiles/$TOOL"
32
+
33
+ echo "โœ… $TOOL installed (Native Binary)"
34
+ echo ""
35
+ echo "Features:"
36
+ echo " โœ“ Official native binary (no Node.js)"
37
+ echo " โœ“ Claude 3.5 Sonnet/Opus models"
38
+ echo " โœ“ Agentic coding with file editing"
39
+ echo " โœ“ Web search and fetch built-in"
40
+ echo ""
41
+ echo "Usage: ai-run claude"
42
+ echo "Auth: Set ANTHROPIC_API_KEY environment variable"
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # CodeBuddy CLI installer: Tencent's AI assistant
5
+ TOOL="codebuddy"
6
+
7
+ echo "Installing $TOOL (Tencent CodeBuddy CLI)..."
8
+
9
+ # Create directories
10
+ mkdir -p "dockerfiles/$TOOL"
11
+ mkdir -p "$HOME/.ai-cache/$TOOL"
12
+ mkdir -p "$HOME/.ai-home/$TOOL"
13
+
14
+ # Create Dockerfile
15
+ cat <<'EOF' > "dockerfiles/$TOOL/Dockerfile"
16
+ FROM ai-base:latest
17
+ USER root
18
+
19
+ # Install CodeBuddy CLI to a non-shadowed path
20
+ RUN mkdir -p /usr/local/lib/codebuddy && \
21
+ cd /usr/local/lib/codebuddy && \
22
+ bun init -y && \
23
+ bun add @tencent-ai/codebuddy-code && \
24
+ ln -s /usr/local/lib/codebuddy/node_modules/.bin/codebuddy /usr/local/bin/codebuddy
25
+
26
+ USER agent
27
+ ENTRYPOINT ["codebuddy"]
28
+ EOF
29
+
30
+ # Build image
31
+ echo "Building Docker image for $TOOL..."
32
+ docker build -t "ai-$TOOL:latest" "dockerfiles/$TOOL"
33
+
34
+ echo "โœ… $TOOL installed"
35
+ echo ""
36
+ echo "Usage: ai-run codebuddy"
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Code-server installer: Browser-based VSCode (fast, no X11 needed)
5
+ TOOL="codeserver"
6
+ CODESERVER_PORT="${CODESERVER_PORT:-8080}"
7
+
8
+ echo "Installing $TOOL (code-server - browser-based VSCode)..."
9
+
10
+ # Create directories
11
+ mkdir -p "dockerfiles/$TOOL"
12
+ mkdir -p "$HOME/.ai-cache/$TOOL"
13
+ mkdir -p "$HOME/.ai-home/$TOOL"
14
+
15
+ WORKSPACES_FILE="$HOME/.ai-workspaces"
16
+
17
+ # Create Dockerfile for code-server
18
+ cat <<'EOF' > "dockerfiles/$TOOL/Dockerfile"
19
+ FROM ubuntu:22.04
20
+
21
+ ENV DEBIAN_FRONTEND=noninteractive
22
+
23
+ # Install code-server dependencies
24
+ RUN apt-get update && apt-get install -y --no-install-recommends \
25
+ wget \
26
+ ca-certificates \
27
+ curl \
28
+ git \
29
+ && rm -rf /var/lib/apt/lists/*
30
+
31
+ # Download and install code-server (latest stable)
32
+ RUN ARCH=$(dpkg --print-architecture) && \
33
+ if [ "$ARCH" = "amd64" ]; then CS_ARCH="amd64"; elif [ "$ARCH" = "arm64" ]; then CS_ARCH="arm64"; else CS_ARCH="amd64"; fi && \
34
+ echo "Downloading code-server for ${CS_ARCH}..." && \
35
+ curl -fsSL https://code-server.dev/install.sh | sh && \
36
+ echo "code-server installed successfully"
37
+
38
+ # Create directories
39
+ RUN mkdir -p /workspace /tmp /home/coder/.config/code-server /home/coder/.local/share/code-server
40
+ WORKDIR /workspace
41
+
42
+ # Non-root user (use UID 1001 to avoid conflicts)
43
+ RUN useradd -m -u 1001 -d /home/coder coder && \
44
+ chown -R coder:coder /workspace /tmp /home/coder
45
+
46
+ USER coder
47
+
48
+ # Set home directory
49
+ ENV HOME=/home/coder
50
+
51
+ # Expose port
52
+ EXPOSE 8080
53
+
54
+ # Start code-server (no auth for local use, bind to all interfaces)
55
+ ENTRYPOINT ["code-server", "--bind-addr", "0.0.0.0:8080", "--auth", "none", "--disable-telemetry"]
56
+ CMD ["/workspace"]
57
+ EOF
58
+
59
+ # Build image
60
+ echo "Building Docker image for $TOOL..."
61
+ docker build -t "ai-$TOOL:latest" "dockerfiles/$TOOL"
62
+
63
+ # Create wrapper script
64
+ cat <<'EOF' > "$HOME/bin/codeserver-run"
65
+ #!/usr/bin/env bash
66
+ # Code-server launcher - opens VSCode in browser
67
+
68
+ set -e
69
+
70
+ WORKSPACES_FILE="$HOME/.ai-workspaces"
71
+ CONTAINER_NAME="ai-codeserver-sandbox-$$"
72
+ CODESERVER_PORT="${CODESERVER_PORT:-8080}"
73
+
74
+ if [ ! -f "$WORKSPACES_FILE" ]; then
75
+ echo "Error: No workspaces configured. Run setup.sh first." >&2
76
+ exit 1
77
+ fi
78
+
79
+ # Build volume mounts from whitelisted workspaces
80
+ VOLUME_MOUNTS=""
81
+ WS_INDEX=0
82
+ while IFS= read -r ws; do
83
+ if [ -n "$ws" ] && [ -d "$ws" ]; then
84
+ VOLUME_MOUNTS="$VOLUME_MOUNTS -v $ws:/workspace/workspace-$WS_INDEX"
85
+ WS_INDEX=$((WS_INDEX + 1))
86
+ fi
87
+ done < "$WORKSPACES_FILE"
88
+
89
+ if [ $WS_INDEX -eq 0 ]; then
90
+ echo "Error: No valid workspaces found in $WORKSPACES_FILE" >&2
91
+ exit 1
92
+ fi
93
+
94
+ echo "๐Ÿ”’ Starting code-server (browser-based VSCode sandbox)..."
95
+ echo ""
96
+ echo "Mounted workspaces:"
97
+ WS_INDEX=0
98
+ while IFS= read -r ws; do
99
+ if [ -n "$ws" ] && [ -d "$ws" ]; then
100
+ echo " โœ“ $ws โ†’ /workspace/workspace-$WS_INDEX"
101
+ WS_INDEX=$((WS_INDEX + 1))
102
+ fi
103
+ done < "$WORKSPACES_FILE"
104
+ echo ""
105
+
106
+ # Open browser after a short delay
107
+ (sleep 2 && open "http://localhost:$CODESERVER_PORT" 2>/dev/null || xdg-open "http://localhost:$CODESERVER_PORT" 2>/dev/null || echo "Open http://localhost:$CODESERVER_PORT in your browser") &
108
+
109
+ echo "๐Ÿš€ Starting code-server at http://localhost:$CODESERVER_PORT"
110
+ echo " Press Ctrl+C to stop"
111
+ echo ""
112
+
113
+ # STRICT SANDBOX SECURITY:
114
+ # - No host environment variables
115
+ # - No access to host files outside volumes
116
+ # - Non-root user
117
+ # - Only localhost can access the server
118
+
119
+ docker run \
120
+ --rm \
121
+ --name "$CONTAINER_NAME" \
122
+ $VOLUME_MOUNTS \
123
+ --tmpfs /tmp:exec \
124
+ --tmpfs /run \
125
+ --tmpfs /home/coder/.config:uid=1001,gid=1001 \
126
+ --tmpfs /home/coder/.local:uid=1001,gid=1001 \
127
+ -p 127.0.0.1:$CODESERVER_PORT:8080 \
128
+ -e HOME=/home/coder \
129
+ -e PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
130
+ -u 1001:1001 \
131
+ -w /workspace \
132
+ "ai-codeserver:latest"
133
+
134
+ echo ""
135
+ echo "โœ… code-server stopped"
136
+ echo "๐Ÿงน Sandbox cleaned up"
137
+ EOF
138
+
139
+ chmod +x "$HOME/bin/codeserver-run"
140
+
141
+ echo "โœ… $TOOL installed (code-server - browser-based)"
142
+ echo ""
143
+ echo "Created files:"
144
+ echo " - Docker image: ai-$TOOL:latest"
145
+ echo " - Wrapper script: $HOME/bin/codeserver-run"
146
+ echo ""
147
+ echo "Features:"
148
+ echo " โœ“ Runs in your native browser (fast, crisp)"
149
+ echo " โœ“ No X11/XQuartz required"
150
+ echo " โœ“ Same sandboxed environment"
151
+ echo " โœ“ HiDPI/Retina support"
152
+ echo ""
153
+ echo "Security Features:"
154
+ echo " โœ“ Only accessible from localhost"
155
+ echo " โœ“ No host environment variables visible"
156
+ echo " โœ“ No access to host filesystem outside volumes"
157
+ echo " โœ“ Runs as non-root user"
158
+ echo " โœ“ Terminal in VSCode is sandboxed"
159
+ echo ""
160
+ echo "Usage:"
161
+ echo " codeserver-run"
162
+ echo " # Opens VSCode in browser at http://localhost:$CODESERVER_PORT"
163
+ echo ""
164
+ echo "Whitelisted Workspaces:"
165
+ if [ -f "$WORKSPACES_FILE" ]; then
166
+ while IFS= read -r ws; do
167
+ if [ -n "$ws" ] && [ -d "$ws" ]; then
168
+ echo " - $ws"
169
+ fi
170
+ done < "$WORKSPACES_FILE"
171
+ fi