Générer des cadres de projet
Capture les meilleures pages du projet courant, puis les encadre. Cette compétence gère la découverte, la préparation de l'application et la qualité brute des captures d'écran ; SOUS-COMPÉTENCE REQUISE : generate-frame gère l'encadrement et la couverture. Exécute d'abord son étape 1 (localiser et vérifier frame-kit) et arrête-toi si elle échoue. <frame-kit> est le chemin qu'elle résout.
Sorties, jamais mélangées : brut → ~/Pictures/<projet>-portfolio/raw/, encadré → ~/Pictures/<projet>-portfolio/framed/.
1. Analyse
Trouve les pages accessibles aux utilisateurs : routes, composants de page/vue, ressources d'administration (Filament, Nova…), menus de navigation. Lis le code pour savoir comment exécuter l'application, quels rôles existent et quel rôle voit quelle page. Ne devine pas les ports, URLs ou identifiants ; vérifie-les en exécutant l'application ou en demandant.
2. Proposer jusqu'à 5
Décide de quel type de produit il s'agit, puis classe les pages selon leur capacité à montrer ce qu'il fait vraiment. La question est : qu'est-ce qui ferait comprendre ce produit à un inconnu en une seule image ?
| Produit | Pages les plus fortes |
|---|---|
| Application métier/administration (POS, CRM, inventaire) | le workflow principal avec des lignes réelles, puis le tableau de bord, puis des listes riches en données |
| Tableau de bord / analytique | tableau de bord principal, un détail, un rapport |
| Site de contenu/marketing/e-commerce | page d'accueil/hero, liste, page détail, panier ou checkout |
| Éditeur / constructeur / outil créatif | le canevas avec du contenu, puis une galerie ou une liste de projets |
| Outil développeur / documentation | interface principale en cours d'utilisation, une vue de résultat/sortie |
Ignore les pages de connexion, les formulaires vides, les paramètres, les pages d'erreur et les quasi-doublons. Moins de 5 est acceptable. Liste chaque page avec son nom, chemin, rôle et une ligne de justification.
3. Demander
AskUserQuestion, multiSelect (max 4 options par question ; divise en deux questions si nécessaire). La capture ne doit pas commencer avant que l'utilisateur ait choisi. Demande aussi : clair ou sombre (seulement si l'application a les deux), et quel rôle/compte utiliser. Les identifiants proviennent de l'environnement de l'utilisateur ou d'une session existante ; ne les écris jamais dans des scripts, fichiers ou sorties, et ne contourne jamais les contrôles d'accès (une page que le rôle choisi ne peut pas voir est ignorée, pas forcée).
4. Préparer l'application
- Démarre l'application si elle ne tourne pas, sur un port libre ; n'oublie pas d'arrêter ce que tu as démarré.
- Ouvre les pages choisies. Données vides ou d'exemple → dis-le et propose des données de démonstration réalistes. L'ensemencement nécessite un oui explicite, va dans une base de données séparée ou jetable, et la base de développement n'est jamais touchée sans accord. Préfère les états que l'interface peut créer (ajouter des articles au panier) plutôt que des écritures en base.
- N'ajoute pas de dépendances ou de fichiers au projet de l'utilisateur. Les scripts vivent dans le scratchpad.
5. Capture
Écris un script scratchpad qui importe capturePages depuis <this skill>/scripts/capture.mjs :
import { capturePages } from '<this skill>/scripts/capture.mjs';
const results = await capturePages({
frameKit: '<frame-kit>', outDir: '<raw dir>', colorScheme: 'light', // un schéma pour le lot
storageState: process.env.APP_STORAGE_STATE, // session sauvegardée ; ou login: async (page) => {...} lisant process.env
setup: (ctx) => ctx.addInitScript(() => localStorage.setItem('theme', 'light')), // le propre sélecteur de thème de l'application, le cas échéant
pages: [{ name: '01-dashboard', url: 'http://localhost:8000/admin', prepare: async (page) => { /* ouvrir le panier, fermer le tour… */ } }],
});
console.log(JSON.stringify(results, null, 2));
Il utilise un contexte 1440×900 @2x pour tout le lot (les PNG font 2880×1800), attend que le réseau soit inactif, les polices et le contenu lazy, et rapporte les issues par page : erreurs console/page, HTTP ≥ 400, redirections (souvent une connexion manquante), images cassées, spinners/squelettes visibles, overlays/bannières de cookies, conteneurs de graphiques vides. Nomme les fichiers NN-<slug>.png dans l'ordre de la proposition. Passe les propres sélecteurs de l'application via loadingSelectors/overlaySelectors/hideCss (toasts, barres de débogage).
Les écrans interactifs (panier, éditeur, tableau) nécessitent d'abord d'ajouter du contenu d'exemple dans prepare.
Pour chaque page avec des problèmes : corrige-les (ferme l'overlay, attend l'élément, connecte-toi) et ne rephotographie que cette page ; ou dis à l'utilisateur qu'elle est irréparable et abandonne-la. Un avertissement que tu juges inoffensif (par exemple une 404 de favicon) est acceptable ; dis-le. Ensuite, lis chaque PNG : contenu réel, rien de semi-chargé, aucune donnée privée (emails, tokens, vrais noms de clients) qui ne devrait pas être publiée ; vérifie avec l'utilisateur en cas de doute.
6. Encadrer
Exécute les étapes 2 à 4 de generate-frame avec le dossier brut en entrée : --out <framed dir>, --url "<app host>/{name}", un --resolution (par défaut max). Un échec partiel est signalé, pas caché : ne rephotographie ou ne réencadre que les fichiers en échec. Rapporte le dossier brut, le dossier encadré, la paire de couverture, les pages abandonnées et pourquoi, et toute limitation (par exemple images non inspectées).