Files
Antigravity 69c99e4f4f feat: page interactive, démos Play/Step et simulateur Carnot
Ajoute le pipeline PageSpec (validation, rendu, publication /p/{slug}),
les démos TipTap /demo, et le simulateur Carnot (modes frigo/PAC/moteur,
énergie kJ vs puissance W, unités K/°C/°F) avec correctifs d’équations KaTeX.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 17:51:43 +00:00
..

Simulateurs interactifs (plugins)

Bibliothèque de simulateurs pédagogiques pour les pages interactives (/p/{slug}). L'IA ne code jamais une simulation : elle choisit un simulateur de cette liste et le configure (preset = valeurs de la note), ou utilise generic-formula si aucun ne correspond au sujet.

Liste des simulateurs disponibles

simId Famille Sujet Interaction
carnot-cycle sim Machine frigorifique / PAC / moteur de Carnot (2ᵉ principe) Curseurs T_c, T_h, Q_c → COP, η, W min, Q_h en direct
carnot-cycle-anim anim Cycle de Carnot animé (piston + diagramme PV live, 5 étapes) Play / Pause / Step / Reset / vitesse + narration
generic-formula sim (générique) toute relation chiffrée y = f(paramètres) Curseurs définis par l'IA, expressions sûres (aucun eval)

Deux familles de plugins : sim (manipulation de paramètres, calcul en direct) et anim (scène animée codée en dur, pilotée par le player Play/Step — narration par battements). Les deux sont choisis par l'IA via le même bloc { "type": "sim" }.

Comment l'IA les utilise

  1. Le prompt de génération de section injecte catalogForPrompt(lang) (registry.ts) — id + résumé + mots-clés + bornes de chaque simulateur.
  2. Si le contenu de la note correspond (keywords), l'IA émet { "type": "sim", "sim": { "simId": "carnot-cycle", "preset": { "t_hot": 300 } } }.
  3. validateInteractivePage vérifie : simId connu, preset dans les bornes, compute(preset) fini — sinon rejet (renvoyé au LLM ou fallback).

Ajouter un plugin (5 étapes)

Pour un sim (curseurs) :

  1. lib/simulators/<id>.ts — implémenter SimulatorPlugin (family: 'sim') : id, title/summary fr+en (le summary sert au matching IA), keywords, params (curseurs : bornes, pas, défaut, unité, intent), outputs (symbole KaTeX, unité), et compute(env) pur et déterministe.
  2. lib/simulators/index.ts — ajouter au REGISTRY.
  3. components/simulators/<id>-view.tsx — composant sur mesure (props : preset, title, disclaimer, lang). Réutiliser SimSlider / SimOutputCard / SimHeading / SimKaTeX de sim-controls.tsx.
  4. components/simulators/index.ts — enregistrer dans SIMULATOR_VIEWS.
  5. Vérifier : compute fini aux valeurs par défaut, npx tsc --noEmit, tester sur /dev/interactive-page.

Pour une anim (scène animée Play/Step) :

  1. lib/simulators/<id>.ts — implémenter AnimPlugin (family: 'anim') : id, title/summary fr+en, keywords, disclaimer?, beats (narration fr+en par étape — KaTeX inline $…$ dans speak).
  2. lib/simulators/index.ts — ajouter au REGISTRY.
  3. components/simulators/<id>-anim-view.tsx — scène SVG/React pilotée par step (props : step, lang). Transitions CSS sur transform/opacity uniquement. Le chrome (Play/Pause/Step/Reset/vitesse + panneau de narration + clavier Espace/←/→/R) est fourni par AnimPlayerShell — ne pas le réécrire.
  4. components/simulators/index.ts — enregistrer dans ANIM_VIEWS.
  5. Vérifier : chaque step rend un état cohérent (y compris état final sans JS), npx tsc --noEmit, tester sur /dev/interactive-page.

Règles : pas de couleurs en dur (intents / tokens --pp-*), labels fr+en dans le plugin, tout calcul côté compute ou scène codée (jamais de logique LLM), SSR = état lisible sans JS.