Copiază COMPLET un website extern în Symbai (magazin online / site de prezentare) — toate paginile, tot catalogul cu poze/descrieri/categorii/variante, blogul, paginile legale — printr-un proces care rulează ORE, descompus în sarcini mici verificate, care NU se oprește la 20% și NU declară „gata" până nu e verificat obiectiv. Folosește la „copiază-mi site-ul / magazinul", „adu-mi site-ul de pe X în Symbai", „clonează magazinul de pe Y", „importă tot site-ul meu", „mută-mă de pe vechiul magazin", „fă-mi site-ul identic cu cel vechi", „copiază toate produsele de pe site-ul meu", „de ce ai copiat doar o parte din site", „continuă copierea site-ului". Pentru un site MIC sau o singură pagină de prezentare (fără catalog mare) poți folosi direct `construieste-website`; pentru cataloage mari / site întreg / „să nu se mai oprească până nu termină" folosește ACEST skill.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Copiază COMPLET un website extern în Symbai (magazin online / site de prezentare) — toate paginile, tot catalogul cu poze/descrieri/categorii/variante, blogul, paginile legale — printr-un proces care rulează ORE, descompus în sarcini mici verificate, care NU se oprește la 20% și NU declară „gata" până nu e verificat obiectiv. Folosește la „copiază-mi site-ul / magazinul", „adu-mi site-ul de pe X în Symbai", „clonează magazinul de pe Y", „importă tot site-ul meu", „mută-mă de pe vechiul magazin", „fă-mi site-ul identic cu cel vechi", „copiază toate produsele de pe site-ul meu", „de ce ai copiat doar o parte din site", „continuă copierea site-ului". Pentru un site MIC sau o singură pagină de prezentare (fără catalog mare) poți folosi direct `construieste-website`; pentru cataloage mari / site întreg / „să nu se mai oprească până nu termină" folosește ACEST skill.
Copiază un website complet în Symbai — hands-free, pe ore, verificat
Proprietarul vrea site-ul lui (sau unul pe care îl deține/administrează) copiat întreg în Symbai: nu o aproximare de homepage, ci tot catalogul, toate categoriile, pozele, descrierile, blogul, paginile legale. Pe site-uri mari asta durează ore și NU încape într-o singură „tură" de agent. Acest skill e un orchestrator care duce treaba la capăt fără să se oprească la 20% și fără să mintă că e gata.
De ce era nevoie de el:analyze_external_website vede maxim 24 de pagini și nu citește sitemap-ul → pe un site de mii de produse copiezi ~20% și pari „gata". Aici pornim de la scopul ADEVĂRAT al site-ului (numitor independent), ținem o coadă durabilă pe disc (supraviețuiește compactării contextului), lucrăm pe loturi mici cu sub-agenți, și declarăm „gata" doar când o poartă de paritate obiectivă (ID-uri lipsă = 0) trece.
../construieste-website/SKILL.md — EXECUTORUL (cum scrii efectiv în Symbai: produse, categorii, hero, footer, PDP). Acest skill îl ORCHESTREAZĂ.
../../knowledge/website-copy-intake.md + ../../knowledge/website-builder-pdp.md — paritate vizuală + pagina de produs bogată.
Două benzi: seed rapid din Setări + perfecționare fidelă cu agentul
Există acum două căi complementare, nu două implementări concurente:
Seed rapid self-service (mecanic): în Symbai, Setări → General → Date & Mentenanță → Import website public. Managerul selectează brandul/unitatea, scrie URL-ul și parola Symbai de import, apoi confirmă că reprezintă brandul sau are permisiunea de copiere. Serverul face crawl + cache + produse + galerii locale + arbore de categorii + blog draft + pagini builder native, în job persistent. Browserul și laptopul pot fi închise. Aceasta este calea recomandată pentru onboarding rapid.
Perfecționare fidelă (judecată): acest skill preia jobul ajuns la review_required, rulează/remediază porțile, construiește design-plan.json, verifică vizual desktop+mobil, mapează variante/formulare/video și aprobă textele legale. Aici rămân utile bucla, verificatorul adversarial și, doar la cerere explicită, agentul programat.
Seed-ul automat este intenționat oprit înainte de cutover. Nu activează meniul importat, nu schimbă website-ul implicit, nu publică textele legale și nu scrie 301-urile până când:
un om confirmă verificarea vizuală și, separat, verificarea legală;
clone_audit_all(...).data.pass === true;
audit_shop_health(...).data.ok === true.
Parola din formular NU este parola site-ului sursă. Este cheia server-side Symbai (WEBSITE_IMPORT_PASSWORD; fallback separat doar în development), comparată constant-time, cu rate-limit. Nu se persistă și nu se trimite sursei. Importul nu acceptă cookies, user/parolă sursă sau conținut din cont/checkout/admin. „Este public” nu înseamnă automat „am dreptul să-l republic”: atestarea de autorizare + auditul actorului sunt obligatorii.
Starea canonică pentru această bandă este clone_crawl_jobs.options.websiteImport + clone_crawl_pages; nu .symbai-clone/. Coada locală .symbai-clone/ rămâne pentru planul de design și munca agentului după seed.
Uneltele de copiere pe server
Crawl-ul greu rulează pe server (owner-ul poate închide laptopul) — tu doar mapezi din cache și verifici. (Descoperire + crawl + 3 porți-produs mai jos; porțile advisory + SEO sunt în Faza 4.)
list_clone_crawl_pages(jobId, type, status, limit, offset) — coada de lucru: toate URL-urile tipizate (product/category/blog/legal/page) cu status. Sursa adevărului pentru „ce mai am de făcut".
get_cached_page(jobId, url) — conținut + date structurate extrase pentru O pagină (nume, SKU, preț, preț vechi, poze, descriere, breadcrumb, specs PDP, variantCount). De aici mapezi un produs/pagină în Symbai, fără re-descărcare. Pentru paginile NON-produs întoarce și sections[] — inventarul OBIECTIV de secțiuni al paginii-sursă (heading, volum de text textChars, imagini lazy-load-aware, CTA-uri, bgHints culori de fundal inline): numitorul de design al paginii. Dacă sursa are 11 secțiuni și tu ai construit 3, e FAIL măsurabil, nu opinie. Cu el seedezi design-plan.json (vezi mai jos).
clone_parity_diff(jobId, brandId) — POARTA 1 (acoperire produse): compară SETUL de produse-sursă (chei SKU) cu cele importate → întoarce ID-urile care LIPSESC. PASS doar dacă denominatorConfident ȘI nu lipsește nimic.
clone_fidelity_audit(jobId, brandId, sampleSize?) — POARTA 2 (calitate produse, adâncime): eșantion din TOT catalogul, comparat CÂMP-CU-CÂMP cu importul (nume/poze/galerie/descriere/preț/categorie/specs/variante) → fidelityScore + fieldScores + worstSample (ce câmp lipsește, pe ce produs) + flags. fieldScores.gallery prinde importuri de tip „1 poză din 8"; low_gallery_fidelity se repară cu bulk_set_product_images.
clone_coverage_audit(jobId, brandId) — POARTA 3 (tot ce NU e produs): set-diff pe sursă vs importat → coverage + per dimensiune. O migrare reală aduce și astea, nu doar catalogul.
Cum lucrezi cu userul — INCREMENTAL, una câte una (mod IMPLICIT)
Implicit, lucrezi user-driven, NU autonom pe ore. Modul „rulează ore, nu te opri" (Faza 5 + harness.md §Nu-te-opri: /loop, agentul programat, hook-ul Stop) este OPT-IN — îl pornești DOAR după ce userul îți cere explicit „rulează tot / nu te opri / las-o să meargă / închid laptopul". Până atunci toată mașinăria „nu te opri" stă OPRITĂ.
De ce: lecția #1 dintr-o clonare reală — când faci prea mult într-un singur prompt NU verifici destul și scapi greșeli (poze lipsă, link-uri care pleacă de pe clonă, componente nemapate). Verificarea temeinică CERE pași mici. Mai bine durează ore în pași verificați decât „pare gata" la 20%.
Reguli ale cadenței (non-negociabile):
Descompune. Orice lucrare mare (clonarea unui site) o spargi într-o listă numerotată de sarcini mici, fiecare verificabilă singură (ex.: „confirmă numitorul", „mapează ACEASTĂ categorie de ~20 produse", „importă pagina Despre și arat-o", „localizează link-urile din blog"). Ține lista pe disc — catalogul în progress.json, paginile de prezentare în design-plan.json (pe secțiuni) — nu în cap. Userul îți poate cere oricând „arată-mi planul" sau îți poate da el planul: îl scrii pe disc și îl urmezi bucată cu bucată.
O singură sarcină pe tură. Faci EXACT o sarcină mică pe tură. Niciodată nu înlănțui mai multe sarcini în tăcere.
Verifică obiectiv, în aceeași tură. Înainte să mergi mai departe, confirmi sarcina prin CITIREA câmpurilor scrise (re-citești din Symbai ce ai scris) — și, pentru pagini, vizual în browser — nu prin „tool success". „Gata" la o sarcină mică ≠ „pare gata".
Explică în limbaj de business. Spui userului, scurt și pe înțeles, CE ai făcut la sarcina asta și de ce — nu jargon, nu dump de cod.
Propune ÎNTOTDEAUNA următoarea sarcină și oprește-te. Închei fiecare tură cu: (a) rezultatul sarcinii curente + dovada verificării, (b) o singură sarcină următoare concretă, propusă. Apoi te OPREȘTI și aștepți ca userul să zică „continuă / da / yes". Userul conduce ritmul.
Niciodată „gata" fără verificare și niciodată întreg catalogul/site-ul într-o singură tură. „Gata" pe tot rămâne definit de porțile obiective (Regula 1 de mai jos) — porțile rulează doar după ce userul a aprobat parcurgerea.
Chiar și în modul autonom (opt-in), fă checkpoint: după fiecare poartă care trece sau fiecare N loturi, postezi o linie de progres + următoarea sarcină planificată, ca userul să poată interveni.
⚠ Reguli NON-NEGOCIABILE (din ele vine corectitudinea)
„Gata" NU înseamnă „pare copiat". „Gata" = clone_audit_all(...).data.pass === true (porțile dure trec + advisory nu blochează) sau, dacă rulezi manual, TOATE porțile dure pass:true — clone_parity_diff (0 produse lipsă, numitor sigur) ȘI clone_fidelity_audit (câmpurile produselor transferate, inclusiv galerie când sursa are 2+ poze) ȘI clone_coverage_audit (categorii/blog/pagini legale migrate) — PLUS Poarta 4 (fidelitate de design, Faza 4b): paginile de prezentare arată ca originalul, verificat vizual — PLUS audit_shop_health fără error. Niciodată pe baza impresiei tale.
Numitorul mai întâi. Dacă denominatorConfident:false, NU începe să declari progres procentual fals. Obține un al doilea semnal (vezi harness.md §Numitor) sau spune-i EXPLICIT userului „best-effort, denominator nesigur (motiv)" — nu ascunde.
Cheia de identitate = SKU / handle / slug-sursă, NU numele. Setează câmpul sku al fiecărui produs = cheia sursă la import (bulk_create_products(sku=<cheie>)). Altfel bulk_create_products deduplică pe NUME și îmbină tăcut produse distincte → pierdere de date care „trece" la numărătoare.
Niciodată tot catalogul într-o singură trecere. Descompune în loturi mici (≤25 produse / 1 pagină) date la sub-agenți (Task tool) cu context curat; tu (liderul) ții doar coada + tally-ul, nu HTML-ul paginilor.
Coada trăiește pe DISC (.symbai-clone/), nu în context. La fiecare iterație/sesiune nouă, prima acțiune = re-citește coada și reia; nu te baza pe memorie după compactare.
„Buget epuizat" ≠ „complet". Dacă atingi un plafon de timp/cost, starea finală e INCOMPLET cu numărul de ID-uri rămase afișat — niciodată COMPLET.
Idempotent. Re-rularea unui lot trebuie să fie no-op (cheia stabilă + dedup Symbai). Verifică prin CITIRE a câmpurilor, nu prin „tool success".
Paginile de prezentare se copiază pe DESIGN, nu pe text. O pagină (acasă, despre, servicii, abonamente, blog, legale) NU se toarnă într-un singur bloc custom-HTML. Fiecare secțiune-sursă se mapează la o componentă nativă de website-builder (hero, text+imagine, carduri, galerie, testimoniale, FAQ, pricing) ca tema s-o stilizeze. „Arată ca originalul" e o POARTĂ (vezi Poarta 4), nu o impresie. Verificarea finală e vizuală, pagină-cu-pagină, componentă-cu-componentă în browser — exact cum verifică ownerul.
Fluxul (faze)
Faza 0 — Scop & numitor onest
list_brands → brandId (sau creează brand+locație+depozit dacă instanța clientului e goală / cont nou — vezi construieste-website).
Dacă denominatorConfident:false: citește flags. single_independent_count/no_independent_count (ex. Magento/OpenCart fără feed JSON) → al doilea semnal: numără produsele dintr-o pagină de listing („N produse/rezultate") pe câteva categorii și extrapolează, SAU continuă marcat „best-effort" și spune-i userului. counts_disagree/denominator_round_cap → reconciliază înainte de a declara vreodată „gata".
Faza 1 — Pornește crawl-ul pe server (hands-free)
start_site_clone_crawl(url, brandId) → jobId. Rulează în fundal pe server. Spune-i userului: „Am pornit copierea pe server — poți închide laptopul; eu continui și verific."
Poll get_clone_crawl_status(jobId) periodic. Nu aștepta să termine 100% ca să începi maparea — mapează pe măsură ce paginile devin cached.
Faza 2 — Coada durabilă pe disc
Creează .symbai-clone/<host>/ cu manifest.json (numitor + goldProducts), progress.json (header/tally), design-plan.json (design DNA + planul pe pagini/secțiuni — schema în references/harness.md) și flag-ul .pending-clone-<sessionId>. (Crawl-ul e deja persistent pe server; fișierele locale sunt tally-ul tău + poarta hook-urilor „nu te opri".)
6b. Design DNA (înainte de ORICE scriere vizuală): deschide site-ul REAL în browser și extrage paleta COMPUTED (header, hero, benzi de conținut, butoane), fontul (link fonts + computed pe h1/body), formele (radius butoane/carduri). Scrie-le în design-plan.json → designDna, fiecare valoare CU dovada ei („navbar computed background", „culoarea dominantă din logo"). De aici — și NUMAI de aici — vin culorile/fonturile pe care le scrii în configuri (Regula 10). clone_branding_audit îți dă semnalele de bază (logo/culoare temă); browserul le rafinează pe roluri semantice.
Faza 3 — Mapează în loturi, cu sub-agenți
Buclă: list_clone_crawl_pages(jobId, type:"product", status:"cached", limit, offset) → ia un lot de ~25. Dă-l unui sub-agent (Task) cu instrucțiune strictă: pentru fiecare URL → get_cached_page → bulk_create_products(sku=cheia sursă, name, description, vat:21, ...) + set_product_image/bulk_set_product_images + add_menu_item(productBrand, ...); întoarce DOAR {lot, produseScrise, pozeScrise, eșecuri[]}. Apoi categorii (ierarhie din breadcrumb → bulk_reparent_menu_categories + set_products_menu_category), blog (bulk_create_blog_posts), legale (set_website_legal_page), footer/branding.
⚠ Parcurge TOATE tipurile, nu doar type:"product"/type:"page". Coada are product/category/blog/legal/page — fiecare cu importatorul lui. Dacă filtrezi importul de pagini pe type:"page", pierzi tăcut paginile cu type:"legal"/type:"blog" (într-o clonare reală au lipsit mai multe pagini exact așa). Iterează pe toate tipurile relevante.
După fiecare lot, actualizează progress.json. Liderul citește doar header-ul + cere următorul lot — nu încarcă tot catalogul în context.
Faza 4 — Verifică (cele 3 porți obiective, în ordine)
Poarta 1 — acoperire produse: clone_parity_diff(jobId, brandId). Dacă pass:false: pentru fiecare ID din missingSample → get_cached_page → re-importă. Re-rulează până pass:true.
9b. Poarta 2 — calitate produse: clone_fidelity_audit(jobId, brandId). Pentru fiecare intrare din worstSample (produs + câmpuri lipsă) → get_cached_page(jobId, url) → completează câmpul: poze/galerie (set_product_image/bulk_set_product_images, prima poză = copertă), descriere/preț-vechi/specs (update_menu_item/add_menu_item), variante (set_product_variants), categorie (set_products_menu_category). Re-rulează până pass:true. Citește flags: low_gallery_fidelity → produsul are prea puține poze față de sursă; unreadable_source_pages_* → re-citește sursa; price_currency_mismatch_suspected → verifică valuta; unaudited_fields_* → câmp absent în sursă (nimic de făcut).
9c. Poarta 3 — non-produs: clone_coverage_audit(jobId, brandId). Pentru fiecare missingSample per dimensiune → importă din get_cached_page: categorii (create_menu_category/bulk_reparent_menu_categories), blog (bulk_create_blog_posts), pagini legale (set_website_legal_page). Re-rulează până fiecare dimensiune ≥95%.
9c-arbore. Arbore categorii (advisory): clone_category_tree_audit(jobId, brandId). pass poate fi null (sursă fără breadcrumb-uri = neauditabil, OK). Dacă pass:false sau flatteningDetected:true: pentru fiecare missingEdgesSample (parent>child) → create_menu_category (categoriile lipsă) + bulk_reparent_menu_categories (leagă copil→părinte, ca arborele să nu fie plat). Re-rulează până pass ∈ {true, null}.
9c-branding. Branding (advisory): clone_branding_audit(jobId, brandId). poate fi (sursă fără semnale vizuale). Dacă : din → + (logos/colors/socialMedia); contactul (telefon/email/adresă din ) → . Re-rulează până ∈ {, }.
9d. → repară toate , re-rulează până curat.
9e. . Rulează la final sau când vrei status executiv. înseamnă că porțile dure trec și advisory nu blochează; înseamnă că nu poți declara complet, chiar dacă restul arată bine.
9f. . După ce porțile trec, scrie 301-uri din URL-urile VECHI (produs/categorie) spre cele noi Symbai, ca firma să NU piardă pozițiile Google când mută domeniul. Rulează ÎNTÂI dry-run (fără ) ca să vezi //; dacă e mare, mai întâi închide golurile (parity/coverage), apoi . (Esențial la o migrare reală cu trafic.)
Faza 4b — Poarta 4: fidelitate de DESIGN (paginile de prezentare)
Catalogul poate fi 100% și site-ul tot să arate „groaznic" dacă paginile sunt text simplu fără designul sursei.
Protocolul plan → loop (obligatoriu, Regula 11):
0. Inventariază ÎNTÂI, construiește DUPĂ. Pentru fiecare pagină non-produs din coadă (list_clone_crawl_pages type page/legal/blog + home + paginile de categorie-cheie): get_cached_page(jobId, url) → citește sections[] (numitorul de secțiuni) → scrie pagina în design-plan.json cu TOATE secțiunile ei (sourceSectionCount, per secțiune: heading/imagini/CTA/bgHints din tool + mappedType propus + status:"todo"). O pagină fără inventar scris pe disc NU se construiește. Arată-i userului planul ca listă numerotată („pagina X: N secțiuni") când îl termini.
Loop — o bucată pe iterație: ia URMĂTORUL item nebifat din design-plan (o pagină mică întreagă SAU o singură secțiune pe pagini mari). Mapează componentă-cu-componentă (cu construieste-website): fiecare secțiune-sursă → componentă nativă echivalentă, cu fundalul/banda colorată (din bgHints + designDna), pozele, butoanele CTA (localizate) și animațiile pe care le are originalul. NU dump custom-HTML. Verifică bucata (pașii 2-3), bifeaz-o cu dovadă (status:"verified" + proof), actualizează design-plan.json, apoi propune următoarea bucată. NU înlănțui mai multe bucăți neverificate.
Agent de verificare structural (rulează după fiecare import): începe cu get_website_page(brandId, pageSlug) ca read-back live, apoi fă diff împotriva sections[] din get_cached_page (numitorul obiectiv, nu memoria ta): fiecare secțiune-sursă are un echivalent construit? → semnalează secțiuni lipsă, poze lipsă (compară cu images[] per secțiune), componente vizuale pierdute, text comprimat agresiv (textChars mare în sursă vs. un rând la tine), link-uri ne-localizate (doar href/src, nu URL-uri ca text afișat). Listează paginile de verificat vizual, worst-first. Nu număra ca „lipsă" tipurile care fuzionează firesc (titluri/rich-text → text-block) sau cele ne-vizuale (formulare) — altfel ai zgomot.
Pas vizual în browser (Chrome): deschide URL-ul REAL și echivalentul local unul lângă altul și compară componentă-cu-componentă (poze, benzi, box offset, fonturi, CTA, animație reveal). Notează diferențele → repară maparea → re-importă → re-verifică. Pe pagini cu multe imagini screenshot-ul poate da timeout: verifică structura cu interogări DOM (componente prezente + datele lor), nu doar poze.
Verifică EXPLICIT că fiecare rută randează conținutul EI (acasă ≠ meniu; /blog = listarea blogului; /<pagină> = pagina ei, nu homepage-ul). Un fallback tăcut la home/meniu (pagină neimportată) = pagină LIPSĂ, nu PASS. Într-un caz real, homepage-ul arăta meniul și /blog arăta tot meniul exact din cauza asta.
POARTĂ: zero poze-lipsă, zero benzi colorate pierdute, zero recenzii-imagine aruncate, zero animații reveal lipsă, zero componente vizuale pierdute, zero link-uri navigaționale ne-localizate, fiecare rută randează conținutul ei (zero fallback la home/meniu), zero pagini stale (re-importate după orice fix de mapare — Regula 9), (zero / rămase — Regula 11) și (fiecare culoare/font scris în configuri e trasabil la ; o valoare „de la site-ul trecut" = FAIL — Regula 10). Abia atunci pagina e „ca originalul".
Capcane de mapare → Verificare (fiecare a stricat o clonă reală). Bifează-le UNA CÂTE UNA pe fiecare componentă — nu „dintr-o privire":
Poză în câmp neevident.image e adesea gol; poza reală e în imageMask, picture (ImageCards), heroSectionSliderItems[] (hero) sau backgroundImage (scroll-list). → Probează TOATE câmpurile de imagine înainte să declari „fără poză".
Cutia decorativă din spate = o IMAGINE (imageBackgroundMask), nu o culoare. → mapeaz-o ca background-image.
Banda colorată de secțiune = câmp real al componentei (backgroundColor / box+boxColor), nu alb implicit. → setează sectionBg + sectionTextColor (ambele).
text-image bogat, nu custom inutil. Pentru secțiuni split folosește componenta nativă cu html, eyebrow, eyebrowColor, titleColor, ctaColor, backgroundImageUrl, backgroundOverlay, imageBoxColor/imageBoxImage, imageMask, imageShadow, decor. Abia dacă schema nu exprimă designul treci la custom-html.
Culorile sunt SEMANTICE — nu vopsi secțiuni întregi cu o culoare-accent. Calibrează pe culorile COMPUTED ale site-ului real (inspectează în Chrome): navy = eroi, light-blue = benzi de conținut, roz/galben = ACCENTE (boxuri, benzi de recenzii), niciodată erou full-bleed. Ex.: DarkTextBoxSection.boxColor e boxul din spatele IMAGINII, nu fundalul secțiunii (secțiunea = navy când textul e alb). Un text+imagine fără culoare → secțiune light-blue implicit, FĂRĂ box inventat.
Blog = Markdown. Renderul de blog NU afișează HTML brut. → convertește HTML→Markdown; restaurează entitățile dublu-escapate (&nbsp; → ).
NU trec prin localizatorul de href/src. → rescrie-le MANUAL la slug-ul Symbai (cazul , paginile legale).
Update 2026-06-24 - mapping-uri native pentru fidelitate vizuala
Inainte sa marchezi o sectiune ca necesitand custom-html, verifica aceste optiuni live din website builder:
Hero corporate cu panou diagonal si poza: hero-slider cu heroLayout:"diagonal-split", backgroundColor, diagonalAccentColor, panelWidth, dots/arrows/autoplay cand sursa are slider.
Hero index editorial: index-hero cu items:[{label,image,url}], height, align, overlayColor, activeColor, ctaText, ctaUrl pentru liste verticale de locatii/destinatii/colectii care schimba imaginea pe hover/focus (hotel groups / The Standard). Nu il inlocui cu grila sau custom HTML.
Titlu bicolor / rand accentuat: slides[].titleAccent; pastreaza slides[].title ca primul rand. Pentru litere cu contur foloseste titleStroke + titleStrokeWidth.
Beneficii in coloane minimaliste: feature-cards cu style:"divided", cards[].description si cards[].linkText; pentru titlu de sectiune aliniat stanga/dreapta sau pe doua randuri foloseste titleAlign si \n in title.
Carduri filtrabile: tabbed-cards cu tabs[], cards[].tab si showAllTab pentru servicii sau portofolii filtrate. Pentru pagina reala de locatii/restaurante/hoteluri cu harta si directii, foloseste store-locator.
Localizator cu harta: store-locator cu locations:[{name,address,city,region,hours,phone,mapQuery,directionsUrl}], regions, allRegionLabel, mapHeight pentru pagini "Find us" / "Restaurants" / "Locations"; filtrele pe regiune sunt interactive si recentreaza harta.
Lista editoriala + imagine: split-list pentru servicii/oferte/valori/pasi cu titluri subliniate, descrieri si linkuri langa fotografie; pastreaza imagePosition, titleUnderline, dividers si culorile originale.
Carusel editorial: content-carousel pentru destinatii, experiente, pachete sau povesti afisate cate una cu sageti/dots; continutul e inline, nu POS live.
Pasi / cum functioneaza: pentru sectiuni "how it works", abonamente, flux comanda/livrare sau experienta in 3-5 pasi; pastreaza , , si culorile.
Acestea trebuie bifate in Poarta 4 de design: screenshot desktop + mobil pentru hero diagonal, text-image diagonal si reveal la scroll, read-back pentru footer/navbar/tema si comparatie vizuala cu originalul.
Faza 5 — Nu te opri până nu e gata (mod AUTONOM, OPT-IN)
Aceasta e modul AUTONOM — pornește-l DOAR după ce userul cere explicit „rulează tot / nu te opri / las-o să meargă". În modul IMPLICIT (vezi „Cum lucrezi cu userul"), după FIECARE sarcină mică verificată te oprești și propui următoarea. În modul autonom, fă checkpoint: după fiecare poartă care trece sau fiecare N loturi, postează o linie de progres + următoarea sarcină planificată, ca userul să poată interveni.
Buclă până: coada goală (0 pending în list_clone_crawl_pages) ȘI clone_audit_all(...).data.pass === true (sau cele 3 porți produs pass:true — clone_parity_diff + clone_fidelity_audit + clone_coverage_audit — + advisory rezolvat/N-A) ȘI Poarta 4 design (Faza 4b) trecută vizual, cu design-plan.json complet verified ȘI audit_shop_health fără error. Fiecare trezire a buclei procesează O bucată din plan (Regula 11) — nu „cât mai mult".
Pentru rulare pe ore, nesupravegheat (owner-ul a plecat): instalează un agent programat care reia skill-ul cât timp mai există pending (vezi references/harness.md §Nu-te-opri + skill-ul schedule). Hook-ul Stop (dacă e instalat) e podeaua dură. /loop e bucla din sesiune.
Re-citește progress.json la fiecare reluare; revendică rândurile in_progress rămase blocate înapoi la pending.
Raport onest (la final)
Nu spune „gata" decât la PASS real pe TOATE trei porțile. Raportează: produse importate / numitor + fidelityScore (calitate câmpuri, din Poarta 2) + acoperirea non-produs (categorii/blog/pagini legale, din Poarta 3), paginile de design verificate / total din design-plan.json (cu secțiuni sursă acoperite), poze %, ID-uri pe dead-letter (cu motiv: 404/login/fără preț), și ce a rămas NESIGUR. Dacă numitorul a fost nesigur, spune-o. Rezumă userului 3-4 lucruri cheie făcute, în limbaj de business.
Capcane (vezi și harness.md)
Site fără sitemap (unele OpenCart) → discover_site_inventory întoarce 0 cu no_independent_count. NU înseamnă „site gol" — înseamnă „nu pot stabili scopul din sitemap"; pornește crawl-ul (folosește link-crawl/categorii) și marchează numitorul nesigur.
Magento: sitemap-ul de produse supranumără (include produse scoase din stoc). Numitorul din sitemap = plafon superior, marcat nesigur — reconciliază cu listing-urile.
Poze: trec prin URL sursă la set_product_image (Symbai le ia); dacă CDN-ul sursă cade, re-rulează din cache.
TVA România = 21 (nu 19). Idempotency pe SKU, nu pe nume.
categorii / blog / pagini legale
missingSample
clone_category_tree_audit(jobId, brandId) — advisory (Faza 4, 9c-arbore): verifică arborele de categorii (părinte→copil) vs aplatizare; pass poate fi null dacă sursa n-are breadcrumb-uri.
clone_branding_audit(jobId, brandId) — advisory (Faza 4, 9c-branding): logo / culori / nume / social / contact din sursă vs brandul Symbai; pass poate fi null fără semnale vizuale.
clone_audit_all(jobId, brandId, sampleSize?) — verdict complet, read-only, într-un apel: rulează parity + fidelity + coverage + tree + branding și întoarce pass, hardPass, erroredGates, sumar per-poartă și remedieri.
clone_redirect_map(jobId, brandId, apply?) — continuitate SEO (Faza 4, 9f): dry-run, apoi apply:true scrie 301-uri din URL-urile vechi produs/categorie spre URL-urile Symbai. Rulează ÎNTÂI dry-run, separat după PASS.
Pentru paginile de prezentare (non-produs): conținutul se scrie cu uneltele din construieste-website (set_website_theme → update_website_navigation → set_website_page_content/set_website_pages/set_website_legal_page) și se verifică prin get_website_page înainte de browser — vezi Faza 4b. Foloseste set_website_pages cand imporți multe pagini odata.
Orice corecție de mapare/renderer invalidează output-ul vechi. După ce repari un mapper sau un renderer (sau adaugi un tip de componentă), RE-importă paginile afectate ÎNAINTE de re-verificare. Un fix ne-reimportat = output stale care trece fals la verificare. Verifici versiunea NOUĂ, nu cea veche.
⚠ ANTI-CONTAMINARE: designul vine DOAR din site-ul pe care îl copiezi ACUM. La fiecare clonare NOUĂ pornești cu ochi proaspeți: site-ul clonat DATA TRECUTĂ (paleta lui, fonturile lui, layout-urile lui, exemplele lui) NU e referință — nici din memorie, nici din sesiuni vechi, nici din exemplele catalogului. Orice culoare / font / valoare vizuală pe care o scrii într-un config trebuie să fie TRASABILĂ la o dovadă din site-ul CURENT (culoare computed inspectată în browser, culoarea din logo, font din <link> fonts) — dovada o ții în designDna din design-plan.json. Valoare fără dovadă = contaminare → n-o scrii. Exemplele din catalogul de componente sunt STRUCTURALE (arată câmpurile), nu palete de copiat. Simptomul clasic al încălcării: „site-ul nou seamănă cu site-ul copiat săptămâna trecută, nu cu sursa lui".
Fidelitatea pe pagini se ține într-un PLAN durabil pe disc, lucrat în BUCLĂ — o bucată pe iterație. Nu construiești nicio pagină de prezentare înainte ca inventarul ei de secțiuni să fie scris în design-plan.json (seedat din get_cached_page(...).sections). Apoi loop: iei O pagină (sau O secțiune, pe pagini mari) → o construiești → o verifici (read-back + vizual) → o bifezi cu dovadă → treci la următoarea. Chiar dacă durează mai mult, fiecare bucată e făcută CORECT și nimic nu e sărit — planul de pe disc arată mereu, obiectiv, ce a rămas. „Am terminat designul" = toate paginile din design-plan au status:"verified", nu o impresie.
SEO — redirecturi 301: clone_redirect_map(jobId, brandId, apply:true)
apply
unmatched
noSlug
chainsSkipped
unmatched
apply:true
toate paginile din design-plan.json cu status:"verified"
todo
built
zero contaminare
designDna
Link-uri în corpul rich-text / descriptionHtml / custom-html
RichTextHtml
Recenzii doar-imagine.reviewItems[] fără text — recenzia e un screenshot în authorPicture. → randează galerie; NU lăsa un filtru pe text să arunce secțiunea.
Liste „scroll list" (ScrollListSection): itemele reale sunt în boxes[].boxCards[] (fiecare {image,title,text}), NU în boxes[].boxTitle; poza de secțiune e în backgroundImage (nu image). → intro text+imagine din backgroundImage + feature-cards din boxCards.
ProductsList ca secțiune de pagină (meniu inline): products.data e adesea gol (încărcat client-side) → afișează imaginea de menu. Mapeaz-o explicit, altfel pierzi tăcut secțiunea.
Componente care fuzionează / ne-vizuale (titluri + rich-text → text-block; formulare) — normal să scadă numărul la import; NU le număra ca „lipsă" (altfel verificatorul dă fals-pozitiv).
Navbar-ul = meniul REAL al sursei, nu lista auto de pagini. Inspectează în browser meniul site-ului real (itemii de top + dropdown-urile lor + href-uri) și reconstruiește-l 1:1 cu update_website_navigation items[] (suport children[] pentru dropdown). Default-ul (o intrare per pagină: Acasă/Atracții/Restaurant/...) NU corespunde. Și ascunde butonul CTA din dreapta dacă originalul n-are (navbarSettings:{ctaButton:{visible:false}}). Daca originalul are meniu lateral stanga, foloseste navbarSettings:{style:"sidebar-left", sidebarBg, sidebarTextColor, socialLinks:[...]}.
NU activa „extra"-uri de componentă pe care sursa NU le are. Componentele Symbai au opțiuni implicite decorative (sidebar de blog cu newsletter + „Recente", badge „Popular"/„Recomandat", toggle de facturare lunar/anual, rating badge, „featured hero"). Activează-le DOAR dacă site-ul real le are. Ex.: dacă blogul sursă NU are sidebar → blog-listing.showSidebar=false (altfel apare un „Abonează-mă" care nu există în original). Compară layout-ul real (câte coloane, cu/fără sidebar, cu/fără badge) și oglindește-l — un element în plus strică fidelitatea la fel ca unul lipsă.
process-steps
layout
numberStyle
connectors
Ticker/marquee: marquee cu items[], speed, separator, direction, textCase, culori pentru benzi derulante cu slogane repetate; nu folosi GIF/video/custom HTML. Pentru branduri lowercase seteaza textCase:"lower".
Banda App Store / Google Play: app-download cu appStoreUrl, googlePlayUrl sau stores[], optional image cu telefon, pentru sectiuni de tip order-ahead, loialitate, livrare sau "download our app"; nu o recrea ca custom-html.
Meniu restaurant static: menu-list cu layout:"grid"|"list", items[]/categories[], pret, meta/kcal, badge-uri, tag-uri dietetice, spice, filters:true, filterTags si culori. Foloseste-l pentru pagini de marketing/clone, inclusiv filtre Vegan/Vegetarian/Gluten-free; daca userul cere meniu POS live, nu-l folosi ca substitut al catalogului.
Fundal light mode: set_website_theme(backgroundColor, textColor?) cand originalul are fundal cream/warm/branded; verifica desktop + mobil ca nu a ramas alb implicit.
Footer complet de magazin: set_website_footer cu description, paymentMethods, showAnpc si socialLinks custom sigure (ex. tripadvisor, whatsapp, booking), pe langa contact/columns.
Navbar/chrome: update_website_navigation aplica navbarSettings direct, inclusiv sidebar-left, navbarBg pentru bare solide pe fundal cream/branded, logoRotate:180 pentru wordmark rasturnat, logoBg pentru cutie colorata in spatele logoText si ctaButton:{style:"outline"} / ctaButton:{style:"outline",color:"#c9a45c"} pentru CTA contur cu culoare default sau custom. Daca navbarBg e inchis la culoare, rendererul comuta automat textul/logo/iconitele pe light; verifica prin get_website_page + screenshot dupa scriere.
CTA solid custom: pentru buton navbar plin cu fundal/text de brand, foloseste ctaButton:{style:"solid",bgColor:"#173f35",color:"#ccff00"} si verifica read-back in navbar.
Navbar transparent / logo contextual: navbarSettings.transparent:true pluteste peste hero doar daca pagina incepe cu hero, hero-slider, image-hero sau index-hero; pe pagini light devine solid si poate folosi logoUrlDark. Pentru selector valuta seteaza showCurrency:true + currencies. Verifica vizual home + cel putin o subpagina.
Reveal-on-scroll global: daca originalul are sectiuni care apar la scroll, seteaza set_website_theme(scrollReveal:true). Verifica in browser ca efectul se vede pe sectiuni editoriale si ca elementele sticky/fixed raman functionale; rendererul exclude hero/navbar/footer/marquee si respecta prefers-reduced-motion.
Text+imagine cu muchie diagonala: pentru sectiuni split cu fotografie taiata oblic spre text, foloseste text-image.imageMask:"diagonal"; masca se intoarce automat cu pozitia imaginii, deci nu marca sectiunea ca fiind custom doar pentru aceasta forma.