Manuel d'instructions de cette app. À LIRE avant toute intervention, et à METTRE À JOUR après chaque modification (ajouter une ligne au CHANGELOG en bas).
Dernière génération/MAJ : 2026-09-24 · Statut : en production
/, texte inversé en miroir, défilement automatique, ligne de lecture) ; n'importe quel autre appareil (ordinateur posé à côté, tablette, 2e téléphone) ouvre la télécommande (/remote) et pilote tout à distance : script, lecture/pause, vitesse, taille, marges, interligne, miroir H/V, ligne de lecture, alignement, couleur, décompte, sauts, retour au début. Bibliothèque de scripts. L'AIOS peut aussi pousser un script directement (CLI)./root/workspace/apps/prompteur (code dans backend/)websockets), front vanilla HTML/CSS/JS (aucune dépendance, aucun build).aios-prompteur.service (fichier versionné apps/prompteur/aios-prompteur.service, installé par systemctl link, Restart=always, enabled).PROMPTEUR_PORT)/etc/nginx/sites-enabled/prompteur.panelbay.com.conf (généré par expose-webapp, Cloudflare DNS + Let's Encrypt, en-têtes Upgrade/Connection pour le WebSocket, proxy_read_timeout 120s : les clients envoient un ping toutes les 20 s).systemctl restart aios-prompteur après modification de app.py. Les pages HTML/JS sont relues à chaque requête (Cache-Control: no-store sur / et /remote), pas de restart pour le front.journalctl -u aios-prompteur -n 50.backend/app.py : serveur. Auth (code + cookie HMAC), état par salle (room), validation des patches (bornes, énumérations, clés inconnues ignorées), WebSocket /ws, REST, bibliothèque, persistance, en-têtes de sécurité.backend/static/index.html : l'ÉCRAN. Défilement par translateY en requestAnimationFrame (px/s = vitesse / 25 × hauteur de ligne, donc une vitesse donnée = même rythme de lecture quelle que soit la taille), miroir par transform: scale(-1, 1) sur le conteneur, paddings calculés pour que la 1re et la dernière ligne puissent se poser sur la ligne de lecture, décompte 3-2-1 mirroré, gestes (toucher = lecture/pause, glisser = déplacer le texte), feuille de réglages locale (⚙), wake lock (écran allumé), plein écran, manifest PWA (« Sur l'écran d'accueil » sur iPhone = vrai plein écran).backend/static/remote.html : la TÉLÉCOMMANDE. Transport, curseurs (envoi limité à 1 message / 60 ms pendant le glisser), toggles, éditeur de script + bibliothèque, aperçu qui suit la position de l'écran, raccourcis clavier, mobile-first.backend/static/common.js : partagé (salle depuis ?room=, appels API, rendu du texte en paragraphes via textContent uniquement, overlay de login, client WebSocket avec reconnexion et battement).backend/static/manifest.webmanifest, icon-180/192/512.png : PWA / icône écran d'accueil.backend/cli.py : CLI pour l'AIOS (voir §5).aios-prompteur.service : unité systemd./root/aios/data/prompteur/ (hors workspace) : state.json (état de chaque salle, sauvegarde différée, jamais playing: true au démarrage), scripts.json (bibliothèque, max 200 scripts de 200 000 caractères), access_code (chmod 600).room, défaut studio, ?room=xxx sur les deux pages pour en isoler une autre) = un état : title, text, speed 1-100, fontSize 20-160 px, lineHeight 1.0-2.2, margin 0-30 %, mirrorH, mirrorV, align center|left, color white|yellow|green|cyan, guide, guidePos 10-80 %, countdown 0-10 s, playing, position 0-1, seq. L'écran est l'autorité sur position (il la remonte 4×/s en lecture) ; le serveur est l'autorité sur tout le reste. Nouveau texte = position 0 + pause.{t:"set", patch}, {t:"cmd", cmd: play|pause|toggle|restart|seek|jump, value}, {t:"pos", position, ended} (écran seulement), {t:"ping"} ; serveur → {t:"state", state, seek, origin, presence}, {t:"pos"} (télécommandes), {t:"cmd", cmd:"jump"} (écrans), {t:"presence"}, {t:"pong"}. Sans auth : fermeture code 4401 (le front affiche le login).GET / écran · GET /remote télécommande · GET /api/health (sans auth) · GET /manifest.webmanifest · /static/*.POST /api/login {code} (pose le cookie prompteur_auth, anti brute-force 8 échecs / 15 min par IP) · POST /api/logout · GET /api/me.X-Prompteur-Code) : GET /api/state?room= · POST /api/state?room= {patch:{...}, cmd, value} · GET /api/scripts · POST /api/scripts {title,text} · GET|PUT|DELETE /api/scripts/{id} · POST /api/scripts/{id}/load?room= (envoie le script à l'écran) · WS /ws?room=&role=display|remote.cd /root/workspace/apps/prompteur/backend) :```bash
python3 cli.py load workspace/mon-script.md --title "Intro vidéo" # envoie un fichier à l'écran (repart du début)
python3 cli.py text "Le texte..." --title "..." # idem inline
python3 cli.py play | pause | restart | jump -3 # transport
python3 cli.py set --speed 18 --font 60 --mirror on --align left # réglages (--help pour tout)
python3 cli.py state | scripts | save fichier.txt --title "..." # état, bibliothèque
```
Utile quand Matt demande « mets ce script dans le prompteur » : écrire le script puis cli.py load.
/root/aios/data/prompteur/access_code (généré au 1er lancement), ou surchargé par PROMPTEUR_ACCESS_CODE dans le fichier d'environnement AIOS. Le changer = redémarrer le service (toutes les sessions sont invalidées, chaque appareil ressaisit le code). Ne jamais citer le code dans un fichier du workspace.mirrorH est ON par défaut (rig à miroir : le texte apparaît inversé sur le téléphone, à l'endroit dans le miroir). Pour lire directement sur l'écran (sans miroir), désactiver « Miroir horizontal » depuis la télécommande ou la feuille ⚙. mirrorV sert si le téléphone est monté à l'envers.requestFullscreen ; l'ajout à l'écran d'accueil (manifest standalone) donne un vrai plein écran. Le wake lock (écran qui ne s'éteint pas) exige HTTPS : OK via l'URL publique, pas en http local.playwright avec --no-sandbox (script de référence utilisé à la création : /root/aios/.tmp/prompteur/browser_test.py, disposable).prompteur.panelbay.com (curl 000 depuis le VPS juste après création) ; depuis l'extérieur c'est immédiat. Tester en local avec curl --resolve prompteur.panelbay.com:443:127.0.0.1 ....aios-prompteur (8371), exposé sur https://prompteur.panelbay.com (Cloudflare + Let's Encrypt). Tests : protocole WebSocket/REST (script Python) + navigateur réel Chromium (écran 844×390 + télécommande desktop/mobile) OK. Script d'exemple « Exemple : intro vidéo immo » chargé et enregistré dans la bibliothèque.