Gateway : POST /v1/assets/text/generate (sans token, même origine) proxie le
LLM ailiance (OpenAI-compatible) avec un system-prompt par type — npc_reply,
hint, scene_text, freeform. Setting ailiance_url (défaut gateway.ailiance.fr).
Atelier : panneau flottant « Générer (IA) » (TextGenPanel) — choix du type,
prompt, génération, aperçu, copier. Client lib/textgen.ts (même URL gateway
que share/deploy, donc même origine en prod → zéro CORS).
Validé : POST .../v1/assets/text/generate → réplique NPC / indice en personnage
(modèle Ministral-14B via ailiance). Bundle prod câblé sur zacus.saillant.cc/api.
Première tranche du plan specs/2026-06-13-atelier-asset-authoring-plan.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan de projet (P0–P5) pour éditer/générer écran, audio et fichiers SD/NFS
depuis l'Atelier web, avec ponts firmware et génération assistée
(gateway.ailiance.fr pour le texte). Inclut l'audit du pipeline d'assets
existant, dépendances entre phases, risques, et chemin web/firmware séparés.
NB: la fondation firmware audio (P4 : playback WAV/MP3, montage SD) est
désormais livrée côté ESP32_ZACUS — voir bump submodule.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Les puzzles de zacus_v3.yaml n'avaient ni `act`, ni `objective`, ni
`firmware_step` (requis par le validateur schema V2). Ajout calqué sur
zacus_v2 : Diapason→acte 1, Piano LEFOU→acte 2, QR Archives→acte 2 ;
valeurs déduites du contenu existant (scène, runtime_steps, solution).
Le scénario valide, compile et simule désormais le playthrough complet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ajoute une barre de menu en haut de l'Atelier :
- Ouvrir : menu déroulant de 3 scénarios de départ embarqués (format
blocks_studio v2) — intro+énigme sonore, maître du jeu adaptatif,
énigmes→coffre.
- Charger / Enregistrer : import depuis / export vers un fichier .yaml local.
- Partager : publie le scénario sur la gateway et copie un lien court ?s= ;
useShareLink réimporte automatiquement le scénario au chargement du lien.
Gateway : endpoints publics sans token POST/GET /v1/share (taille plafonnée,
YAML validé), adossés à un store fichier (share-store/).
Corrige aussi l'inlining de VITE_GATEWAY_BASE_URL : accès statique
import.meta.env pour que le build prod vise la vraie gateway
(zacus.saillant.cc/api) — ce qui répare au passage le DeployPanel en prod.
Le build web prod utilise désormais un mode Vite dédié `webdeploy`
(.env.webdeploy) pour ne pas polluer le bundle desktop.
Ajoute ops/deploy-frontend.sh (typecheck → build → tar-over-ssh → reload →
vérif du hash live), le déploiement n'étant pas scripté jusqu'ici.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ajoute 10 blocs pour rendre les conditions composables (avant: chaînes
opaques tapées à la main) :
- Reporters: opCompare, opBool, opNot, opArith, valVar, valScore,
valNumber, valText → sérialisés vers la grammaire d'expression existante
(ex: "score > 5", "(pct >= 60) and (lives > 0)")
- Contrôle: loopRepeat, loopWhile (nouveau kind IR "loop")
- logicIf/sceneBranch acceptent un reporter branché OU le champ texte
(rétrocompat totale)
Catalogue 41→51 blocs, catégories Opérateurs + Contrôle. Compilateur
gateway (_reporter_to_expr) miroir du serializeReporter() TS. Hub
Blockly régénéré.
Validé: build atelier OK, 18 tests scenario-engine, round-trip
bloc→IR (reporters + loops + rétrocompat).
NB: le kind IR "loop" exige un support firmware runtime3 (à ajouter
dans une passe firmware) ; les conditions sont déjà évaluées par le
firmware existant.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diagnostic réseau electron-server (2026-06-12) : la collision 192.168.0.0/20
qui justifiait le contournement n'existe plus. Les ESP sont en LAN 10.2.5.x,
aucun réseau Docker ne capture 10.2.x, et le conteneur gateway (réseau traefik)
route vers 10.2.x via l'hôte. /v1/flash/{board} doit marcher en direct quand la
carte est sous tension. À confirmer par un flash réel puis supprimer le script.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Les guillemets typographiques servaient de pseudo-délimiteurs YAML :
les valeurs chargées contenaient littéralement “…” (endpoints LLM/TTS,
names des puzzles) et la séquence du piano valait [“L”,“E”,…] au lieu
de [L,E,F,O,U]. Conversion “”→", ‘’→', …→... ; tirets et « » français
conservés. Parse vérifié avant/après (yaml.safe_load).
Catégorie « Énigmes » dans le catalogue Blockly canonique :
zacus_scene (écran maître title/subtitle/symbol/effect),
zacus_puzzleQR et zacus_puzzleSound. L'export blocks_to_runtime3
les attache au step courant comme objets IR scene/puzzle (pas des
actions), avec clamping/troncature vers les limites strictes du
gateway pour que l'IR émis valide toujours. Copie hub régénérée
via sync_blockly_catalog.sh. 14 tests d'export ajoutés (60 verts).
Custom ESP32-WROOM-32E + Si3210 SLIC board replacing the ESP32-A1S
dev kit (final PLIP target, RJ9 handset). Generated via tools/
gen_si3210_lib.py (symbol + QFN-38 footprint), gen_schematic.py
(parses standard KiCad libs, 45 instances, 157 global labels on pin
ends) and gen_pcb.py (58x38mm outline, 41 footprints placed per the
plan, nets assigned, unrouted).
ERC: 0 violations. Schematic follows the spec GPIO map and the plan's
passive network. PCB placed not routed (Freerouting + DRC + gerbers
remain — see README). BOM in JLCPCB format; CP2102N/transformer/RJ9
LCSC parts marked TBD.
WARNINGS (README): the Si3210 -72V DC-DC stage is simplified and must
be checked against the Skyworks datasheet/AN35 before fab; line
protection is minimal; human review required before ordering.
- ConsolePane shows the ScenePlayer narration (simLog, green) under
the validation entries, plus a current-scene badge in the header.
- voice-bridge accepts rate + emotion on /tts: rate (clamped 0.5..2.0)
drives the F5 sampler speed; emotion is accepted and cache-keyed but
not rendered yet (no F5 emotion control). Legacy cache keys are
preserved when both fields are absent/default — the NPC pool
generator contract is untouched.
- Bump ESP32_ZACUS: GET/POST /game/peers (PR ESP32_ZACUS#4) — PLIP
provisioning by curl, live registration without reboot.
Verified: py_compile OK, tsc clean, vite build green, master firmware
build green.
The Run button fed blocks_studio v2 YAML to the legacy gameplay engine,
which only parses old zacus_v3 scenarios. loadScenario now tries the v2
document first and plays it through a new ScenePlayer: « Zacus dit »
drives the NPC bubble + Web Speech (rate applied, emotion mapped to the
stage mood), timers wait, goto/branch/intent jump between scenes,
hardware actions are narrated into a capped simLog. Legacy YAML still
falls back to ZacusScenarioEngine. Visualization fidelity only — the
authoritative compiler remains blocks_to_runtime3.py.
Verified: tsc clean, vite build green.
The Atelier exposed a legacy 12-block gameplay-config language whose
export the gateway could not compile (no blocks_studio_version) — and
no start/end blocks. It now speaks the same language as the zacus-hub
native Studio: the 38-block scene catalog (sceneStart/sceneEnd, npcSay
voice lines, HW/ESP-NOW/M5/PLIP, logic) lives once in
@zacus/shared/blockly; the hub copy is GENERATED via
tools/dev/sync_blockly_catalog.sh.
- Export/import rewritten to blocks_studio_version: 2 (flat nodes,
next pointers, logicIf slots) via shared blocks-doc.ts — what
POST /v1/flash compiles to Runtime 3 IR, and what the hub Studio
reads/writes (full interop).
- « Zacus dit » gains voice (voice-bridge voice_ref), emotion and rate
fields; the compiler forwards them as optional tts_say fields
(omitted at defaults, backward compatible).
- Editor validation now mirrors compiler rules: missing sceneStart,
duplicate scene ids, unknown goto targets, empty voice lines.
Verified: tsc clean, vite build green, v2->IR round-trip OK
(entry STEP_intro, tts_say{voice_ref,emotion,rate}).