Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# GitHub Codespaces Configuration for Roo Code

This directory contains the configuration files needed to run Roo Code in GitHub Codespaces with full browser tool support.

## What's Included

### Chrome/Chromium Support

The configuration automatically installs Google Chrome and all necessary dependencies for Puppeteer to work correctly in the Codespace environment. This resolves the issue where the browser tool would fail with missing library errors like `libatk-1.0.so.0`.

### Files

- **`devcontainer.json`**: Main configuration file that defines the development container

- Uses Node.js 20 TypeScript image
- Installs essential VS Code extensions
- Configures environment variables for Puppeteer
- Sets up port forwarding for development servers

- **`post-create.sh`**: Script that runs after the container is created
- Installs Chrome browser and all required system libraries
- Configures Chrome for headless operation in containers
- Installs project dependencies
- Sets up the development environment

## How It Works

1. When you create a new Codespace, GitHub reads the `devcontainer.json` configuration
2. It creates a container based on the specified Node.js image
3. The `post-create.sh` script runs automatically to:
- Install Chrome and its dependencies
- Configure Chrome with appropriate flags for container environments
- Install pnpm and project dependencies
- Build the project

## Browser Tool Compatibility

The browser tool now works seamlessly in Codespaces by:

- Installing all required Chrome/Chromium dependencies
- Adding necessary sandbox flags (`--no-sandbox`, `--disable-setuid-sandbox`) for container environments
- Detecting when running in Codespaces via the `CODESPACES` environment variable
- Automatically applying the correct configuration

## Testing the Browser Tool

After creating a Codespace with this configuration, you can test the browser tool:

1. Open the Roo Code extension in the Codespace
2. Try a task that uses the browser tool, such as:
- "Open google.com and take a screenshot"
- "Navigate to a website and extract information"
- "Test a local development server"

## Troubleshooting

If you encounter issues:

1. **Chrome not found**: Run `.devcontainer/post-create.sh` manually
2. **Permission errors**: The script uses `sudo` where needed, but ensure you're running as the correct user
3. **Browser tool still failing**: Check that Chrome is installed: `google-chrome-stable --version`

## Environment Variables

The following environment variables are set for Puppeteer compatibility:

- `PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=false`: Ensures Puppeteer can download Chromium if needed
- `PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable`: Points to the installed Chrome binary

## Additional Notes

- The configuration includes common development tools (git, vim, jq, curl)
- VS Code extensions for TypeScript, ESLint, and Prettier are pre-installed
- The container runs with additional capabilities for debugging (`SYS_PTRACE`)
- Ports 3000 and 5173 are automatically forwarded for web development
64 changes: 64 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "Roo Code Development",
"image": "mcr.microsoft.com/devcontainers/typescript-node:20",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": true,
"configureZshAsDefaultShell": true,
"installOhMyZsh": true,
"upgradePackages": true,
"username": "automatic",
"userUid": "automatic",
"userGid": "automatic"
},
"ghcr.io/devcontainers/features/git:1": {
"version": "latest",
"ppa": false
},
"ghcr.io/devcontainers/features/github-cli:1": {
"installDirectlyFromGitHubRelease": true,
"version": "latest"
}
},
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vscode.vscode-typescript-next",
"vitest.explorer",
"zixuanchen.vitest-explorer"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.preferences.includePackageJsonAutoImports": "auto"
}
}
},
"postCreateCommand": "bash .devcontainer/post-create.sh",
"postStartCommand": "pnpm install",
"remoteUser": "node",
"mounts": [],
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
"containerEnv": {
"PUPPETEER_SKIP_CHROMIUM_DOWNLOAD": "false",
"PUPPETEER_EXECUTABLE_PATH": "/usr/bin/google-chrome-stable"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hardcoded path assumes Chrome will always be at this location. Could we make this more flexible or add a fallback? What if Chrome gets installed elsewhere or we use Chromium instead?

},
"portsAttributes": {
"3000": {
"label": "Web App",
"onAutoForward": "notify"
},
"5173": {
"label": "Vite Dev Server",
"onAutoForward": "notify"
}
},
"forwardPorts": [3000, 5173]
}
101 changes: 101 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/bash
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script needs executable permissions. Could we add a chmod +x in the devcontainer.json or ensure it's committed with executable permissions?


echo "🚀 Setting up Roo Code development environment..."

# Update package lists
echo "📦 Updating package lists..."
sudo apt-get update

# Install Chrome dependencies for Puppeteer
echo "🌐 Installing Chrome dependencies for Puppeteer..."
sudo apt-get install -y \
wget \
ca-certificates \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgbm1 \
libgcc1 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
lsb-release \
xdg-utils

# Install Google Chrome Stable
echo "🌐 Installing Google Chrome..."
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security concern: apt-key add is deprecated and insecure. Consider using the signed-by option instead:

