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) :
| # | Element | Fichier | Ce qu'il faisait |
|---|---|---|---|
| A | Ligne d'en-tete, 56 px | upstream/.../_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 |
| B | Popover de zoom | upstream/.../design-panel/zoom-controls/index.tsx | Bouton « 100% », popover : champ libre, zoom +, zoom -, ajuster, 100 %, 200 % |
| C | Barre de style, 44 px | upstream/.../editor-bar/index.tsx | Rangee DOCKEE sous A, visible seulement quand un element ou un cadre est selectionne : les controles de style de DivSelected |
| D | Rail d'activite, 44 px | upstream/.../design-panel/index.tsx (DesignPanel) | Trois boutons : Calques, Pages, « Library ». aria-label="Builder panels" en anglais en dur, infobulles title natives |
| E | Panneau lateral, 256 px | meme fichier | En-tete de 36 px (libelle du panneau), puis LayersTab, PagesTab scope="pages" ou PagesTab scope="library" |
| F | Aiguillage gauche | upstream/.../left-panel/index.tsx (LeftPanel) | D + E en mode design / main, CodePanel en mode code |
| G | Canevas | upstream/.../canvas/** | Les cadres (chacun avec sa propre barre de cadre : page, lien externe), overlays, bouton « recentrer » |
| H | Mesure des panneaux | upstream/.../_hooks/use-panel-measure.tsx | Mesurait 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 :
| # | Element | Fichier | Ce qu'il faisait |
|---|---|---|---|
| M1 | Ligne d'en-tete, 56 px | src/features/ai/preview/mirror/mirror-pane.tsx (WorkbenchToolbar) | Titre « Mirror / hote », champ URL + Charger, Selection / parent / enfant, Bureau / Mobile, Capturer |
| M2 | Bande d'onglets, 36 px | meme fichier | Source / Resultat, apparue apres compilation |
| M3 | Colonne droite, 320 px | meme fichier | Selection + « Ask @Atlas », options (nom, texte, droits), Construire, rapport, telechargement, choix du theme brouillon, Installer |
| M4 | Stage | meme fichier | Cadre sandbox="allow-scripts" du snapshot, cadre sandbox="" du resultat |
| M5 | Etape du stepper | src/config/dashboard-nav.ts | Cinquieme etape, ?mode=mirror |
2. Les doublons
- 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.
- Deux barres d'outils du meme grammaire pour une seule tache (A et M1), dans deux modes voisins : trouver une section, puis la travailler.
- 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).
- Deux choix de theme : le Builder edite le premier theme non live
(
pickThemeIddebuilder-frameetbuilder-library), Mirror proposait sa propre liste de brouillons. Une section installee dans un autre brouillon n'apparaissait pas dans la Bibliotheque qu'on regardait. - 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.
- Deux zooms : le popover B et les raccourcis clavier du canevas, qui ne partageaient pas la meme fonction.
- Un calcul mort (H), appele a chaque rendu, jamais lu.
- 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 flottanteWorkbenchFloatingToolbar(Toolbar.Rootde 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,
PanelIconButtonetPanelSectionLabel, sousDARK_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.
DivSelectedrepliait 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
| Avant | Apres |
|---|---|
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 dockee | d'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 / Resultat | deux boutons de la face Mirror |
| M3 colonne droite | chrome/mirror/mirror-panel.tsx, onglet Mirror du panneau gauche |
| M4 stage | chrome/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 brouillon | le 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) :ModeViewpassepreviewThemeIdau Builder, chaque requetebuilder-frame/builder-libraryporte?themeId=(src/features/ai/onlook/builder-theme.ts), etpickBuilderThemele retient s'il n'est pas live. - Le zoom du canvas Workflow est encore le
Controlsde React Flow, style parworkflow-v2.css, pasWorkbenchFloatingToolbar. - Le mode code d'Onlook doublait le Worktree. Retire (
ai-platform/3052) : plus deCodePanelni de slotcode; « 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 :
| Section | Controles | Ecriture (inchangee) |
|---|---|---|
| Ask @Atlas | champ + envoyer | attachSelectedElement (le meme que le menu contextuel, donc attachBuilderSelection), puis boostecom:chat-prompt |
| Contenu | « Modifier le texte sur le canevas » (texte), indication (image) | text.editSelectedElement |
| Couleurs | texte, fond : couleurs de marque d'abord, puis couleur libre | useColorUpdate.handleColorUpdateEnd |
| Typographie | police (lecture), taille, graisse, interligne, espacement, alignement | useTextControl, style.update |
| Espacement | marge interieure, marge exterieure : tous les cotes ou un seul | useBoxControl.handleBoxChange / handleIndividualChange |
| Disposition | direction, repartition, alignement, ecart (en flex seulement) | style.update |
| Avance (repliable) | affichage, largeur, hauteur, bordure, couleur de bordure, arrondi | style.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 :
| Section | Controles | Ecriture |
|---|---|---|
| Couleurs | image de fond : images deja affichees par la page, ou URL https ; retirer | style.update('backgroundImage') |
| Typographie | police : familles du theme, celles du kit de marque en tete | style.update('fontFamily') |
| Visibilite | masquer sur mobile, masquer sur ordinateur (une section de theme) | getUpdateStyleAction + action.run, l'etat sauve en original |
| Avance | opacite, 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 :
| Piece | Avant | Apres |
|---|---|---|
| Onglets Pages et Sections | PagesTab d'Onlook (slot), anglais, « Create a new page » sans bac a sable | chrome/library/builder-library-panel.tsx, traduit, sur la reponse de builder-library (status, source) |
| Onglet Calques | le LayersTab seul, vide sans explication | chrome/frames/builder-layers-panel.tsx : squelette, raison et correctif, puis l'arbre sous le nom de sa page |
| Canevas | blanc tant que les cadres chargent, fausse section en cas d'echec | chrome/canvas/builder-canvas-status.tsx : bloqueur centre (Shopify, portee, theme), squelette de page, carte d'etat en bas a gauche |
| Onglet Mirror | une colonne, « Construire » grise sans dire pourquoi, erreurs du serveur telles quelles | trois 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.