Add ESP32-S3 companion support and harden Command Centre config/file handling - #1
Merged
Merged
Conversation
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Co-authored-by: artifact-opensource <270091407+artifact-opensource@users.noreply.github.com>
Copilot
AI
changed the title
Add ESP32-S3 companion scaffold and command centre support
Add ESP32-S3 companion support and harden Command Centre config/file handling
Aug 22, 2026
Copilot created this pull request from a session on behalf of
artifact-opensource
August 22, 2026 05:44
View session
artifact-opensource
marked this pull request as ready for review
August 22, 2026 08:04
artifact-opensource
approved these changes
Aug 22, 2026
There was a problem hiding this comment.
🟡 Changes recommended
The Command Centre currently exposes sensitive config fields to the browser and has a couple of concrete correctness/security issues (XSS risk, stale /shared root, and path-prefix logic).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds an ESP32-S3 companion scaffold and introduces a new “Command Centre” surface in the Android daemon to manage providers, shared storage, firmware staging, and RGB profiles, alongside config normalization and regression tests to prevent unintended persistence.
Changes:
- Added
esp32_s3/companion scaffold (ESP-IDF project files, partition layout, Lua RGB profiles, host simulation). - Added Command Centre UI/API endpoints plus firmware catalog + install/flash actions, and exposed
/shared/browsing. - Hardened config/provider behavior (directory normalization, provider alias canonicalization) and added regression tests.
File summaries
| File | Description |
|---|---|
| README.md | Documents ESP32-S3 companion and Command Centre component; updates provider list. |
| esp32_s3/README.md | New documentation for ESP32-S3 scaffold, layout, and host simulation. |
| esp32_s3/partitions.csv | Defines partitions including spore_assets for staged firmware/assets. |
| esp32_s3/main/spore_esp32_s3.c | New companion firmware + host sim, Lua-backed RGB profile loading, status snapshot scaffold. |
| esp32_s3/main/rgb_profiles.lua | Default RGB activity profiles/patterns. |
| esp32_s3/main/CMakeLists.txt | ESP-IDF component registration for companion firmware. |
| esp32_s3/CMakeLists.txt | ESP-IDF project scaffold entry. |
| android/README.md | Mentions Command Centre and adds provider setup examples. |
| android/provider/provider.go | Expands/adjusts provider registry; canonicalizes gemini → google. |
| android/main.go | Updates CLI help to include Command Centre and expanded providers. |
| android/go.mod | Marks nhooyr.io/websocket as a direct dependency. |
| android/daemon/webchat.go | Adds a navigation link to /command-centre. |
| android/daemon/daemon.go | Registers Command Centre routes and /shared/ file browsing. |
| android/daemon/command_centre.go | New Command Centre API/UI, firmware catalog + install/flash actions, storage/provider controls. |
| android/daemon/command_centre_test.go | New tests for Command Centre behavior and persistence expectations. |
| android/core/config.go | Adds shared/storage fields and normalizes managed directories; provider canonicalization. |
| android/core/config_test.go | Adds tests for shared/secondary dir normalization and provider alias canonicalization. |
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 8
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| case "shared_dir": | ||
| oldShared := c.SharedDir | ||
| c.SharedDir = value | ||
| if c.SecondaryFirmwareDir == "" || (oldShared != "" && strings.HasPrefix(filepath.Clean(c.SecondaryFirmwareDir), filepath.Clean(oldShared))) { |
| mux.HandleFunc("/api/sessions/", h.sessionByID) | ||
| mux.HandleFunc("/api/command-centre", h.commandCentreAPI) | ||
| mux.HandleFunc("/api/command-centre/firmware", h.commandCentreFirmware) | ||
| mux.Handle("/shared/", http.StripPrefix("/shared/", http.FileServer(http.Dir(cfg.SharedDir)))) |
Comment on lines
+207
to
+210
| projectDir := detectESP32Project() | ||
| configView := *cfg | ||
| configView.APIKey = "" | ||
| return commandCentreState{ |
Comment on lines
+170
to
+176
| case "install", "": | ||
| target, err := joinUnderRoot(cfg.SecondaryFirmwareDir, filepath.Base(source)) | ||
| if err != nil { | ||
| http.Error(w, err.Error(), http.StatusBadRequest) | ||
| return | ||
| } | ||
| if err := copyFile(sourceRoot, source, cfg.SecondaryFirmwareDir, target); err != nil { |
Comment on lines
+635
to
+638
| document.getElementById('sharedFiles').innerHTML=(state.shared_files||[]).map(function(f){return '<div class="item"><strong>'+f.name+'</strong><small>'+f.path+'</small></div>';}).join('') || '<div class="muted">Shared directory is empty.</div>'; | ||
| document.getElementById('firmware').innerHTML=(state.firmware_catalog||[]).map(function(f){return '<div class="item"><strong>'+f.name+'</strong><small>'+f.path+'</small><div class="actions"><button data-source="'+esc(f.source)+'" onclick="installFirmware(this.dataset.source)">Install</button><button class="ghost" data-source="'+esc(f.source)+'" onclick="flashFirmware(this.dataset.source)">Flash</button></div></div>';}).join('') || '<div class="muted">No firmware or Lua/MicroPython assets detected yet.</div>'; | ||
| } | ||
| function esc(v){return String(v).replace(/'/g,"'")} |
Comment on lines
+6
to
+14
|
|
||
| #if __has_include(<lua.h>) | ||
| #include <lua.h> | ||
| #include <lauxlib.h> | ||
| #include <lualib.h> | ||
| #define SPORE_HAS_LUA 1 | ||
| #else | ||
| #define SPORE_HAS_LUA 0 | ||
| #endif |
Comment on lines
+82
to
+84
| lua_getfield(L, -1, "pattern"); | ||
| snprintf(out->pattern, sizeof(out->pattern), "%s", lua_tostring(L, -1)); | ||
| lua_pop(L, 1); |
| #if SPORE_HAS_HTTPD | ||
| static esp_err_t status_handler(httpd_req_t *req) { | ||
| char body[96]; | ||
| snprintf(body, sizeof(body), "{\"service\":\"spore-command-centre\",\"gpio_rgb\":%d,\"espnow\":true}", SPORE_RGB_GPIO); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change adds the ESP32-S3 companion scaffold and wires the Command Centre to manage shared firmware, RGB profiles, and related storage paths. It also removes unintended config writes and tightens managed-path handling so the new flows behave predictably.
Command Centre surface area
Config and provider behavior
shared_dirandsecondary_firmware_dirconsistently under managed roots.geminialias to thegoogleprovider to avoid duplicate registry entries in the UI.Filesystem safety
ESP32-S3 companion scaffold
Regression coverage