seo-os — Orchestrateur du système SEO unifié
seo-os est le point d'entrée du système SEO. Il route les commandes vers les branches existantes (audit, contenu, refresh, monitoring), en résolvant à chaque fois le client concerné depuis sa configuration.
Rôle exact (à ne pas confondre)
- Aujourd'hui (local) :
seo-osest la structure de build + l'outil de démo. Lucas lance les commandes à la main pour construire, valider et démontrer chaque branche. Ce n'est PAS le produit final. - Cible (cloud) : le produit final est autonome (Trigger.dev planifie les branches par client, le client reçoit un dashboard).
seo-osne fait que router ; il n'embarque aucune logique métier SEO — celle-ci vit dans les branches.
Principe multi-client
Chaque client a un dossier clients/<slug>/ :
client.json— manifest (domaine, gsc_property, langue, business_type, competitors, context_dir, cms, api_keys en réfs d'env, seuils de fraîcheur). Source de vérité ; aucune branche ne redemande ces infos.context/— 11 fichiers markdown (ligne éditoriale + positionnement) qui calent le contenu sur la voix du client.data/— réserve de données mutualisée (crawl/,gsc/,dataforseo/), datée. Toutes les branches lisent dedans. Une branche ne (re)crawle/(re)requête que si la donnée est périmée (seuils dansclient.json).outputs/— sorties versionnées par date par branche → reporting comparable d'un run à l'autre.state/— planning local des tâches auto.
Le slug est la clé primaire. Toute branche reçoit --client <slug>, lit client.json via scripts/resolve_client.py, et résout ses chemins.
Commandes
| Commande | Action | Skill/branche invoqué |
|---|---|---|
/seo client new <slug> |
Crée la structure de base d'un client | scripts/new_client.py |
/seo client list |
Liste les clients existants | scripts/resolve_client.py |
/seo audit <slug> |
Audit SEO complet (technique + GEO + recos mesurables) | technical-seo-audit |
/seo audit-page <slug> <url> |
Audit d'une page précise (Phase 2) | page-audit |
/seo strategy <slug> |
Stratégie de contenu : keywords client + local → plan de pages à créer/améliorer | seo-strategy |
/seo keywords <slug> |
Gap concurrentiel (sur quoi les concurrents rankent que le client ne couvre pas) | keyword-gap + Phase 3 audit |
/seo content <slug> "<keyword>" |
Brief → rédaction → QA (sans kanban) | Content-brief-creator → Article-creator → Content-quality-evaluator |
/seo refresh <slug> |
Détection contenu à rafraîchir + brief de MAJ | Content-refresh |
/seo monitor <slug> |
Monitoring léger + alerte (déclins vs run précédent) | scripts/monitor.py (Phase 2) |
/seo publish <slug> <article> |
Publication WordPress ou livraison fichier (Phase 4) | publish-wordpress |
/seo report <slug> |
Recompile le dernier audit / compare au précédent | technical-seo-audit + compare_audits.py (Phase 5) |
references/block-map.md détaille, pour chaque commande, le skill invoqué, ses inputs (depuis client.json + la réserve) et où il écrit ses outputs.
Comment router une commande
- Résoudre le client : lire
clients/<slug>/client.jsonviascripts/resolve_client.py(expose les chemins absolus + helpers de réserveis_fresh/latest_data/data_dir/output_dir).python seo/seo-os/scripts/resolve_client.py <slug> --json - Vérifier la réserve : pour les branches qui consomment crawl/gsc/dataforseo, tester la fraîcheur. Si périmé, la branche régénère et dépose dans
data/<kind>/<date>/; sinon elle lit le dernier dossier daté. - Invoquer la branche en lui passant le slug et les chemins résolus. La branche écrit ses sorties dans
outputs/<branche>/<date>/. - Ne jamais hardcoder de domaine/clé : tout vient de
client.json. Les clés API sont celles du client (réfs d'env), appels REST directs.
Création d'un client
python seo/seo-os/scripts/new_client.py <slug> --name "Nom Client" --domain example.com --lang fr --business-type local --cms none
Crée le dossier, le manifest, les 11 fichiers de contexte (à remplir), la réserve vide, et enregistre le client dans registry/clients.json. Compléter ensuite client.json (competitors, cms, api_keys) à la main ou via populate-context.py pour le contexte.
Fichiers
scripts/new_client.py— crée la structure de base d'un client.scripts/resolve_client.py— résout un client (chemins + réserve). Importé par les branches.registry/clients.json— index de tous les clients.references/block-map.md— mapping commande → branche → inputs/outputs.templates/context/— gabarits des 11 fichiers de contexte (copiés à la création d'un client).
Démo "système global"
Le but de la démo de vente est de montrer un output par branche (audit, brief, article, refresh, alerte monitoring) sur un client test — pas une seule branche polie. Les branches sur données publiques (technique, page, contenu, GEO, SERP) tournent sur un site test ; les branches qui dépendent du GSC/GA4 (impact trafic, monitoring, refresh) utilisent des inputs simulés réalistes (générateur dédié). On démontre que la machine complète produit un livrable par branche.