
La page de login EST la démo
GeekBye v1.7.5 a ajouté une capture d'écran du produit sur la page de login et l'a supprimée le jour même — pour la reconstruire en vrais composants. En prime : l'utilisateur plus rapide que l'OCR, et à quoi ressemblent vraiment 25 commits de style en une seule journée.
GeekBye v1.7.5 est une release d'une semaine à la personnalité double : 37 commits, dont 28 sont une refonte de la page de login — et 25 de ceux-là sont des micro-retouches style(login), toutes atterries en une seule journée. C'est aussi la release qui a corrigé l'une des courses les plus instructives de la base de code. Les deux histoires méritent d'être racontées, et elles se rejoignent sur la même idée : la page de login est la première chose que voit un utilisateur non authentifié, alors elle a intérêt à être le produit, pas une photo du produit.
Une capture d'écran, pendant environ cinq heures
La refonte a commencé de façon conventionnelle. Restructurer en deux colonnes, mettre la connexion à gauche, et montrer le produit à droite — sous forme d'image. Les commits de fin de matinée font exactement ça : à 11:57, une vraie capture d'aperçu atterrit dans le dépôt, un PNG de 114 KB, mis à jour une fois six minutes plus tard.
À 17:04, elle avait disparu. Le commit du pivot remplace l'image statique par 344 lignes de vrais composants — un panneau LoginDemo assemblé à partir de huit petites pièces qui répliquent la vraie UI de l'overlay : la pilule de navigation d'enregistrement avec ses barres d'EQ pulsantes et son bouton stop, le panneau de chat avec les onglets Chat/Transcript, une réponse d'assistant rendue (expliquant le useEffect de React, comme par hasard), les actions rapides "Tell me more / Simplify / Show example" (en dire plus / simplifier / montrer un exemple), la rangée de prompts en direct et le champ Assist ⌘⏎.
Soyons précis sur le mot « démo », parce qu'il est facile d'en dire trop : les boutons ont de vrais états hover — lueurs, reflets, transitions — mais rien n'est câblé au clic, et le champ de saisie est en lecture seule. Ce n'est pas un bac à sable. Ce que c'est, c'est le vrai vocabulaire UI du produit rendu en direct : le même asset de logo, le même traitement bordure dégradée et backdrop-blur, le même import productName qu'utilise le système white-label — si bien que la démo se rebrande automatiquement pour chaque produit construit depuis cette base de code. Une capture d'écran ne sait rien faire de tout ça. Une capture est périmée le jour où vous la prenez, floue sur le mauvais écran, et marquée à jamais du produit que vous avez capturé par hasard. Les composants sont nets à n'importe quel DPI, toujours à jour, et corrects pour chaque marque — parce qu'ils ne sont pas une photo du design system, ils sont le design system.
Le PNG supprimé, soit dit en passant, est toujours dans le dépôt au tag de la release — orphelin, référencé par rien. Toute base de code transporte quelques fossiles de l'approche qui a perdu.
À quoi ressemblent 25 commits de style en une journée
Le log de commits de cette seule journée est un carnet de croquis de designer, conservé avec une honnêteté inhabituelle. Le ratio des colonnes est passé à 40/60, puis 45/55. Un libellé "Works with" (fonctionne avec) au-dessus des logos de plateformes a été ajouté à midi, repositionné, puis retiré — il a vécu environ une demi-journée. La rangée de logos de plateformes elle-même (Google Meet, Teams, Zoom, Slack, Webex), ajoutée à 10:59 le matin, a été supprimée entièrement à 22:08 le soir même. Et le footer a demandé une saga en quatre approches pour s'aligner : un seul conteneur wrapper, puis le retrait des classes de centrage, puis un centrage flexbox, puis simplement le pousser un peu plus près du bas.
Il serait facile de lire ça comme du churn. Nous, nous y lisons la vraie forme du travail de design : on converge en rendant, en regardant, en ajustant — et le faire en 25 petits commits plutôt qu'en un seul « redesign login page » écrasé signifie que la recherche elle-même est consignée. Quand quelqu'un demande « on n'avait pas essayé une rangée de logos, une fois ? », la réponse est dans l'historique, avec les timestamps.
L'utilisateur plus rapide que l'OCR
L'histoire d'ingénierie de la release s'est jouée cinq jours plus tôt, dans une chaîne de correctifs en trois commits. Depuis v1.5.12, appuyer sur Cmd+H met une capture en file avec un retour instantané : la miniature apparaît immédiatement dans la file, et l'extraction de texte — OCR local Apple Vision, environ une à deux secondes — tourne en arrière-plan. L'événement de mise en file part littéralement avec ocrText: '' et un commentaire promettant qu'il se remplira plus tard.
C'est une bonne optimisation, et elle a frappé une course. Un utilisateur rapide appuie sur Cmd+H et envoie immédiatement sa question. Le champ texte de la capture est encore vide. La requête part sans contenu d'écran, et le modèle répond — véridiquement, exaspérément — "I cannot see images" (je ne peux pas voir d'images). Le chemin naïf n'a pas échoué avec une erreur ; il a échoué avec une réponse correcte à la mauvaise question, ce qui est la façon la plus déroutante dont un logiciel peut échouer.
Le correctif bloque le chemin d'envoi sur le travail asynchrone que l'optimisation avait différé : si une capture en file a encore un texte OCR vide, la requête se met en attente et l'UI affiche un indicateur "Reading screen..." (lecture de l'écran) ; un useEffect se déclenche à l'instant où le texte arrive et envoie la requête avec le contenu extrait complet. Deux détails spécifiques à React dans le diff valent la peine d'être volés : la file de captures est reflétée dans une ref synchronisée pendant le rendu, parce que la chaîne de closures du gestionnaire d'événements capturait un état périmé ; et la requête en attente est envoyée directement plutôt qu'à travers le hook générique de requêtes en file, pour la même raison de stale closure.
Et il y a un pli honnête consigné directement dans le message de commit : les logs de traçage ajoutés pour traquer cette course ont révélé un second bug côté backend — l'assemblage du prompt laissait tomber entièrement le texte de la capture dans un des chemins de code. Un symptôme, deux bugs, trouvés en instrumentant toute la chaîne et en regardant où le texte disparaissait. La chaîne s'est terminée par une décision produit, neuf minutes après le correctif de la course : Cmd+H met les captures en file pour une analyse par lot, tandis que Cmd+Enter prend toujours une capture fraîche de l'écran courant — deux workflows distincts au lieu d'un seul ambigu. (Ce que fait vraiment l'Assist de Cmd+Enter est un billet à part : de l'aide IA instantanée sur ce que vous regardez.)
Une petite coda de la même semaine, pour les lecteurs du chapitre white-label : le User-Agent Product/version (platform) a reçu un correctif pour le mode dev, parce que app.getVersion() dans un Electron non packagé renvoie la version d'Electron, pas celle du produit. Les chaînes d'identité, comme toujours, fuient dans la tuyauterie.
Trois choses que cette release nous a apprises
- Rendez le produit, ne le photographiez pas. Une démo de page de login construite avec de vrais composants se rebrande automatiquement, survit à toutes les densités d'écran et ne peut pas se périmer. L'approche capture d'écran a été essayée et supprimée dans la même journée de travail — expérience bon marché, verdict clair.
- Chaque optimisation asynchrone a besoin d'un verrou au point d'usage. « Retour instantané avec texte OCR vide » était le bon choix d'UX, mais le chemin d'envoi a dû apprendre à attendre ce que l'optimisation avait différé. Si vous différez du travail, trouvez chaque consommateur de son résultat et apprenez-lui la différence entre « vide » et « pas encore prêt ».
- Instrumentez la chaîne, pas le suspect. Les logs de traçage ont suivi le texte de la capture de bout en bout — du gestionnaire de raccourci à l'IPC au client API — et c'est pour ça qu'une seule enquête a clos deux bugs, dont un de l'autre côté du réseau.
Pour le chapitre précédent de l'histoire v1, des réunions qu'on retrouve enfin (v1.7.3) ; et pour tout l'arc, l'anatomie de livrer un logiciel jusqu'à la perfection.