The stop-first guard in the Run button only fires when board.running is
true, but the Run button is DISABLED while a board runs — so by the time the
user can actually click Run, the board has already disconnected
(running=false) and the guard is a no-op. The failure lives one level down:
Esp32Bridge.connect() early-returned whenever a socket lingered in ANY
non-CLOSED state (CONNECTING/OPEN/CLOSING). The agent's run_simulation
leaves such a socket; when its backend QEMU session ends but the frontend
socket is still zombie, the user's Run → startBoard → connect() did nothing.
A page reload "fixed" it only by constructing a fresh bridge.
connect() now tears down any lingering socket (detaching handlers + close)
and opens a new one to the same session key — exactly what the reload does,
which is why the reload always worked. The backend already handles a new WS
replacing an existing session, so no reload is needed.
Test: connect() on an OPEN socket closes the old one and boots a fresh
start_esp32 (esp32-dht22-flow).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Move the CYW43439 (Pico W) WiFi emulation out of the open-source tree so it
can ship as a paid feature in a private overlay. OSS keeps a plain Pico W
(no WiFi); the overlay registers the cyw43 protocol + backend network stack
at runtime via generic seams.
Frontend:
- Add simulation/PioPeripheral.ts: a generic "PIO bus peripheral" seam
(feedWord / inDiscardableWriteData / resetFraming / hostWakeLevel /
onHostWake / onSimulationStart). No factory is installed in OSS, so
createPioPeripheral() returns null and a Pico W simulates as a plain Pico.
- RP2040Simulator: keep the fragile PIO-FIFO plumbing (it must re-run after
loadMicroPython swaps the chip) but drive it through PioPeripheral instead
of an inlined cyw43 import (attachCyw43 -> attachPioPeripheral, etc.).
- useSimulatorStore: generic attach/detach + setBoardWifiStatus; drop the
cyw43 bridge map.
- MicroPythonLoader: add registerFirmwareVariant() so an overlay can add the
RPI_PICO_W build; remove the OSS pico-w config + bundled .uf2.
- Delete simulation/cyw43/ (moved to the overlay).
Backend:
- core/hooks.py: add generic register_ws_sim_handler / dispatch_ws_sim_message
and register_gateway_proxy / dispatch_gateway_proxy seams.
- simulation.py: route start_picow / stop_picow / picow_packet_out through the
ws_sim_handler hook (the overlay handles + gates them).
- iot_gateway.py: resolve the Pico W gateway through the gateway_proxy hook.
- Delete services/picow_net/ + picow_net_bridge.py (moved to the overlay).
Tests: move the cyw43/picow suites to the overlay; update RP2040Simulator
mock stubs to attachPioPeripheral.
Same root cause as the previous test fix in 3e38397 — upstream commit
d64eebc (fix(stop): reset CPU to PC=0) added a hardResetPinStates() call
to useSimulatorStore.stopBoard. The vi.mock factories in these 6 ESP32-
adjacent test files only exposed updatePort/onPinChange/getListenersCount,
so any test path that hits stopBoard crashed with "is not a function"
once the real prod code called the new method.
Each gets a single-line addition: this.hardResetPinStates = vi.fn();
Verified with full vitest run: 127 files pass, 2,005 tests pass, 0 failures.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Implemented `i2c-esp32-real-firmware.test.ts` to test ESP32 I2C communication via backend and WebSocket.
- Created `load-example-transitions.test.ts` to ensure proper loading of examples between board-less and board-based contexts.
- Added `CircuitVerificationModal.tsx` to display circuit verification results before running simulations.
- Developed `circuitVerifier.ts` to perform pre-flight checks for circuit safety, identifying potential issues like short circuits and component overloads.
- Introduced minimal ESP32 I2C master sketch `esp32_i2c_writer.ino` for testing I2C transactions.
CI's Frontend Tests workflow had been failing on master for ~15 runs.
Two pre-existing issues, neither related to the SPI refactor in 8b1433d
or the ESP32-CAM work:
1. RP2040Simulator mock missing attachCyw43 method (23 test files)
PR #126 (8e769f8 "feat(multi-board): add wire-aware cross-board
interconnect router", merged 2026-04-25) added a Pico-W-specific
`sim.attachCyw43(bridge)` call inside addBoard(). The 23 test files
that mock RP2040Simulator with vi.fn weren't updated; whenever a
test path created a Pico W board the mock threw "TypeError:
sim.attachCyw43 is not a function" and aborted addBoard.
Fix: add `this.attachCyw43 = vi.fn()` to every affected mock.
Also pre-populate `this.spi = { onByte: null, completeTransfer: vi.fn() }`
so any future SPI-part tests don't trip on the new generic .spi
adapter from 8b1433d.
2. install-libraries.test.ts payload mismatch
PR #135 (b1026ec7 "library-version-uninstall", merged 2026-04-29)
extended `installLibrary(name)` to `installLibrary(name, version?)`
and now sends `{name, version: version ?? null}` over the wire.
The test still asserted `{name}` only and failed.
Fix: assert `{name, version: null}` for the no-version call.
Verified locally: 1161 passed | 1 skipped (was 1117 passed | 44 failed).
Backend E2E "Run HC-SR04 e2e test" is a separate failure that needs
its own investigation — it downloads QEMU binaries from a release and
runs real firmware compilation, which I can't reproduce on Windows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Modified the index file to reflect the new naming convention for Velxio components.
- Changed JSX declarations to use 'velxio-' prefix for various components.
- Updated component overrides to replace 'wokwi-' with 'velxio-' for logic gates and other components.
- Adjusted SVG generation script to use 'velxio-' prefix for BMP280 and Raspberry Pi components.
- Marked submodules as dirty in QEMU and RP2040 libraries.
- Added .prettierignore and .prettierrc.json for consistent code formatting.
- Introduced InstrumentComponent with support for Voltmeter and Ammeter, including pin information handling.
- Added board-agnostic sensor registration methods in RP2040Simulator.
- Enhanced ComplexParts to handle LEDC PWM duty updates for ESP32.
- Updated ProtocolParts to check if the simulator handles sensor protocols natively, delegating to backend if applicable.
- Introduced pre-registration of sensors in useSimulatorStore for ESP32 to prevent race conditions.
- Added tests for ESP32 DHT22 sensor registration flow, ensuring proper delegation and fallback mechanisms.
- Created tests for ESP32 Servo and Potentiometer interactions, verifying PWM subscriptions and ADC handling.