Suggested change
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
wget -q -O /usr/share/keyrings/google-chrome.gpg https://dl-ssl.google.com/linux/linux_signing_key.pub
sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'

sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install -y google-chrome-stable
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling here. If Chrome installation fails, the script continues and reports success. Consider adding:

Suggested change
sudo apt-get install -y google-chrome-stable
sudo apt-get install -y google-chrome-stable || {
echo "❌ Failed to install Chrome. Browser tool may not work properly."
exit 1
}


# Install additional tools that might be useful
echo "🔧 Installing additional development tools..."
sudo apt-get install -y \
jq \
vim \
curl \
git-lfs

# Set up Chrome for headless operation in container
echo "⚙️ Configuring Chrome for container environment..."
# Add Chrome flags for running in container
sudo mkdir -p /etc/chromium.d/
echo 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox --disable-dev-shm-usage"' | sudo tee /etc/chromium.d/default-flags

# Install pnpm if not already installed
if ! command -v pnpm &> /dev/null; then
echo "📦 Installing pnpm..."
npm install -g pnpm
fi

# Install project dependencies
echo "📦 Installing project dependencies..."
pnpm install

# Build the project
echo "🔨 Building the project..."
pnpm build || true # Don't fail if build has issues initially

# Set up git (if in Codespace)
if [ -n "$CODESPACES" ]; then
echo "🔧 Configuring git for Codespace..."
git config --global --add safe.directory /workspaces/Roo-Code
fi

echo "✅ Development environment setup complete!"
echo ""
echo "🎉 Welcome to Roo Code development!"
echo ""
echo "Quick start commands:"
echo " pnpm install - Install dependencies"
echo " pnpm build - Build the project"
echo " pnpm test - Run tests"
echo " pnpm dev - Start development mode"
echo ""
echo "Chrome is installed at: $(which google-chrome-stable)"
echo "Chrome version: $(google-chrome-stable --version)"
23 changes: 20 additions & 3 deletions src/services/browser/BrowserSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,27 @@ export class BrowserSession {
private async launchLocalBrowser(): Promise<void> {
console.log("Launching local browser")
const stats = await this.ensureChromiumExists()

// Prepare browser launch arguments
const args = [
"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
]

// Add sandbox flags for container environments (Codespaces, Docker, etc.)
if (process.env.CODESPACES === "true" || process.env.CONTAINER === "true" || process.platform === "linux") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is checking for Linux platform alongside container env vars intentional? This would apply sandbox flags to ALL Linux systems, not just containers. Consider:

Suggested change
if (process.env.CODESPACES === "true" || process.env.CONTAINER === "true" || process.platform === "linux") {
if (process.env.CODESPACES === "true" || process.env.CONTAINER === "true" || (process.platform === "linux" && (process.env.container || process.env.KUBERNETES_SERVICE_HOST))) {

Or maybe we actually want this for all Linux systems?

args.push(
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage",
"--disable-gpu",
"--disable-web-security",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these flags like --disable-web-security and --disable-features=IsolateOrigins,site-per-process are quite permissive. Are we comfortable with the security implications for production use?

"--disable-features=IsolateOrigins,site-per-process",
)
console.log("Running in container/Linux environment, adding sandbox flags")
}

this.browser = await stats.puppeteer.launch({
args: [
"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
],
args,
executablePath: stats.executablePath,
defaultViewport: this.getViewport(),
// headless: false,
Expand Down
16 changes: 13 additions & 3 deletions src/services/browser/UrlContentFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,20 @@ export class UrlContentFetcher {
"--disable-gpu",
"--disable-features=VizDisplayCompositor",
]
if (process.platform === "linux") {
// Fixes network errors on Linux hosts (see https://github.com/puppeteer/puppeteer/issues/8246)
args.push("--no-sandbox")

// Add sandbox flags for container environments (Codespaces, Docker, Linux)
if (process.platform === "linux" || process.env.CODESPACES === "true" || process.env.CONTAINER === "true") {
// Fixes network errors on Linux hosts and container environments
// See https://github.com/puppeteer/puppeteer/issues/8246
args.push(
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-web-security",
"--disable-features=IsolateOrigins,site-per-process",
)
console.log("Running in container/Linux environment, adding sandbox flags for UrlContentFetcher")
}

this.browser = await stats.puppeteer.launch({
args,
executablePath: stats.executablePath,
Expand Down
3 changes: 3 additions & 0 deletions src/services/browser/__tests__/UrlContentFetcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ describe("UrlContentFetcher", () => {
"--disable-gpu",
"--disable-features=VizDisplayCompositor",
"--no-sandbox", // Linux-specific argument
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good that we're testing Linux-specific flags, but should we also add a test specifically for the CODESPACES environment variable detection?

"--disable-setuid-sandbox",
"--disable-web-security",
"--disable-features=IsolateOrigins,site-per-process",
],
executablePath: "/path/to/chromium",
})
Expand Down
Loading