Commit Graph

16 Commits

Author SHA1 Message Date
David Montero Crespo fae9208fae Merge branch 'master' of https://github.com/davidmonterocrespo24/velxio 2026-06-15 11:57:59 -03:00
David Montero Crespo cf6a609671 Raspberri pi 4 y 5 2026-06-15 11:57:10 -03:00
David Montero c580a7e418 feat(library-manager): read-only libraries.json file + drop Uninstall for shared index libs
(1) The explorer's per-board manifest entry is renamed velxio.json -> libraries.json
and clicking it now opens a READ-ONLY JSON view of that board's declared libraries
(board.libraries) in the editor, instead of the modal. New editor state
manifestViewBoardId: when set, CodeEditor renders a read-only Monaco showing
{libraries:[...]} live; opening/activating any real file clears it. No file is
added to the workspace, so nothing touches compile or save. Library actions are
done in the Library Manager modal (toolbar button).

(2) Drop the 'Uninstall' button for shared index/cache libraries — you can't
uninstall a copy everyone shares (content-addressed cache). Only your own custom
.zip uploads keep a 'Remove' (per-user store). Index libs: just Add to / In project.
2026-06-09 15:49:14 +02:00
David Montero 5a23e89eb5 feat(custom-chip): program lives in its own editor group, not the board sketch
A programmable custom-chip (a CPU emulator that runs a ROM/program, e.g. the
Z80 or 8080) now keeps its program (larson.s, chaser.c, ...) in a dedicated
editor file group — group-chip-<chipId> — rendered as its own collapsible
section in the file explorer, exactly like each board owns its sketch group.
Behaviour/driver chips and predefined chips carry no programFile and get no
group; they stay editable only in the chip designer.

Fixes two reported issues on the Z80 examples:
- /example/z80-larson-no-board: the board-less chip example now opens its
  program (larson.s) as the active group, editable on the left — previously
  the editor showed but no file appeared.
- /example/z80-led-chaser-c: the chip program (chaser.c) no longer shows as
  a sibling tab inside the Arduino sketch group; it sits in its own chip
  section instead. The board group shows only sketch.ino.

Details:
- useEditorStore: chipFileGroupId()/CHIP_GROUP_PREFIX helpers.
- loadExample: seedChipProgramGroups() routes each chip's programFile into its
  own group (seeded from the example files), sweeps stale chip groups, keeps
  the program OUT of the board group, and for a board-less chip example makes
  the chip group active so the program is the editable file shown.
- EditorToolbar.prepareCustomChips: resolves the program from the chip's own
  group (falls back to board files for older projects) before assembling ROM.
- FileExplorer: renders one collapsible section per programmable chip with an
  IC icon; clicking switches the editor to the chip group. Lazy-creates a
  group for chips dropped on the canvas.
- projectPayload + vlxFile: serialise chip groups alongside board groups and
  include them in the dirty-check hash, so chip-program edits persist on
  save / autosave / .vlx export and round-trip via replaceFileGroups on load.
- Regression tests for board-less + board+chip routing and stale-group sweep.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 22:07:56 +02:00
David Montero Crespo 70cc8c2e11 feat(editor): view-mode toggle, agent-chat slot, toolbar polish
Changes that ship to OSS — all benign for self-hosters, but most are
extension points the velxio-prod overlay (and any private fork) needs to
plug an in-editor AI chat into the page.

Editor:
- 3-way view-mode toggle (code / both / circuit) in the unified toolbar.
  Lets users hide a pane to give a right-docked sidebar (e.g. the AI
  chat overlay) more breathing room. Persisted in useEditorStore.
- Default file explorer narrower (210 → 165 px); min 110.
- Removed the redundant `tb-board-pill` (icon + "Editing: X" tooltip);
  the BoardSelector dropdown elsewhere already shows the active board.
- Inlined Import/Export/Upload-firmware buttons; the 3-dot overflow
  menu gave up too much discoverability. Removed dead overflow state.

Simulator:
- Fix: global Delete/Backspace handler in SimulatorCanvas no longer
  fires when the event target is an INPUT/TEXTAREA/SELECT/contentEditable
  — affected any in-page text field, not just the chat overlay.

Overlay extensibility:
- New `data-velxio-slot="agent-chat"` at the bottom of EditorPage so
  pro overlays can portal a chat panel into the editor without
  forking the page.
- vite.config.ts: preserveSymlinks=true when VITE_PRO_BUILD is set.
  Lets local-dev junctions (overlay tree → frontend/src/pro) resolve
  bare imports back to the OSS node_modules without resolving symlinks.

Deps:
- Added react-markdown + remark-gfm (rendered chat output) and
  @google/genai + zod (overlay agent loop). Tree-shaken from the OSS
  bundle when no pro code imports them.

gitignore:
- Ignore backend/app/pro/ and frontend/src/pro/ junctions used by
  developers running a private overlay against the OSS dev server.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 00:56:51 -03:00
