chore: bump ESP32_ZACUS + nested CLAUDE.md refresh
Submodule bump: 6129375 -> 1a984b0 Pulls in the firmware build fixes pushed to github.com/electron-rare/ESP32_ZACUS branch fix/build-arduino-esp32-3.20014 (PR pending review). The firmware now compiles cleanly and survives boot on the Freenove ESP32-S3 dev board (verified flash + 30 s monitor: SD mounted, LittleFS ready, no panic, 90 k UI frames). Once the upstream PR is merged to main, the parent pointer can be re-bumped to ESP32_ZACUS@main without changes. CLAUDE.md refresh (init-deep follow-up): - frontend-v3/apps/atelier/CLAUDE.md (new, 61 lines): layout map, store responsibilities, lazy-chunk pattern, dev-only window hooks, build with --base, anti-patterns. - desktop/CLAUDE.md (+8 lines): Tests section + npm test command + --ignore-scripts install hint. - tests/CLAUDE.md (+1 line): list test_firmware_bundle.py alongside test_runtime3_routes.py. All nested CLAUDE.md remain within the 30-80 line target (longest is atelier at 61).
This commit is contained in:
+1
-1
Submodule ESP32_ZACUS updated: 6129375916...1a984b006d
@@ -19,13 +19,21 @@ resources/ # Bundled frontend artefacts + assets
|
||||
|
||||
```bash
|
||||
npm install # Triggers electron-builder install-app-deps + electron-rebuild
|
||||
npm install --ignore-scripts # Skip native rebuild (sufficient for unit tests)
|
||||
npm run dev # Concurrent main + renderer
|
||||
npm run build # tsc main + vite renderer
|
||||
npm run build:mac # Universal (x64 + arm64) installer
|
||||
npm run build:mac-arm64 # Apple Silicon only
|
||||
npm run rebuild-native # zacus-native addon for current Electron ABI
|
||||
npm test # Vitest unit tests (mocks electron + serialport)
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
Unit tests live in `src/**/__tests__/**/*.test.ts` and run via Vitest in node env. `electron`, `fs`, `os`, and `http` are mocked via `vi.mock` so tests need neither a real ESP32 nor the native serialport rebuild.
|
||||
|
||||
Out of scope here: Playwright Electron mode (would launch the packaged app), HTTP-flow OTA tests (need server fixture), BLE/USB delegation paths.
|
||||
|
||||
## Patterns
|
||||
|
||||
- Three tsconfigs (`tsconfig.main.json`, `tsconfig.renderer.json`, root) — never share between processes; main and renderer have different module systems.
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Atelier
|
||||
|
||||
Scratch-like authoring studio: Blockly editor (left/center) + R3F 3D simulation stage (right) + validation console (bottom). Live-diff: edit a block → 500 ms debounce → stale badge → click Run → simulation reloads via `simStore.loadScenario(yaml)`.
|
||||
|
||||
Design doc: `docs/superpowers/specs/2026-05-01-v3-fusion-atelier-design.md`.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
src/
|
||||
main.tsx # ReactDOM root, StrictMode
|
||||
App.tsx # useLiveDiff() + <Layout/>; dev hooks on window
|
||||
main.css # Shell + pane styles
|
||||
vite-env.d.ts # Vite client types
|
||||
components/
|
||||
Layout.tsx # PanelGroup tree, ⌘B stage toggle
|
||||
EditorPane.tsx # Lazy(BlocklyWorkspace) + register blocks + validate on change
|
||||
StagePane.tsx # Lazy(RoomScene + mode HUDs) + Run button
|
||||
ConsolePane.tsx # Mode tabs + validation entries list
|
||||
BlocklyWorkspace.tsx # forwardRef wrapper around Blockly.inject
|
||||
toolbox.ts # XML toolbox config
|
||||
YamlPreview.tsx # Syntax-highlighted YAML rendering
|
||||
blocks/
|
||||
{puzzle,npc,flow}-blocks.ts # Block definitions + YAML generators
|
||||
index.ts # registerAllBlocks (idempotent)
|
||||
scene/ # R3F 3D scene (RoomScene, RtcPhone, PuzzleStations, NpcBubble)
|
||||
puzzles/ # P1Sound, P5Morse, P6Symbols, P7Coffre (3D widgets)
|
||||
modes/ # SandboxMode, DemoMode, TestMode HUDs
|
||||
stores/ # editor / runtime / sim / validation (zustand)
|
||||
lib/
|
||||
yaml-export.ts # workspace -> YAML
|
||||
yaml-import.ts # YAML -> workspace
|
||||
validator.ts # 6-rule schema check (ScenarioYaml -> ValidationResult)
|
||||
useLiveDiff.ts # debounce 500 ms then setPendingIr
|
||||
```
|
||||
|
||||
## Patterns
|
||||
|
||||
- **Lazy chunks** via `React.lazy` + Suspense for both Blockly (~700 kB gzip) and R3F+three (~1 MB gzip). Initial shell stays under 80 kB. Vite `manualChunks` in `vite.config.ts` enforces the split.
|
||||
- **Stores stay focused**: `editorStore` = blocklyJson string ; `runtimeStore` = pending/current IR + isStale ; `simStore` = mode + engine instance + npcMood ; `validationStore` = entries with `severity` + `source` (schema|compile|runtime|test).
|
||||
- **Mode is sim concern**, not editor↔stage sync — lives in `simStore`. ConsolePane reads from there.
|
||||
- **Run button** in `StagePane` is the only commit point: it calls `simStore.loadScenario(pendingIr)` then `runtimeStore.commitPendingIr()`.
|
||||
- **Tailwind classes are not configured** — use inline styles or `main.css` classes (`atelier-pane`, `atelier-mode-tab`, `atelier-resizer--*`). Tailwind in legacy simulation HUDs was rewritten as inline styles during P4.
|
||||
- **Dev-only window hooks**: `App.tsx` exposes stores on `window.__atelierStores`, `Layout.tsx` exposes `window.__atelierToggleStage`, `EditorPane.tsx` exposes `window.__atelierBlockly.getWorkspace()`. All gated by `import.meta.env.DEV`. E2E specs drive workflow through them instead of relying on real DnD.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
pnpm exec vite build --base=/atelier/ # for prod deployment with prefix
|
||||
pnpm exec vite build # for dev / desktop bundle (root path)
|
||||
```
|
||||
|
||||
`pnpm --filter @zacus/atelier build -- --base=...` does NOT pass `--base` correctly through the script chain — call vite directly via `cd apps/atelier && pnpm exec vite ...`.
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- Putting `mode` back into `runtimeStore` — it belongs to `simStore`.
|
||||
- Calling `voiceWsConnect()` or any lwip-touching code at boot without a network-ready guard (matches the ESP32_ZACUS bug fix from this session).
|
||||
- Hardcoding `/atelier/` as base path — the dev server uses root, only the deployed prod build uses the prefix.
|
||||
- Adding deps to root `frontend-v3/package.json` — atelier deps live here.
|
||||
- Bypassing the Run button to mutate `simStore.engine` directly — breaks the live-diff contract.
|
||||
+2
-1
@@ -9,7 +9,8 @@ Python unittest suite covering Runtime 3 IR, NPC engine integration, and scenari
|
||||
| `test_npc_engine.py` | NPC state machine (triggers, mood, rule firing) |
|
||||
| `test_npc_integration.py` | NPC ↔ TTS ↔ phrase bank wiring |
|
||||
| `test_npc_phrases_schema.py` | `npc_phrases.yaml` schema invariants |
|
||||
| `runtime3/` | Runtime 3 compiler/IR/pivot tests |
|
||||
| `runtime3/test_runtime3_routes.py` | Runtime 3 compiler/IR/pivot tests |
|
||||
| `runtime3/test_firmware_bundle.py` | E2E pipeline: scenario YAML → IR → firmware bundle JSON (subprocess) |
|
||||
|
||||
## Running
|
||||
|
||||
|
||||
Reference in New Issue
Block a user