Désormais avec création de pages par IA via le serveur MCP

La CLI cmssy

init génère le câblage dans une application existante, add block échafaude et enregistre un bloc, link connecte l'application à un espace de travail et prouve que ça marche.

Trois commandes, chacune pour un moment qui relève autrefois du travail manuel : câbler une nouvelle application, ajouter un bloc, se connecter à un espace de travail.

cmssy init

cmssy n'échafaude jamais votre application. Le framework est un adaptateur, jamais la fondation : vous créez l'application avec la CLI de Next.js, et init y ajoute le câblage cmssy.

npx create-next-app@latest my-site
cd my-site
npx @cmssy/cli init

La CLI vise Next.js avec l'App Router et requiert Node 18.18+. Astro, Remix et React Router sont pris en charge par le SDK lui-même : ceux-là, vous les câblez à la main plutôt que via init.

Elle est idempotente : un fichier déjà présent est ignoré et signalé comme tel, jamais écrasé. Lancée deux fois, la seconde exécution ne change rien.

Ce qu'elle écrit

cmssy.config.ts
proxy.ts
next.config.mjs
env.example
cmssy/blocks.ts          registre de blocs
cmssy/editor.tsx         pont d'édition
blocks/hero/block.ts
blocks/hero/Hero.tsx
blocks/hero/Hero.module.css
app/[[...path]]/page.tsx route catch-all
app/api/draft/route.ts   aperçu brouillon

Remarquez ce qui n'y est pas : ni app/sitemap.ts, ni app/robots.ts, ni route /cmssy-edit, ni layout racine, ni layout éditable.

Ce n'est pas un oubli mais un choix. Ces fichiers encodent des décisions propres à votre application - quelles URL vous exposez, à quoi ressemble votre habillage, comment vous formez un sitemap - et un modèle qui les devinerait serait faux pour la plupart des projets. init vous donne une page qui s'affiche et une route de brouillon ; le reste, vous l'ajoutez selon vos besoins - voir routes et pages, layouts et SEO.

Options : --dir <chemin> vise une application hors du répertoire courant, --force écrase le câblage existant.

cmssy add block

Chaque bloc après le hero généré signifiait recopier des fichiers à la main et penser à modifier le registre.

cmssy add block pricing-table
cmssy add block faq-list --dir ../my-site

Tous les noms dérivent de l'argument en kebab-case : pricing-table donne le type pricing-table, le libellé Pricing Table, le composant PricingTable et l'export pricingTableBlock.

Il écrit les fichiers du bloc et l'enregistre dans cmssy/blocks.ts - ajout de l'import et ajout au tableau blocks, en préservant votre formatage et vos entrées existantes.

Il refuse de toucher à tout ce qui est ambigu : un nom invalide, un bloc déjà enregistré, des fichiers existants, ou un registre sans tableau export const blocks = [...]. Chaque cas est un échec explicite avec l'étape manuelle détaillée - jamais une écriture partielle silencieuse.

Le bloc généré démarre avec un heading requis et un text optionnel. Modifiez les props et le markup, redémarrez le serveur de développement, et l'éditeur récupère le nouveau type via la poignée de main du manifeste.

Connecter une application à un espace de travail signifiait recopier cinq valeurs entre le tableau de bord et .env.local - et l'éditeur restait mort tant que toutes n'étaient pas bonnes.

npx @cmssy/cli link
cmssy link --token cs_... --workspace acme/shop --preview-url https://shop.example.com

Il s'authentifie avec un jeton API (depuis --token ou CMSSY_API_TOKEN ; .env.local et .env sont lus d'abord, sans jamais écraser les variables du shell), choisit un espace de travail, lit le secret de brouillon, écrit CMSSY_ORG_SLUG, CMSSY_WORKSPACE_SLUG et CMSSY_DRAFT_SECRET dans .env.local - en fusionnant, donc lignes et commentaires existants survivent - puis lance le preflight.

Lire le secret de brouillon exige la permission PAGES_EDIT. Une permission manquante est signalée exactement comme telle.

L'URL de prévisualisation est partagée - localhost est refusé

--preview-url définit l'origine où l'éditeur encadre votre application pour tout le monde dans l'espace de travail. Une valeur localhost est refusée exprès : pointer l'aperçu partagé vers votre machine casserait l'éditeur de chaque collègue.

Pour le développement local, activez le mode dev dans l'éditeur cmssy et saisissez-y votre hôte local. Cette cible est propre à chaque utilisateur.

Les vérifications

  • Espace de travail joignable - public.siteConfig répond. Distingue slugs erronés, problèmes réseau et espace au-delà de sa limite de diffusion.
  • Secret de brouillon - le backend confirme que le secret écrit correspond. Sur une plateforme sans ce champ, il signale ? et continue.
  • Lien profond éditeur - toujours affiché.
  • Lien d'aperçu brouillon - affiché quand l'espace déclare une URL d'aperçu. Quitter : /api/draft?disable=1.

Il y a trois statuts, pas deux : vérifié, cassé avec le correctif à la ligne suivante et code de sortie 1, et ? non vérifiable - qui ne bloque jamais. Ce troisième état existe parce que « inconnu » et « cassé » sont différents, et qu'un outil qui les confond soit crie au loup, soit masque une vraie panne.

Le preflight est aussi une API

Chaque vérification est une fonction pure de @cmssy/core, exposée sous un sous-chemin pour que l'outillage de développement n'entre jamais dans votre bundle de production :

import {
  checkWorkspaceReachable,
  checkDraftSecret,
  checkPreviewUrl,
  checkFrameAncestors,
  buildEditorUrl,
} from "@cmssy/core/preflight";

Chacune renvoie { status: "ok" | "fail" | "unknown", message, fix? }. Les deux premières parlent à l'API de diffusion ; le reste est de la logique de chaînes pure. Aucune n'importe de framework ni de module Node : elles tournent partout.

Quand le câblage est cassé

En développement, les mêmes vérifications gardent la route d'édition. Une requête éditeur qui échoue à la vérification ne renvoie pas 404 : l'adaptateur affiche une page de diagnostic dans l'iframe de l'éditeur, une ligne par vérification.

Elle montre le slug de l'espace de travail et la vérification en échec, jamais une valeur de secret.

Étapes suivantes