David Montero Crespo 694a2f4073 fix(frontend): polyfill crypto.randomUUID for non-secure contexts
crypto.randomUUID() is only exposed on secure contexts (HTTPS, localhost,
127.0.0.1, ::1). When Velxio is self-hosted and accessed via a LAN IP over
plain HTTP (e.g. http://192.168.31.139:3080/), crypto.randomUUID is
undefined and any code path that calls it throws TypeError.

This silently broke ESP32 simulation start for self-hosters: the frontend
generates a UUID for the WS client_id when Run is clicked; the throw
rejected the promise before reaching the WS connect, so the backend
never got the start request — no worker spawned, logs empty, simulation
"didn't start" with no visible error.

Same root cause would also break the multi-file editor (createFile,
createFileGroup) on the same LAN-HTTP self-host setup, just less
observably.

Add a single generateUUID() helper that:
  1. Uses crypto.randomUUID() when available (secure context fast path).
  2. Falls back to crypto.getRandomValues() — which IS available in
     non-secure contexts — to build a v4 UUID by hand.
  3. Final fallback to Math.random() if even that is missing
     (defensive — Web Crypto getRandomValues has been universal for
     years).

Replace all 6 crypto.randomUUID() call sites:
  - frontend/src/simulation/Esp32Bridge.ts (2 sites — getTabSessionId)
  - frontend/src/store/useEditorStore.ts   (4 sites — file IDs)

Reported by a self-hoster on OrangePi 5B accessing Velxio via LAN IP.
DevTools console showed:
  TypeError: crypto.randomUUID is not a function
    at Ph (...) at wh.connect (...) at startBoard (...)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 13:41:30 -03:00
David Montero Crespo 6a88375bc0 feat: persist multi-board projects + add auto-save
The project save/load pipeline only persisted a single `board_type`, so
multi-board workspaces silently lost every board except the active one
on save, and wires referencing the dropped boards' IDs orphaned to the
canvas corner on reload. An audit of the production backup found 74/306
projects (24%) with at least one orphaned wire and 174/301 non-trivial
projects whose code was still the default Blink template — strong signal
that users save once and never re-save.

Backend
- Add `boards_json` column on `projects` with idempotent ALTER TABLE in
  the lifespan migration list.
- New `FileGroup` schema + `file_groups` array on
  ProjectCreate/Update/Response. Legacy `files`/`code` kept for back-compat.
- `project_files.py` now uses `{pid}/{groupId}/{filename}` subdirs via
  `read_groups`/`write_groups`. Legacy flat layouts are auto-promoted on
  read; legacy single-list `files` only updates the active group, leaving
  other boards' files intact.
- `_persist_files_from_body` honors file_groups → files → code priority.

Frontend
- `useSimulatorStore.addBoard` accepts an optional `explicitId` so
  saved board IDs can be restored verbatim (wires reference IDs literally).
- New `loadProjectState({boards, fileGroups, components, wires,
  activeBoardId})` action: tears down current boards, recreates from the
  payload, restores file groups atomically, recalculates wire positions
  on the next frame, and refreshes the Interconnect.
- `useEditorStore.replaceFileGroups` for atomic multi-group restore.
- `SaveProjectModal` and `ProjectByIdPage`/`ProjectPage` now go through
  `buildSavePayload` / `buildLoadPayload` (handles pre-backfill projects
  by synthesising a default board from `board_type`).

Auto-save (#useAutoSaveProject hook)
- 2.5s debounced silent PUT triggered ONLY when an authenticated user
  has a `currentProject` with a UUID. State hash detects real changes
  vs. UI-only churn; baseline is reset on project load so the just-loaded
  state isn't immediately re-saved.
- `beforeunload` flush via `fetch keepalive: true` (supports PUT +
  credentials, survives unload).
- Compact status indicator in `AppHeader` (idle/dirty/saving/saved/error).

Backfill script (one-off, idempotent)
- `backend/scripts/backfill_boards_2026_05.py` populates `boards_json`
  for legacy projects. Heuristic per project, based on which board IDs
  the wires reference:
    Case A — wires only ref 'arduino-uno' but board_type ≠ uno:
             rename id→board_type and rewrite wire endpoints.
    Case B — single-board normal: keep verbatim.
    Case C — multi-board: recreate one board per distinct ref, infer
             kind by stripping trailing -N suffix.
  Also moves any flat files into the active board's group subdir.
  Stdlib-only, runs from host or `docker exec`.

Docker
- `Dockerfile.standalone` now copies `backend/scripts/` into the image
  so the backfill is callable via `docker exec velxio-app python
  /app/scripts/backfill_boards_2026_05.py --apply`.

Verified locally on the restored production backup (363 projects):
33 Case A, 316 Case B, 14 Case C, 135 wire endpoints renamed, 0 orphans.
Re-running the script after apply skips all 363 (idempotent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 13:43:33 -03:00
David Montero Crespo 641ac8c1de Add comprehensive tests for Cyw43Emulator functionality and lifecycle
- Implemented handshake tests to validate initial bus state and register responses.
- Created end-to-end tests for Pico W LED blinking using MicroPython firmware.
- Added SDPCM framing tests to ensure proper encoding and decoding of control frames.
- Developed IOCTL tests to verify command responses and state changes in the emulator.
- Established a full lifecycle test for WiFi operations, including scanning, connecting, and packet handling.
- Introduced TypeScript configuration for test files to ensure compatibility and strict type checking.
2026-04-29 00:21:26 -03:00
David Montero Crespo 212ecd1bcb refactor: rename components and update prefixes to 'velxio-' for consistency
- 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.
2026-04-21 16:45:45 -03:00
David Montero Crespo a64b14c94e Merge branch 'master' into feature/micropython-rp2040
# Conflicts:
#	.gitignore
#	frontend/src/components/editor/EditorToolbar.tsx
#	frontend/src/components/simulator/SerialMonitor.tsx
#	frontend/src/types/board.ts
2026-04-08 00:11:23 -03:00
David Montero Crespo 7c9fd0bf2b feat: add MicroPython support for ESP32/ESP32-S3 boards via QEMU bridge
Extends MicroPython support (Phase 2) to ESP32 Xtensa boards running on
QEMU. Firmware is downloaded from micropython.org, cached in IndexedDB,
and loaded into QEMU. User code is injected via the raw-paste REPL
protocol after the MicroPython REPL boots.

- Create Esp32MicroPythonLoader.ts for firmware download/cache
- Add raw-paste REPL injection (Ctrl+A → Ctrl+E → code → Ctrl+D) to Esp32Bridge
- Extend loadMicroPythonProgram in store for ESP32 path
- Add ESP32 default MicroPython content (GPIO 2 blink)
- Simplify SerialMonitor Ctrl+C/D to work for all MicroPython boards
- Bundle fallback firmware for ESP32 and ESP32-S3
- Add all ESP32 board variants to SerialMonitor tab maps

Closes #3 (Phase 2)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 23:12:24 -03:00
David Montero Crespo 990ae4be8c feat: add MicroPython support for RP2040 boards (Pico / Pico W)
Implements MicroPython emulation for Raspberry Pi Pico boards running
entirely in the browser using rp2040js. Users can toggle between
Arduino C++ and MicroPython modes via a language selector dropdown.

Key changes:
- Add LanguageMode type and BOARD_SUPPORTS_MICROPYTHON to board types
- Create MicroPythonLoader.ts: UF2 firmware parser, LittleFS filesystem
  builder (via littlefs-wasm), IndexedDB firmware caching
- Extend RP2040Simulator with loadMicroPython() method using USBCDC for
  serial REPL instead of UART
- Add setBoardLanguageMode and loadMicroPythonProgram store actions
- Update EditorToolbar with language toggle and MicroPython compile flow
- Enhance SerialMonitor with REPL label, Ctrl+C/D support
- Bundle MicroPython v1.20.0 UF2 firmware as fallback in public/firmware/
- Update useEditorStore to create main.py default for MicroPython mode

Closes #3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 21:27:41 -03:00
David Montero Crespo 67f9bc70c6 feat: auto-compile when pressing Play if code changed or no hex loaded
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>
2026-03-29 01:46:07 -03:00
David Montero Crespo 17b1a0f058 feat: add board types and mappings for Raspberry Pi 3B
- Introduced new BoardKind types for Raspberry Pi 3B and updated BoardInstance interface.
- Added BOARD_KIND_LABELS and BOARD_KIND_FQBN mappings for new board types.
- Implemented physical to BCM GPIO mapping for Raspberry Pi 3B in boardPinMapping utility.
- Updated BOARD_COMPONENT_IDS to include Raspberry Pi 3B.
- Enhanced isBoardComponent function to support new board type.
- Modified boardPinToNumber function to handle pin mapping for Raspberry Pi 3B.
2026-03-12 23:39:04 -03:00
David Montero Crespo a5c6987aca feat: implement user authentication and project management features
- Add LoginPage and RegisterPage for user authentication.
- Create UserProfilePage to display user projects.
- Implement ProjectPage for viewing and editing individual projects.
- Introduce authService for handling user login, registration, and session management.
- Add projectService for managing project data retrieval and manipulation.
- Enhance EditorPage with file management capabilities and save prompts.
- Introduce Zustand stores for managing authentication, editor state, and project state.
- Add reserved usernames utility to prevent certain usernames during registration.
- Update compilation service to handle multiple files for Arduino sketches.
2026-03-06 10:14:50 -03:00
David Montero Crespo a8c4f143af feat: Implement Arduino Simulator with component management and simulation features
- Added SimulatorCanvas component for rendering the simulator interface.
- Integrated Wokwi components (Arduino, LED, Resistor, Pushbutton, Potentiometer) into the simulator.
- Created PinManager to handle pin state changes and notifications.
- Developed AVRSimulator class for emulating Arduino Uno functionality.
- Implemented hex file loading and compilation service.
- Added CSS styles for the simulator interface.
- Established Zustand stores for managing editor and simulator states.
- Created utility functions for parsing Intel HEX format.
- Set up Vite configuration for the frontend project.
- Added batch scripts for starting backend and frontend servers, and updating Wokwi libraries.
2026-03-03 00:20:49 -03:00