- Add data-segment-handle attribute to segment handle circles in WireLayer
- Skip long-press aiming timer when touch targets segment handle
- Add safety checks to cancel pending timer when segment drag starts
- Ensure segment drag always takes priority over crosshair activation
This fixes the bug where accidentally holding still while dragging a wire
segment would activate the crosshair overlay and interrupt the editing workflow.
- Snapshot-based undo/redo (full wires array per step, max 50 entries)
- Keyboard shortcuts: Ctrl+Z (undo), Ctrl+Shift+Z (redo)
- Toolbar buttons in canvas header (visible on mobile via separate
undo-controls CSS class that isn't hidden by mobile media query)
- All 4 wire mutations (add, remove, update, finish) push snapshots
- selectedWireId reset on undo/redo to avoid stale references
Two bugs fixed:
1. SaveProjectModal was reading from the legacy global `files` array instead
of the active board's file group, causing projects to be saved with the
wrong board_type (e.g. 'arduino-uno' for ESP32 projects).
Now reads from fileGroups[activeBoard.activeFileGroupId] and uses
activeBoard.boardKind for board_type.
2. Error handling was always showing "Save failed." — now shows:
- "Server unreachable. Check your connection and try again." for network errors
- "Not authenticated. Please log in and try again." for 401 responses
- The server's detail message (with status code) for other errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Frontend WiFi detection via file-content scanning was unreliable because
fileGroups[board.activeFileGroupId] could be an empty array (not null),
bypassing the ?? fallback to editorState.files.
Fix: the ESP-IDF compiler now returns has_wifi:bool in its compile response.
The frontend stores this on the BoardInstance and uses it in startBoard()
instead of scanning file contents. The file-content scan is kept as a
fallback for boards that haven't been compiled in this session.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
startBoard() was reading useEditorStore.getState().files (the legacy global
array with the default Arduino sketch) instead of the board's specific file
group. This caused hasWifi to always be false for ESP32 boards, so QEMU
never received the -nic flag and WiFi never connected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_build_env() on Linux only set IDF_TOOLS_PATH but never added the tool
binary directories to PATH, so cmake could not find riscv32-esp-elf-g++
when compiling for ESP32-C3. Also improve ninja failure logging to show
stdout (where build errors actually appear) instead of empty stderr.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dockerfile: download pre-built .so + ROM from velxio public release
instead of building from private qemu-lcgamboa source
- espidf_compiler: normalize any WiFi SSID → "Velxio-GUEST" for QEMU
compatibility (channel 6, open auth)
- docker-compose.yml: unified dev/prod using Dockerfile.standalone
- .dockerignore: exclude qemu-lcgamboa source from Docker context
- .gitignore: ignore prebuilt/ binaries, keep .gitkeep
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- handleRun now auto-compiles for ESP32/QEMU boards when no firmware is
available (same behavior as AVR/RP2040 boards)
- startBoard now reloads compiledProgram into the bridge if _pendingFirmware
was lost (e.g. after a page refresh between compile and run)
- Adds Esp32Bridge.hasFirmware() helper used by the store check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ESP-IDF 4.4.x requires specific package versions (reedsolo<=1.5.4,
bitstring<4, pyparsing<2.4.0, kconfiglib==13.7.1, etc.) that conflict
with newer defaults. Installing requirements.txt after copying ESP-IDF
ensures the correct versions are used and cmake configure succeeds.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- git is required by ESP-IDF cmake to resolve submodules and version info
- packaging Python package is required by ESP-IDF Python dependency checks
during cmake configure step
Without these, ESP32 compilation fails at cmake configure with:
"Some Python dependencies must be installed"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- cmake and ninja are required by ESP-IDF compilation pipeline but were
missing from the final stage, causing all ESP32 compilations to fail
- libusb-1.0-0 fixes the openocd-esp32 shared library warning on startup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The openocd-esp32 tool fails with exit code 127 due to missing libusb-1.0.so.0
in the runtime image. With set -e, this caused the entrypoint to exit before
starting uvicorn and nginx, putting the container in a restart loop.
Adding || true allows the ESP-IDF environment to be sourced while tolerating
the non-critical openocd warning.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace arduino-cli with ESP-IDF 4.4.7 for ESP32 compilation — Arduino-compiled
firmware crashes in QEMU (9-28 reboots) while ESP-IDF boots cleanly (0 reboots).
The new espidf_compiler translates Arduino WiFi/WebServer sketches to native
ESP-IDF C code, compiles with cmake+ninja, and merges into 4MB flash images.
Key changes:
- ESP-IDF compiler: translates WiFi.begin/WebServer to esp_wifi/esp_http_server
- ESP-IDF project template with QEMU-optimized sdkconfig (DIO, 40MHz, no WDT)
- WiFi status parser for ESP-IDF serial logs (wifi_status, ble_status events)
- IoT Gateway HTTP reverse proxy for ESP32 web servers
- WiFi/BLE auto-detection from sketch content + visual status icons
- Static IP 192.168.4.15 matching slirp DHCP first-client range
- Docker: new espidf-builder stage with ESP-IDF 4.4.7 toolchain
- 157 tests covering WiFi/BLE for both ESP32 (Xtensa) and ESP32-C3 (RISC-V)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds the Velxio VS Code extension skeleton with:
- Extension host: commands (Open/Compile/Run/Stop/Select Board),
WebView panel with postMessage bridge, FastAPI backend manager,
velxio.toml + diagram.json config parser, file watcher, serial
pseudo-terminal
- WebView: placeholder React app with board display and serial
monitor, ready for wiring to the real simulation engines
- Build system: esbuild for extension (94KB), Vite for webview (198KB)
- Wokwi-compatible diagram.json schema for future import support
Based on reverse-engineering of the Wokwi VS Code extension (v3.5.0).
Key differentiator: Velxio runs simulation 100% locally (avr8js/rp2040js
in WebView, QEMU for ESP32) vs Wokwi's cloud iframe approach.
Refs #4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Closes#14
- Right-click context menu on boards with "Remove board" option
- Delete/Backspace key removes the active board (when no component selected)
- Confirmation dialog before removal showing connected wire count
- Removing a board also removes all connected wires and cleans up
file groups, simulators, bridges, and VFS
- Cannot remove the last remaining board (button disabled + guard)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Closes#81
- Add `codeChangedSinceLastCompile` dirty flag to useEditorStore
- Play button now triggers compilation automatically when no compiled
program exists or code has changed since last compile
- Show compilation progress during auto-compile before run
- If compilation fails, show errors instead of running stale code
- Keep separate Compile button for manual compile-only workflow
- Play button always enabled (disabled only while running/compiling)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>