# exe.dev Environment Guide for Agents This document describes the exe.dev VM environment for coding agents. Details of what's preinstalled and exeuntu-specific paths are a snapshot as of a particular time. They're meant to be helpful, but if you find they're outdated or wrong (you hit errors or just see something else on the system), of course believe what you find over what you read here. You could offer to update or delete sections in this file to make things easier in the future. Finally, remember you have sudo, apt, and Internet access; you aren't limited to preinstalled tools. ## What is exe.dev? A VM hosting service with persistent disks, HTTPS proxying, and quick setup. VMs share CPU/RAM from a user's allocation. The base image is called "exeuntu" (Ubuntu-based with dev tools pre-installed). **Documentation:** https://exe.dev/docs/all.md ## Network & HTTPS Proxy - You can find this VM's name with `hostname` - **Your public domain:** `https://.exe.xyz/` - Ports 3000-9999 are transparently proxied: `https://.exe.xyz:/` - Default proxy port is auto-detected, or the user (but not you) can set it via `ssh exe.dev share port ` from their own machine (with their ssh key) - By default, access requires exe.dev login. The user can make it public with `ssh exe.dev share set-public ` **Important:** When building web services, run them on localhost but give users URLs of the form `https://.exe.xyz:/` Port 8000 is a sensible default choice. ### Reverse Proxy Headers Requests include standard headers: - `X-Forwarded-Proto`: `https` or `http` - `X-Forwarded-Host`: Original host header - `X-Forwarded-For`: Client IP chain ## File Transfer ```bash scp .exe.xyz: scp .exe.xyz: . ``` ## Persistent Services with systemd To run a service that survives reboots: ```bash # Create a unit file, e.g., /etc/systemd/system/myapp.service sudo systemctl daemon-reload sudo systemctl enable myapp.service sudo systemctl start myapp # Management systemctl status myapp systemctl restart myapp journalctl -u myapp -f ``` Example unit file: ```ini [Unit] Description=My Application After=network.target [Service] Type=simple User=exedev WorkingDirectory=/home/exedev/myapp ExecStart=/home/exedev/myapp/server Restart=always [Install] WantedBy=multi-user.target ``` ## Project Templates Shelley (the default agent) has a Go web app template: ```bash mkdir -p /path/to/project && shelley unpack-template go /path/to/project ``` This provides: Go HTTP server, SQLite, migrations, systemd service config. Other agents can examine the output as a reference architecture. ## Guidance Files Agents should look for project-specific instructions in: - `dear_llm.md` - `agent.md` - `claude.md` - `AGENTS.md` Check the current directory and parent directories for these files before modifying code. ## VM Management (from outside) The user may run these commands from their development machine with their ssh key. You can't! ```bash ssh exe.dev new # Create new VM ssh exe.dev new --name=foo # With specific name ssh exe.dev new --image=ubuntu:22.04 # With specific image ssh exe.dev ls # List VMs ssh exe.dev rm # Delete VM ssh exe.dev share set-public # Make HTTP public ssh exe.dev share set-private # Restrict HTTP access ``` As you can see, ssh'ing to exe.dev fires up a custom REPL for managing exe.dev resources, not a Unix shell. ## Sudo Access `sudo` is available without password for the `exedev` user. --- # exeuntu Image: Pre-installed Software **Base OS:** Ubuntu 24.04.3 LTS (Noble Numbat) **Kernel:** 6.12.x **Default user:** `exedev` (has passwordless sudo) ## Languages & Runtimes | Tool | Version | Notes | |------|---------|-------| | Python | 3.12.3 | pip, pipx, venv available | | Go | 1.22.2 | | | Ruby | 3.2.3 | | | Perl | 5.38.2 | | | PHP | 8.3.6 | | | Java | OpenJDK 11.0.29 | | | Rust/Cargo | 1.75.0 | | | Lua | 5.3.6 | | | Elixir | 1.14.0 | with Erlang/OTP 24 | **Not pre-installed:** Node.js, Deno, Bun, .NET ### Installing Node.js Using snap will *not* necessarily work, and apt installs an older version of Node. Use nvm instead: ```bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash source ~/.bashrc nvm install 24 nvm alias default 24 ``` This gives you Node 24 + npm, enabling tools like Google's Gemini CLI: ```bash npx https://github.com/google-gemini/gemini-cli ``` ### Python Package Managers - `pip3` 24.0 - `pipx` 1.4.3 - `uv` - not pre-installed but easy: `curl -LsSf https://astral.sh/uv/install.sh | sh` ## Build Tools | Tool | Version | |------|---------| | GCC | 13.3.0 | | G++ | 13.3.0 | | Make | 4.3 | | CMake | 3.28.3 | ## Containers | Tool | Version | |------|---------| | Docker | 28.2.2 | | docker-compose | 1.29.2 | | Podman | 4.9.3 | ## Web Servers | Tool | Version | Notes | |------|---------|-------| | nginx | 1.24.0 | Not running by default | | Apache | 2.4.58 | Not running by default | | Caddy | 2.6.2 | | ## Databases | Tool | Version | Notes | |------|---------|-------| | SQLite | 3.45.1 | | | PostgreSQL client | 16.11 | Client only, no server | | MySQL client | 8.0.44 | Client only, no server | | Redis CLI | 7.0.15 | Client only, no server | ## Version Control & Dev Tools | Tool | Version | |------|---------| | Git | 2.43.0 | | GitHub CLI (gh) | 2.45.0 | | jq | 1.7 | | yq | 0.0.0 (basic) | | ripgrep (rg) | 14.1.0 | | fzf | 0.44.1 | | tmux | 3.4 | | htop | 3.3.0 | | vim | 9.1 | | nano | 7.2 | ## Network Tools | Tool | Version | |------|---------| | curl | 8.5.0 | | wget | 1.21.4 | | OpenSSH | 9.6p1 | | rsync | 3.2.7 | | netcat (nc) | OpenBSD variant | | socat | 1.8.0.0 | | nmap | 7.94 | | dig | 9.18.x | | OpenSSL | 3.0.13 | ## Compression tar, gzip, zip, unzip, 7z, zstd - all available ## Image & Media | Tool | Version | |------|---------| | ffmpeg | 6.1.1 | | ImageMagick | 6.9.12 | | GraphicsMagick | 1.3.42 | | optipng | 0.7.8 | | pngquant | 2.18.0 | ## Static Site Generators None pre-installed. Easy to add: ```bash # Hugo (extended, for SCSS support) curl -L https://github.com/gohugoio/hugo/releases/download/v0.147.4/hugo_extended_0.147.4_linux-amd64.tar.gz \ -o /tmp/hugo.tar.gz && sudo tar -xzf /tmp/hugo.tar.gz -C /usr/local/bin hugo # Jekyll sudo gem install jekyll bundler ``` ## Coding Agents | Tool | Location | |------|----------| | Shelley | `/usr/local/bin/shelley` (runs on port 9999 by default) | | Claude Code | `/home/exedev/.local/bin/claude` (symlinked from /usr/local/bin) | | Codex | `/usr/local/bin/codex` | ## Infrastructure / IaC | Tool | Version | |------|---------| | Ansible | 2.16.3 | **Not installed:** AWS CLI, gcloud, Azure CLI, Terraform ## Shells | Shell | Version | |-------|---------| | bash | 5.2.21 | | zsh | 5.9 | | fish | 3.7.0 | ## Browser Automation Headless Chrome available at `/headless-shell/headless-shell` ```bash # Launch with CDP debugging /headless-shell/headless-shell \ --no-sandbox \ --headless \ --remote-debugging-port=9222 # Connect via CDP at http://localhost:9222 ``` Includes SwiftShader for software rendering (no GPU required). ## Special Directories | Path | Purpose | |------|---------| | `/headless-shell/` | Headless Chrome + libs | | `/exe.dev/` | exe.dev system config | | `/exe.dev/shelley.json` | Shelley agent config | | `/home/exedev/.config/shelley/` | Shelley data (conversations DB, etc.) | ## Disk & Memory (shared) - Disk: ~19GB total, starts ~5GB used - Memory: 7.2GB shared across all VMs in account ## Gotchas & Tips 1. **Node.js not pre-installed** - Use nvm (see above) for recent Node; apt will get you Node 18. 2. **`/usr/bin/yarn` is cmdtest** - Not the JavaScript yarn. After installing Node, get real yarn via corepack. 3. **Database servers not running** - Only clients installed. Run servers via Docker or install manually. 4. **Web servers not running** - nginx/Apache installed but not started. 5. **Shared resources** - CPU/RAM shared with other VMs in your account; don't assume dedicated resources. 6. **No public IP** - All external access goes through the exe.dev HTTPS proxy. 7. **Disk is persistent** - Your files survive reboots. 8. **Use systemd for long-running services** - Background processes may not persist; see systemd section above. 9. **Docker works** - `docker run --rm alpine:latest echo hello`