Aller au contenu

Vue d'ensemble

τ-mux ouvre trois descripteurs de fichier supplémentaires pour chaque shell. Les scripts qui s’exécutent dans le terminal les utilisent pour rendre du contenu structuré (images, SVG, HTML, widgets interactifs) dans des canvas flottants — sans perturber le flux texte du terminal.

Le plan des canaux est publié dans HYPERTERM_CHANNELS au format JSON, afin que les scripts puissent s’adapter s’il change un jour. Valeurs par défaut :

fdDirectionRôleFormat
3script → terminalMétadonnées : définitions, mises à jour et effacements de panneauxJSONL
4script → terminalDonnées binaires référencées depuis fd 3octets bruts, préfixés par longueur
5terminal → scriptÉvénements : clics, glissers, redimensionnements, erreurs systèmeJSONL

La première lecture d’un script devrait être :

Fenêtre de terminal
echo "$HYPERTERM_CHANNELS"
# {"meta":3,"data":4,"events":5}

Les bibliothèques client le font automatiquement.

Pour savoir si un script s’exécute à l’intérieur de τ-mux :

Fenêtre de terminal
[ -n "$HYPERTERM_PROTOCOL_VERSION" ] && echo "inside τ-mux"

HYPERTERM_PROTOCOL_VERSION=1 est défini dans chaque shell créé dans une surface terminal. Les clients Python et TypeScript détectent cela et deviennent silencieusement des no-op en dehors de τ-mux — le même script s’exécute dans un terminal classique sans erreur.

Un objet JSON par ligne. Exemples :

{"id":"img1","type":"image","format":"png","x":100,"y":100,"byteLength":4096}
{"id":"chart","type":"svg","position":"float","width":400,"height":300,"byteLength":2048}
{"id":"widget","type":"html","interactive":true,"byteLength":512}
{"id":"img1","type":"update","x":200,"y":200}
{"id":"img1","type":"clear"}

Champs requis : id, type. L’id relie cette ligne de métadonnées à (a) toute charge utile binaire sur fd 4, (b) les futurs updates / clears, (c) les événements sur fd 5.

Lorsqu’une ligne de métadonnées contient byteLength: N, exactement N octets bruts suivent sur fd 4 — pas de framing, pas de préfixe de longueur au-delà du byteLength côté métadonnées. Le lecteur copie N octets depuis fd 4 et les associe à l’id du panneau.

Si plusieurs panneaux sont créés en succession rapide, leurs charges utiles fd 4 sont lues dans l’ordre d’émission des métadonnées.

{"id":"img1","event":"dragend","x":300,"y":400}
{"id":"img1","event":"resize","width":600,"height":400}
{"id":"widget","event":"click","x":42,"y":87}
{"id":"img1","event":"close"}
{"id":"__terminal__","event":"resize","cols":120,"rows":40}
{"id":"__system__","event":"error","code":"meta-validate","message":"Missing id"}

__terminal__ et __system__ sont des id virtuels réservés — événements de niveau terminal et erreurs de protocole.

τ-mux valide chaque ligne fd 3 avant de créer un panneau :

  • id doit être une chaîne non vide.
  • type doit être un type de contenu connu ou une opération (update, clear).
  • byteLength doit être un entier non négatif.
  • position, width, height, x, y doivent être des nombres / des enums connus.

Les lignes invalides produisent un événement d’erreur __system__ sur fd 5 — elles ne plantent pas le parseur et ne ferment pas le canal.

Les deux directions sont soumises à contre-pression au niveau du système d’exploitation. Si le script écrit sur fd 3 / 4 plus vite que τ-mux ne consomme, le script bloque sur sa prochaine write. Les bibliothèques client utilisent intentionnellement des écritures bloquantes — un O_NONBLOCK non bloquant abandonnerait silencieusement des trames.