Audits · septembre 2026Chrome du Builder : carte, doublons, et ou chaque piece est allee

Chrome du Builder : carte, doublons, et ou chaque piece est allee

2026-09-26. Demande : Mirror doit vivre DANS le Builder (pas comme un mode de la scene), en reutilisant ce que le Builder a deja, et le chrome du Builder est « un bordel » : supprimer l'en-tete du haut, et une barre…

2026-09-26. Demande : Mirror doit vivre DANS le Builder (pas comme un mode de la scene), en reutilisant ce que le Builder a deja, et le chrome du Builder est « un bordel » : supprimer l'en-tete du haut, et une barre d'outils flottante comme celle du composer ou le zoom du canvas Workflow. Decision : ADR 0045.

1. Ce qu'il y avait a l'ecran (avant)

De haut en bas, en mode Builder (?mode=builder), sous l'en-tete global et la barre centrale du shell (le stepper Preview → Builder → Workflow → Studio → Mirror) :

#ElementFichierCe qu'il faisait
ALigne d'en-tete, 56 pxupstream/.../_components/top-bar/index.tsx (TopBar, sur WorkbenchToolbar)Titre « Builder / Visual edit », Annuler / Retablir au centre, Selection / Main au centre, niveau de zoom a droite
BPopover de zoomupstream/.../design-panel/zoom-controls/index.tsxBouton « 100% », popover : champ libre, zoom +, zoom -, ajuster, 100 %, 200 %
CBarre de style, 44 pxupstream/.../editor-bar/index.tsxRangee DOCKEE sous A, visible seulement quand un element ou un cadre est selectionne : les controles de style de DivSelected
DRail d'activite, 44 pxupstream/.../design-panel/index.tsx (DesignPanel)Trois boutons : Calques, Pages, « Library ». aria-label="Builder panels" en anglais en dur, infobulles title natives
EPanneau lateral, 256 pxmeme fichierEn-tete de 36 px (libelle du panneau), puis LayersTab, PagesTab scope="pages" ou PagesTab scope="library"
FAiguillage gaucheupstream/.../left-panel/index.tsx (LeftPanel)D + E en mode design / main, CodePanel en mode code
GCanevasupstream/.../canvas/**Les cadres (chacun avec sa propre barre de cadre : page, lien externe), overlays, bouton « recentrer »
HMesure des panneauxupstream/.../_hooks/use-panel-measure.tsxMesurait la largeur des panneaux gauche / droit. Son resultat n'etait lu par personne

Et Mirror, un AUTRE mode de la scene (?mode=mirror), avec son propre chrome :

#ElementFichierCe qu'il faisait
M1Ligne d'en-tete, 56 pxsrc/features/ai/preview/mirror/mirror-pane.tsx (WorkbenchToolbar)Titre « Mirror / hote », champ URL + Charger, Selection / parent / enfant, Bureau / Mobile, Capturer
M2Bande d'onglets, 36 pxmeme fichierSource / Resultat, apparue apres compilation
M3Colonne droite, 320 pxmeme fichierSelection + « Ask @Atlas », options (nom, texte, droits), Construire, rapport, telechargement, choix du theme brouillon, Installer
M4Stagememe fichierCadre sandbox="allow-scripts" du snapshot, cadre sandbox="" du resultat
M5Etape du steppersrc/config/dashboard-nav.tsCinquieme etape, ?mode=mirror

2. Les doublons

  1. Le titre de A repetait « Builder » une ligne sous le stepper qui le disait deja. M1 faisait pareil pour « Mirror ». Deux lignes de 56 px dont la moitie gauche ne portait aucune information.
  2. Deux barres d'outils du meme grammaire pour une seule tache (A et M1), dans deux modes voisins : trouver une section, puis la travailler.
  3. Deux colonnes laterales : E a gauche pour le Builder, M3 a droite pour Mirror, avec deux vocabulaires (Onlook d'un cote, pilules faites main de l'autre).
  4. Deux choix de theme : le Builder edite le premier theme non live (pickThemeId de builder-frame et builder-library), Mirror proposait sa propre liste de brouillons. Une section installee dans un autre brouillon n'apparaissait pas dans la Bibliotheque qu'on regardait.
  5. Trois rangees empilees au-dessus du canevas quand un element etait selectionne (A + C sous la barre du shell) : environ 100 px de chrome avant le premier pixel du cadre.
  6. Deux zooms : le popover B et les raccourcis clavier du canevas, qui ne partageaient pas la meme fonction.
  7. Un calcul mort (H), appele a chaque rendu, jamais lu.
  8. Pages et « Library » sont deux vues filtrees du MEME arbre builder-library : ce n'est pas un doublon a supprimer (l'une compose des pages, l'autre des pieces), mais le nom « Library » ne disait pas ce qu'on y trouve. Il devient « Sections ».

3. Le layout cible (livre)

┌──────┬──────────────┬────────────────────────────────┬─────────────┐
│ rail │ onglet ouvert│                                │ inspecteur  │
│ Cal. │ Calques      │                                │ (sur une    │
│ Pag. │ Pages        │  canevas Onlook / stage Mirror │ selection)  │
│ Sec. │ Sections     │                                │ Ask @Atlas  │
│ Mir. │ Mirror       │  ╰ UNE barre d'outils flottante╯│ Couleurs...│
└──────┴──────────────┴────────────────────────────────┴─────────────┘
  • Plus d'en-tete. A et M1 sont supprimes. Le canevas commence sous la barre du shell.
  • Une barre d'outils flottante, en bas au centre du stage, construite sur patterns/workbench-toolbar (la famille que la barre du Workflow utilise deja), dans sa forme flottante WorkbenchFloatingToolbar (Toolbar.Root de Base UI : un seul arret de tabulation, fleches entre les boutons, role="toolbar" nomme). Deux faces, jamais les deux :
    • canevas : Annuler / Retablir · Selection / Main · zoom - / niveau (clic = 100 %) / zoom + / ajuster · « Importer une section » ;
    • Mirror : retour au canevas · selection / parent / enfant · Bureau / Mobile · Source / Resultat (apres compilation) · Capturer.
  • Un panneau lateral, docke a gauche comme un IDE : rail de quatre onglets (Calques, Pages, Sections, Mirror) et l'onglet ouvert, avec un bouton fermer. Traduit dans les six langues, PanelIconButton et PanelSectionLabel, sous DARK_CARD_SCOPE. Le mode code d'Onlook, qui remplacait l'onglet, est retire depuis (ai-platform/3052) : « voir le code » ouvre le Worktree.
  • Les styles sont un inspecteur a droite (livre ensuite, voir la section 7). La barre de style qui flottait en haut du stage est supprimee : rien ne couvre plus le haut du canevas.
  • Mirror est un onglet. Le stage montre alors la page source (meme cadre isole, meme route, meme CSP) ; le canevas reste monte, cache et inert. L'installation vise le theme que le Builder edite, puis ouvre la section dans l'onglet Sections et sur le canevas.
  • Un inspecteur a droite, pas la barre deplacee. DivSelected repliait ses groupes par largeur ; posee dans une colonne de 280 px elle aurait tout replie dans son menu. La mise en page a donc ete reecrite en sections verticales, les ecritures non (section 7).

4. Ou chaque piece est allee

AvantApres
A TopBar (supprime)Annuler / Retablir, Selection / Main : face canevas de chrome/builder-toolbar.tsx
B ZoomControls (supprime)zoom -, niveau, zoom +, ajuster dans la meme barre ; la mise a l'echelle « ajuster » est reprise dans Main (zoomToFit)
C barre de style dockeed'abord flottante en haut du stage, puis supprimee : chrome/inspector/builder-inspector.tsx, colonne droite (section 7)
D + E DesignPanel (supprime)chrome/builder-side-panel.tsx
F LeftPanel (supprime)builder-side-panel.tsx (onglets ; le panneau de code est retire par ai-platform/3052)
H use-panel-measure (supprime)rien : son resultat n'etait pas lu
M1 en-tete Mirror (supprime)face Mirror de la barre flottante ; le champ URL est dans l'onglet
M2 bande Source / Resultatdeux boutons de la face Mirror
M3 colonne droitechrome/mirror/mirror-panel.tsx, onglet Mirror du panneau gauche
M4 stagechrome/mirror/mirror-stage.tsx
M5 etape du stepper (supprimee)« Importer une section » et l'onglet Mirror ; ?mode=mirror ouvre le Builder sur l'onglet
etat du pane (un composant de 630 lignes)chrome/mirror/use-mirror-session.ts, partage par l'onglet, le stage et la barre
choix de brouillonle theme du Builder : builder-library renvoie theme, meme regle (pickBuilderTheme) que builder-frame

5. La couture avec le code vendore

Le chrome est du code BoostEcom (src/features/ai/onlook/chrome/), type, linte et traduit ; le moteur reste celui d'Onlook, vendore en @ts-nocheck. Un seul fichier vendore les relie, Main : il lit le moteur MobX (historique, outil, zoom, onglet ouvert, theme resolu) dans un objet BuilderControls et passe les vues d'Onlook au chrome comme des slots.

Deux catalogues de traduction cohabitent : les vues d'Onlook lisent le leur (anglais, leurs cles), le chrome lit le notre. chrome/intl-bridge.tsx capture la configuration de l'application avant que le fournisseur d'Onlook ne l'occulte, et chaque sous-arbre dit laquelle il parle (AppIntl, OnlookIntl).

6. Hors perimetre, suivi en backlog (depuis livre)

  • Le Builder n'editait pas le theme choisi dans la Preview. Livre (ai-platform/3054) : ModeView passe previewThemeId au Builder, chaque requete builder-frame / builder-library porte ?themeId= (src/features/ai/onlook/builder-theme.ts), et pickBuilderTheme le retient s'il n'est pas live.
  • Le zoom du canvas Workflow est encore le Controls de React Flow, style par workflow-v2.css, pas WorkbenchFloatingToolbar.
  • Le mode code d'Onlook doublait le Worktree. Retire (ai-platform/3052) : plus de CodePanel ni de slot code ; « voir le code » (clic droit, bouton du survol, double clic, mod+2) ouvre le Worktree sur le fichier (src/features/ai/onlook/builder-code.ts).
  • La visibilite mobile dans l'inspecteur. Livre (ai-platform/3055) : voir la section 7.

7. L'inspecteur (livre, ai-platform/3053)

Approuve par le proprietaire le 2026-09-26. Une colonne de 288 px a droite du stage, montee seulement quand un element est selectionne en mode design ; elle se ferme a la deselection (clic dans le vide, Echap sur le canevas par le raccourci d'Onlook, Echap dans un champ ou la croix, qui rendent le focus au canevas). Masquee quand l'onglet Mirror occupe le stage.

De haut en bas, dans l'ordre d'un marchand :

SectionControlesEcriture (inchangee)
Ask @Atlaschamp + envoyerattachSelectedElement (le meme que le menu contextuel, donc attachBuilderSelection), puis boostecom:chat-prompt
Contenu« Modifier le texte sur le canevas » (texte), indication (image)text.editSelectedElement
Couleurstexte, fond : couleurs de marque d'abord, puis couleur libreuseColorUpdate.handleColorUpdateEnd
Typographiepolice (lecture), taille, graisse, interligne, espacement, alignementuseTextControl, style.update
Espacementmarge interieure, marge exterieure : tous les cotes ou un seuluseBoxControl.handleBoxChange / handleIndividualChange
Dispositiondirection, repartition, alignement, ecart (en flex seulement)style.update
Avance (repliable)affichage, largeur, hauteur, bordure, couleur de bordure, arrondistyle.update

La couture suit celle de Main : upstream/.../_components/inspector-bridge.tsx (vendore) lit la selection dans un InspectorModel type (chrome/types.ts) et branche chaque action sur les hooks d'Onlook ; la colonne (chrome/inspector/) ne touche jamais le moteur, ce que src/test/builder-inspector-replaces-the-style-bar.test.ts verifie. Un champ valide sur Entree ou a la sortie, jamais a la frappe : une modification = une entree d'historique.

Depuis ai-platform/3055, trois lignes s'ajoutent, par les MEMES ecritures :

SectionControlesEcriture
Couleursimage de fond : images deja affichees par la page, ou URL https ; retirerstyle.update('backgroundImage')
Typographiepolice : familles du theme, celles du kit de marque en tetestyle.update('fontFamily')
Visibilitemasquer sur mobile, masquer sur ordinateur (une section de theme)getUpdateStyleAction + action.run, l'etat sauve en original
Avanceopacite, en %style.update('opacity')

La visibilite ne pose jamais display: none sur l'element : cssFromStyleDraft en fait une regle sous @media (750 px, le point de rupture de Dawn) dans assets/boostecom-builder.css, qui vise aussi l'enveloppe shopify-section-… de la boutique. Seule une section en a une : un enfant est estampille par le Builder et n'existe pas pour un acheteur, donc l'inspecteur ne lui propose pas l'interrupteur. Dans l'editeur, l'element est estompe au lieu d'etre cache, pour rester selectionnable.

Ecart qui reste : le remplacement d'une balise img passe par @Atlas. Une police du kit de marque que le theme ne charge pas n'est pas proposee : l'ecrire rendrait la police de repli.

8. Les etats (livre, ai-platform/3069)

Le meme jour, le Builder paraissait vide. Diagnostic et preuves : 2026-09-26-builder-empty.md. Ce que le chrome a gagne :

PieceAvantApres
Onglets Pages et SectionsPagesTab d'Onlook (slot), anglais, « Create a new page » sans bac a sablechrome/library/builder-library-panel.tsx, traduit, sur la reponse de builder-library (status, source)
Onglet Calquesle LayersTab seul, vide sans explicationchrome/frames/builder-layers-panel.tsx : squelette, raison et correctif, puis l'arbre sous le nom de sa page
Canevasblanc tant que les cadres chargent, fausse section en cas d'echecchrome/canvas/builder-canvas-status.tsx : bloqueur centre (Shopify, portee, theme), squelette de page, carte d'etat en bas a gauche
Onglet Mirrorune colonne, « Construire » grise sans dire pourquoi, erreurs du serveur telles quellestrois etapes (Source, Resultat, Installer), erreurs traduites, « Reessayer », « Creer un brouillon du theme »

La carte d'etat reste en bas a gauche, au-dessus de la barre flottante : rien ne couvre le haut du canevas (section 3). BuilderSlots.overlay reserve une couche entre le canevas et la barre pour une fonction a venir (Annotations) ; rien ne la monte encore.