
La pàgina de login ÉS la demo
GeekBye v1.7.5 va afegir una captura de pantalla del producte a la pàgina de login i la va esborrar el mateix dia — per reconstruir-la com a components reals. A més: l'usuari que era més ràpid que l'OCR, i com són de debò 25 commits d'estil en un sol dia.
GeekBye v1.7.5 és una release d'una setmana amb doble personalitat: 37 commits, dels quals 28 són un redisseny de la pàgina de login — i 25 d'aquests són micro-retocs style(login), tots aterrats en un sol dia. També és la release que va arreglar una de les races més instructives de la base de codi. Totes dues històries valen la pena, i es troben en la mateixa idea: la pàgina de login és el primer que veu un usuari sense autenticar, així que més val que sigui el producte, no una foto del producte.
Una captura de pantalla, durant unes cinc hores
El redisseny va començar de manera convencional. Reestructurar a dues columnes, posar el sign-in a l'esquerra i mostrar el producte a la dreta — com a imatge. Els commits de mig matí fan exactament això: a les 11:57 aterra al repo una captura de previsualització real, un PNG de 114 KB, que s'actualitza una vegada sis minuts després.
A les 17:04 ja no hi era. El commit del gir substitueix la imatge estàtica per 344 línies de components reals — un panell LoginDemo muntat amb vuit peces petites que repliquen la UI d'overlay real: la píndola de navegació de gravació amb les seves barres d'EQ pulsants i el botó d'aturar, el panell de xat amb les pestanyes Chat/Transcript, una resposta de l'assistent renderitzada (explicant el useEffect de React, apropiadament), les accions ràpides "Tell me more / Simplify / Show example", la fila de prompts en directe i l'entrada Assist ⌘⏎.
Siguem precisos amb la paraula "demo", perquè és fàcil exagerar: els botons tenen hover states reals — brillantors, reflexos, transicions — però res no està cablejat per fer clic, i l'entrada és de només lectura. No és un sandbox. El que sí que és, és el vocabulari d'UI real del producte renderitzat en viu: el mateix asset del logotip, el mateix tractament de gradient-border i backdrop-blur, el mateix import de productName que fa servir el sistema white-label — de manera que la demo es rebrandeja automàticament per a cada producte construït des d'aquesta base de codi. Una captura de pantalla no pot fer res d'això. Una captura queda desfasada el dia que la fas, es veu borrosa a la pantalla equivocada i queda marcada per sempre amb el producte que casualment vas capturar. Els components són nítids a qualsevol DPI, sempre actuals i correctes per a cada marca — perquè no són una foto del design system, són el design system.
El PNG esborrat, per cert, encara és al repo al tag de la release — orfe, sense cap referència. Cada base de codi arrossega alguns fòssils de l'enfocament que va perdre.
Com són 25 commits d'estil en un sol dia
El registre de commits d'aquell únic dia és el quadern d'esbossos d'un dissenyador, conservat amb una honestedat inusual. La proporció de columnes va passar de 40/60 a 45/55. Una etiqueta "Works with" sobre els logotips de plataformes es va afegir al migdia, es va recol·locar i es va treure — va viure aproximadament mig dia. La fila de logotips de plataformes en si (Google Meet, Teams, Zoom, Slack, Webex), afegida a les 10:59 del matí, es va esborrar del tot a les 22:08 d'aquella nit. I el footer va necessitar una saga de quatre enfocaments per alinear-se: un únic contenidor wrapper, després treure les classes de centrat, després centrat amb flexbox, després simplement acostar-lo una mica més al fons.
Seria fàcil llegir-ho com a churn. Nosaltres ho llegim com la forma real de la feina de disseny: convergeixes renderitzant, mirant i ajustant — i fer-ho en 25 commits petits en lloc d'un sol "redesign login page" aixafat vol dir que la cerca mateixa queda registrada. Quan algú pregunta "no vam provar una fila de logotips una vegada?", la resposta és a l'historial, amb marques de temps.
L'usuari que era més ràpid que l'OCR
La història d'enginyeria de la release va passar cinc dies abans, en una cadena de fixes de tres commits. Des de la v1.5.12, prémer Cmd+H encua una captura de pantalla amb feedback instantani: la miniatura apareix a la cua immediatament, i l'extracció de text — OCR local d'Apple Vision, aproximadament un o dos segons — corre en segon pla. L'esdeveniment de cua s'envia literalment amb ocrText: '' i un comentari que promet que s'omplirà més tard.
És una bona optimització, i va encunyar una race. Un usuari ràpid prem Cmd+H i envia la seva pregunta immediatament. El camp de text de la captura encara és buit. La petició surt sense contingut de pantalla, i el model respon — amb veracitat, exasperantment — "I cannot see images." El camí ingenu no fallava amb un error; fallava amb una resposta correcta a la pregunta equivocada, que és la manera més confusa que té el programari de fallar.
El fix bloqueja el camí d'enviament sobre la feina async que l'optimització havia ajornat: si alguna captura encuada encara té el text d'OCR buit, la petició s'aparca i la UI mostra un indicador "Reading screen..."; un useEffect es dispara en el moment que arriba el text i envia la petició amb tot el contingut extret. Dos detalls específics de React al diff valen la pena de robar: la cua de captures es reflecteix en una ref que se sincronitza durant el render, perquè la cadena de closures dels handlers d'esdeveniments capturava estat obsolet; i la petició aparcada s'envia directament en lloc de passar pel hook genèric de peticions encuades, pel mateix motiu de stale closure.
I hi ha una arruga honesta registrada al mateix missatge de commit: els logs de traça afegits per caçar aquesta race van revelar un segon bug al backend — l'assemblatge del prompt descartava del tot el text de la captura en un dels camins de codi. Un símptoma, dos bugs, trobats instrumentant tota la cadena i mirant on desapareixia el text. La cadena va acabar amb una decisió de producte, nou minuts després del fix de la race: Cmd+H encua captures per a anàlisi en lot, mentre que Cmd+Enter sempre fa una captura fresca de la pantalla actual — dos fluxos de treball diferenciats en lloc d'un d'ambigu. (El que fa realment l'Assist de Cmd+Enter és un post a part: ajuda d'IA instantània sobre el que estàs mirant.)
Una petita coda de la mateixa setmana, per als lectors del capítol de white-label: el User-Agent Product/version (platform) va rebre un fix per al mode dev, perquè app.getVersion() a Electron sense empaquetar retorna la versió d'Electron, no la del producte. Les cadenes d'identitat, com sempre, es filtren per les canonades.
Tres coses que aquesta release ens va ensenyar
- Renderitza el producte, no el fotografiïs. Una demo de pàgina de login construïda amb components reals es rebrandeja sola, sobreviu a qualsevol densitat de pantalla i no pot quedar desfasada. L'enfocament de la captura es va provar i esborrar dins d'un mateix dia laborable — experiment barat, veredicte clar.
- Cada optimització async necessita un bloqueig al punt d'ús. "Feedback instantani amb el text d'OCR buit" era la decisió d'UX correcta, però el camí d'enviament havia d'aprendre a esperar el que l'optimització havia ajornat. Si ajornes feina, troba cada consumidor del seu resultat i ensenya-li la diferència entre "buit" i "encara no llest".
- Instrumenta la cadena, no el sospitós. Els logs de traça van seguir el text de la captura de punta a punta — del handler de la drecera a l'IPC al client d'API — i per això una sola investigació va tancar dos bugs, un d'ells a l'altra banda de la xarxa.
Per al capítol anterior de la història de la v1, reunions que realment pots tornar a trobar (v1.7.3); i per a tot l'arc, l'anatomia de publicar programari fins a la perfecció.