@isupervillain/opencode-container-exec
v1.1.0
Published
OpenCode plugin for WSL devcontainer integration - run commands inside devcontainers from WSL
Downloads
352
Maintainers
Readme
opencode-container-exec
OpenCode plugin for WSL devcontainer integration - run commands inside devcontainers from WSL.
Why?
When using VSCode Dev Containers from WSL, you need to reinstall OpenCode in every new container. This plugin lets you run OpenCode from WSL and route commands to the container automatically.
Features
- Auto-detect running devcontainers via
devcontainer.local_folderlabel - Container selection by number, ID, or name when multiple containers running
- Visual indicator
[🐳 container-name]prefix in bash output - WSL path conversion automatically converts Linux paths to Windows format
- Direct execution use
!prefix for instant execution without LLM - Security hardened with input validation and command injection prevention
- Container health checks ensures containers are running before command execution
- Dependency checking validates required CLIs are installed
Prerequisites
System Requirements
- Operating System: Windows 10/11 with WSL (Windows Subsystem for Linux)
- WSL Distribution: Ubuntu (default) or other distributions (configurable)
- Docker: Docker Desktop with WSL 2 backend
- Node.js: Version 18.0.0 or higher
Required Software
- WSL 2: Installation guide
- Docker Desktop: Download
- Enable WSL 2 integration in Docker Desktop settings
- devcontainer CLI: Install globally
npm install -g @devcontainers/cli - jq (required for
scripts/toggle.sh)sudo apt-get update && sudo apt-get install -y jq - OpenCode CLI: Install from opencode.ai
Verification
Verify your setup:
# Check WSL
wsl --list --verbose
# Check Docker
docker --version
docker ps
# Check devcontainer CLI
devcontainer --version
# Check Node.js
node --versionInstallation
From npm (recommended)
The plugin intelligently installs commands to the appropriate location based on how it's installed:
Global Installation (recommended for system-wide use)
npm install -g @isupervillain/opencode-container-execInstalls commands to: ~/.config/opencode/commands/container.md
Local/Project Installation (recommended for project-specific use)
npm install @isupervillain/opencode-container-execInstalls commands to: ./commands/container.md (relative to project root)
Add to your ~/.config/opencode/opencode.json or project opencode.json:
{
"plugin": ["@isupervillain/opencode-container-exec"]
}Manual installation
- Clone this repository
- Copy the
plugindirectory to~/.config/opencode/plugins/or.opencode/plugins/ - Copy
scripts/toggle.shto a location in your PATH
Note: The /container slash command is automatically installed when the plugin loads. The installation location depends on how the plugin was installed:
- Global npm install:
~/.config/opencode/commands/container.md - Local npm install:
./commands/container.md(project-relative) - Manual copy: Choose either location based on your preference
If you don't see /container immediately, restart OpenCode once so the command file can be discovered.
If auto-install fails in your environment, you can manually copy plugin/command/container.md to:
~/.config/opencode/commands/container.md(for global availability)./commands/container.md(for project-specific use)
Plugin runtime entrypoint contract
For OpenCode runtime loading, keep plugin/index.js limited to plugin export(s) only (for this project: ContainerExecPlugin and default export).
Move helper/utility exports to plugin/internal.js.
Usage
Direct execution (instant, no LLM)
# Enable container mode (auto-detect)
!path/to/scripts/toggle.sh on
# Disable container mode
!path/to/scripts/toggle.sh off
# Show current status
!path/to/scripts/toggle.sh status
# List all running devcontainers
!path/to/scripts/toggle.sh list
# Select container by number
!path/to/scripts/toggle.sh on 1
# Select container by ID
!path/to/scripts/toggle.sh on fa6c0c798c6c
# Select container by name
!path/to/scripts/toggle.sh on flamboyant_robinsonVia slash command (LLM processed)
/container on
/container off
/container status
/container list
/container on 1Visual indicator
When container mode is ON, bash commands show:
[🐳 flamboyant_robinson] /home/vscode
[🐳 flamboyant_robinson] Python 3.12.11When container mode is OFF:
/home/your-user/projects/your-repo
Python 3.12.11API Reference
Tools
bash
Execute shell commands. Routes to devcontainer when container mode is enabled.
Description:
- When container mode is ON:
Execute shell commands in devcontainer [🐳 container-name] - When container mode is OFF:
Execute shell commands locally on WSL
Arguments:
command(string, required): Shell command to executetimeout(number, optional): Timeout in milliseconds
Returns: Command output with container indicator prefix when applicable.
container
Toggle devcontainer mode on/off for running commands inside a container.
Description: Toggle devcontainer mode on/off for running commands inside a container
Arguments:
action(enum, required): Action to performon: Enable container modeoff: Disable container modestatus: Show current statuslist: List all running devcontainers
selection(string, optional): Container selection (number, ID, or name)
Returns: Status message and container information.
Shell Script API
The toggle.sh script provides the same functionality via command line:
toggle.sh [action] [container]Actions:
on [container]: Enable container mode (auto-detect or specify container)off: Disable container modestatus: Show current state and available containerslist: List all running devcontainers
Container Selection:
- Number: Select by position in list (e.g.,
1) - Container ID: Select by Docker container ID (e.g.,
fa6c0c798c6c) - Container name: Select by Docker container name (e.g.,
flamboyant_robinson)
How it works
- The plugin detects running devcontainers by checking the
devcontainer.local_folderDocker label - It converts WSL paths to Windows format (prefers
wslpath -w, falls back to\\wsl.localhost\<distro>\...) - When enabled, bash commands are routed through
devcontainer exec --container-id - State is persisted in
~/.config/opencode/container-mode.json
Configuration
Environment Variables
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| WSL_DISTRO_NAME | WSL distribution name | Ubuntu | No |
| WSL_DISTRO | Alternate WSL distribution variable (fallback) | unset | No |
| HOME | User home directory | ~ | No |
| NODE_ENV | Node environment | production | No |
| OPENCODE_PLUGIN_GLOBAL_INSTALL | Force global installation behavior (for testing) | unset | No |
State File
The plugin stores state in ~/.config/opencode/container-mode.json:
{
"enabled": true,
"containerId": "fa6c0c798c6c",
"containerName": "flamboyant_robinson",
"containerImage": "mcr.microsoft.com/devcontainers/python:2-3.12-bullseye",
"directory": "/home/your-user/projects/your-repo"
}Security: State file is created with restrictive permissions (0o600).
Configuration Options
Currently, the plugin uses automatic configuration. Future versions will support:
- Timeout configuration
- Container selection preferences
- Path conversion options
- Security settings
Troubleshooting
Common Issues
1. No devcontainers found
Symptoms: "No running devcontainers found" error
Solutions:
- Ensure VSCode has opened a directory in a devcontainer
- Check if container is running:
docker ps - Verify container has
devcontainer.local_folderlabel:docker inspect --format '{{json .Config.Labels}}' <container_id> | grep devcontainer.local_folder
2. Commands not running in container
Symptoms: Commands execute locally instead of in container
Solutions:
- Check container mode status:
!path/to/scripts/toggle.sh status - Verify container is still running:
docker ps | grep <container_name> - Re-enable container mode:
!path/to/scripts/toggle.sh on
3. Path conversion issues
Symptoms: Container not found for current directory
Solutions:
- Check if using correct WSL distribution:
echo $WSL_DISTRO_NAME - Set distribution name if not Ubuntu (dot/hyphen names are supported, e.g.
Ubuntu-24.04):export WSL_DISTRO_NAME="Ubuntu-24.04" - Verify path conversion:
wslpath -w "$(pwd)"
4. Permission errors
Symptoms: "Permission denied" or state file errors
Solutions:
- Check state file permissions:
ls -la ~/.config/opencode/container-mode.json - Fix permissions if needed:
chmod 600 ~/.config/opencode/container-mode.json - Check config directory permissions:
ls -ld ~/.config/opencode chmod 700 ~/.config/opencode
5. Docker connection issues
Symptoms: "Cannot connect to Docker daemon" error
Solutions:
- Ensure Docker Desktop is running
- Check WSL integration in Docker Desktop settings
- Verify Docker socket permissions:
ls -la /var/run/docker.sock - Restart Docker Desktop
6. devcontainer CLI not found
Symptoms: "devcontainer: command not found" error
Solutions:
- Install devcontainer CLI:
npm install -g @devcontainers/cli - Verify installation:
devcontainer --version - Check PATH includes npm global bin:
echo $PATH | grep "$(npm config get prefix)/bin"
7. Plugin load crash: TypeError related to plugin.auth
Symptoms: OpenCode fails to load the plugin with a TypeError mentioning plugin.auth.
Cause: plugin/index.js exports non-plugin helper symbols, so runtime plugin detection receives unexpected exports.
Resolution:
- Ensure
plugin/index.jsexports only plugin function entrypoints. - Move helper utilities to
plugin/internal.js. - Upgrade to a release that includes this entrypoint/internal split.
Debug Mode
Enable debug logging for troubleshooting:
export NODE_ENV=developmentThis will output security events and debugging information to stderr.
Log Files
The plugin logs security events in development mode. For production issues:
- Check system logs:
journalctl -u docker - Check Docker logs:
docker logs <container_id> - Check OpenCode logs:
~/.config/opencode/logs/
Security
Security Features
- Input validation: All inputs validated against strict patterns
- Command injection prevention: Proper escaping of shell arguments
- Secure file permissions: State files created with 0o600 permissions
- Atomic file operations: Prevents state file corruption
- Container health checks: Verifies containers are running before execution
- Dependency validation: Checks required CLIs are installed
- Security logging: Logs suspicious activities in development mode
Security Best Practices
- Keep dependencies updated: Regularly update Docker, devcontainer CLI, and Node.js
- Use strong container names: Avoid special characters in container names
- Monitor logs: Check security logs for suspicious activities
- Validate inputs: Don't trust user inputs; validate all container selections
- Use restrictive permissions: Ensure config directory has 0o700 permissions
Reporting Vulnerabilities
If you discover a security vulnerability, please report it responsibly by opening a private GitHub Security Advisory.
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
# Clone repository
git clone https://github.com/isupervillain/opencode-container-exec.git
cd opencode-container-exec
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watchTesting
# Run all tests
npm test
# Run specific test file
node --test test/unit/state.test.js
# Run tests with watch mode
npm run test:watchChangelog
See CHANGELOG.md for version history.
License
MIT © isupervillain
Support
- Documentation: README.md
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security: Report via GitHub Security Advisory
