From c1b9244341b9f6344d18d16579c8efdcebf62610 Mon Sep 17 00:00:00 2001 From: Sipho Mokoena Date: Fri, 27 Mar 2026 01:59:48 +0000 Subject: [PATCH] feat: add VS Code devcontainer configuration with optimized setup - Add .devcontainer/devcontainer.json with Python 3.12 + Node 20 base image - Added remoteUser: vscode to avoid running as root - Configured named volumes for node_modules (frontend + 3 wokwi-libs) to improve I/O performance on non-Linux hosts - Added volume for arduino-cli cache at /home/vscode/.arduino15 - Added remoteEnv PATH to include node_modules/.bin and venv/bin - Configured port forwarding for 5173 (Vite) and 8001 (FastAPI) - Add .devcontainer/post-create.sh for initial container setup - Fix ownership of node_modules volumes with chown vscode:vscode - Install arduino-cli with sudo to /usr/local/bin - Install Arduino cores (arduino:avr, rp2040:rp2040) with duplicate guards - Set up Python venv with base deps (wheel, setuptools) before requirements.txt - Install npm deps with HUSKY=0 to disable git hooks in container environment - Build wokwi-libs (avr8js, rp2040js, wokwi-elements) in parallel - All installs run in parallel background jobs with wait for optimal performance - Add .devcontainer/post-start.sh for incremental updates on container restart - Lightweight sync of Python and npm dependencies - Runs on every container start for drift detection - Add wokwi-boards submodule for ESP32/Pico board SVG assets - Code imports board.svg files from wokwi-libs/wokwi-boards/boards/ - Submodule was referenced but not initialized, causing Vite import errors - Configure Vite to bind to 0.0.0.0:5173 for devcontainer port forwarding - Default 127.0.0.1 binding is not accessible from outside container - Explicit host/port config enables VS Code port forwarding to work --- .devcontainer/devcontainer.json | 46 +++++++++++++++++++++++ .devcontainer/post-create.sh | 65 +++++++++++++++++++++++++++++++++ .devcontainer/post-start.sh | 16 ++++++++ .gitmodules | 3 ++ frontend/vite.config.ts | 2 + 5 files changed, 132 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100755 .devcontainer/post-create.sh create mode 100644 .devcontainer/post-start.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..5838758 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,46 @@ +{ + "name": "Velxio", + "image": "mcr.microsoft.com/devcontainers/python:3.12", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "20", + "installGlobally": true + } + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-vscode.vscode-typescript-next", + "dbaeumer.vscode-eslint", + "bradlc.vscode-tailwindcss" + ] + } + }, + "remoteUser": "vscode", + "waitFor": "postCreateCommand", + "mounts": [ + "source=${localWorkspaceFolder}/wokwi-libs,target=/workspaces/velxio/wokwi-libs,type=bind,consistency=cached", + "source=velxio-arduino-cache,target=/home/vscode/.arduino15,type=volume", + "source=velxio-frontend-nodemodules,target=/workspaces/velxio/frontend/node_modules,type=volume", + "source=velxio-avr8js-nodemodules,target=/workspaces/velxio/wokwi-libs/avr8js/node_modules,type=volume", + "source=velxio-rp2040js-nodemodules,target=/workspaces/velxio/wokwi-libs/rp2040js/node_modules,type=volume", + "source=velxio-wokwi-elements-nodemodules,target=/workspaces/velxio/wokwi-libs/wokwi-elements/node_modules,type=volume" + ], + "postCreateCommand": "bash .devcontainer/post-create.sh", + "postStartCommand": "bash .devcontainer/post-start.sh", + "remoteEnv": { + "PATH": "${containerEnv:PATH}:/workspaces/velxio/frontend/node_modules/.bin:/workspaces/velxio/backend/venv/bin" + }, + "forwardPorts": [5173, 8001], + "portsAttributes": { + "5173": { + "label": "Frontend (Vite)", + "onAutoForward": "notify" + }, + "8001": { + "label": "Backend (FastAPI)", + "onAutoForward": "notify" + } + } +} diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100755 index 0000000..6dc38e6 --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,65 @@ +#!/bin/bash +set -e + +cd /workspaces/velxio + +echo "==> Fixing ownership for mounted volumes..." +# Fix ownership of directories that are mounted as volumes +sudo chown -R vscode:vscode /workspaces/velxio/frontend/node_modules 2>/dev/null || true +sudo chown -R vscode:vscode /workspaces/velxio/wokwi-libs/avr8js/node_modules 2>/dev/null || true +sudo chown -R vscode:vscode /workspaces/velxio/wokwi-libs/rp2040js/node_modules 2>/dev/null || true +sudo chown -R vscode:vscode /workspaces/velxio/wokwi-libs/wokwi-elements/node_modules 2>/dev/null || true +sudo chown -R vscode:vscode /home/vscode/.arduino15 2>/dev/null || true + +echo "==> Installing arduino-cli..." +if ! command -v arduino-cli &> /dev/null; then + curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sudo BINDIR=/usr/local/bin sh +fi + +echo "==> Installing Arduino cores (this may take a few minutes)..." +sudo arduino-cli core update-index +if ! sudo arduino-cli core list | grep -q "arduino:avr"; then + sudo arduino-cli core install arduino:avr +fi + +# Add RP2040 board manager (guard against duplicates) +if ! sudo arduino-cli config get board_manager.additional_urls | grep -q "rp2040"; then + sudo arduino-cli config add board_manager.additional_urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json +fi +if ! sudo arduino-cli core list | grep -q "rp2040:rp2040"; then + sudo arduino-cli core install rp2040:rp2040 +fi + +echo "==> Setting up Python virtual environment (base layer)..." +(cd /workspaces/velxio/backend +python3 -m venv venv +./venv/bin/pip install wheel setuptools +./venv/bin/pip install -r requirements.txt) & + +echo "==> Installing frontend dependencies..." +(cd /workspaces/velxio/frontend +HUSKY=0 npm install) & + +echo "==> Building wokwi-libs..." +# Local wokwi-libs are cloned from GitHub instead of using npm packages. +# This allows us to modify the emulators and components for Velxio-specific behavior. +# Build outputs go to dist/ directories and are resolved via Vite aliases. +(cd /workspaces/velxio/wokwi-libs/avr8js +HUSKY=0 npm install +npm run build) & + +(cd /workspaces/velxio/wokwi-libs/rp2040js +HUSKY=0 npm install +npm run build) & + +(cd /workspaces/velxio/wokwi-libs/wokwi-elements +HUSKY=0 npm install +npm run build) & + +wait # Wait for all background jobs to complete + +echo "==> Dev environment ready!" +echo "" +echo "To start development:" +echo " Backend: cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8001" +echo " Frontend: cd frontend && npm run dev" diff --git a/.devcontainer/post-start.sh b/.devcontainer/post-start.sh new file mode 100644 index 0000000..84895ed --- /dev/null +++ b/.devcontainer/post-start.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +cd /workspaces/velxio + +echo "==> Fixing ownership for mounted volumes..." +sudo chown -R vscode:vscode /workspaces/velxio/frontend/node_modules 2>/dev/null || true + +echo "==> Syncing Python dependencies..." +(cd /workspaces/velxio/backend +source venv/bin/activate +pip install -q -r requirements.txt) + +echo "==> Syncing frontend dependencies..." +cd /workspaces/velxio/frontend +HUSKY=0 npm install diff --git a/.gitmodules b/.gitmodules index 17c9e41..175529e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "wokwi-libs/wokwi-features"] path = wokwi-libs/wokwi-features url = https://github.com/wokwi/wokwi-features.git +[submodule "wokwi-libs/wokwi-boards"] + path = wokwi-libs/wokwi-boards + url = https://github.com/wokwi/wokwi-boards.git diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index fafeaad..3ec9b95 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -13,6 +13,8 @@ export default defineConfig({ }, }, server: { + host: '0.0.0.0', + port: 5173, proxy: { '/api': { target: 'http://localhost:8001',