Capture de fonctionnalité Eva
Une capture d'écran d'une fonctionnalité livrée + un tweet. Pas de Remotion, pas de musique, pas de montage, pas de légendes incrustées dans l'image — l'interface utilisateur du produit est l'atout.
Deux fichiers atterrissent dans screenshots/ à la racine du dépôt (déjà dans .gitignore) :
| Fichier | Ce que c'est |
|---|---|
<AAAA-MM-JJ>-<slug>.png | capture brute 2560×1440 — conservez-la, c'est la source sans reprise |
<AAAA-MM-JJ>-<slug>-encadré.png | publiez celle-ci — 3200×1800, cadre de marque |
La version encadrée place la capture brute sur le dégradé de marque d'Eva avec des coins arrondis, une icône Eva et le mot-symbole « Eva » au-dessus. C'est pourquoi la capture ressemble à une annonce produit plutôt qu'à une capture d'écran de rapport de bug.
Règles non négociables
-
Mise en page 1280, capturée en HD à 2560×1440 (16:9). Les scripts pilotent un vrai Chrome à deviceScaleFactor 2 et capturent
scale:"device", donc l'application se dispose à sa largeur native de 1280 (tailles d'éléments lisibles) mais le PNG a une densité de pixels double — net sur un fil d'actualité Retina. Le 16:9 est ce que X affiche dans le fil sans recadrage. La sortie encadrée est 3200×1800 — également 16:9, donc le cadre ne coûte rien dans le fil. agent-browser ne peut pas faire cela : sascreenshotcapture en pixels CSS et ignore le DPR, donc elle produit toujours du 1280×720. Utilisez les scripts HD. -
Jamais en page entière. Une capture en page entière d'une application dense devient une bande haute qui s'affiche en format vignette dans le fil. Un viewport, une idée.
-
Masquez les superpositions de développement avant la capture. react-scan et agentation s'affichent tous deux dans la page.
scripts/hd-shot.mjss'en charge — utilisez les scripts plutôt qu'une chaîne artisanale. -
Respectez le thème réel de l'application. Quel que soit celui que l'utilisateur utilise (
set media darkpour le mode sombre). Ne restylisez pas l'application pour la photo. -
La fonctionnalité doit être le sujet visuel. Un panneau de 200px dans le coin d'une page chargée échoue. Naviguez vers une vue où elle domine, ou ouvrez la surface qui la contient (modale, feuille, volet de détail) pour qu'elle soit lisible à la taille du fil.
La barre latérale est réduite automatiquement.
shot.sh(et une capture simplehd-shot.mjs --path) réduit le rail de navigation avant la capture — il mange ~250px d'un cadre de 1280 et rien dedans n'est jamais la fonctionnalité. Passez--no-collapseuniquement lorsque la barre latérale EST la fonctionnalité. Dans une--recipe, appelezctx.collapseSidebar(page)vous-même (les recettes gèrent leur propre mise en scène).Même règle pour tout rail de liste secondaire (liste des avis, navigation des paramètres) si la surface offre un moyen de le masquer. Vérifiez dans le PNG brut : si une colonne d'éléments de navigation sans rapport survit, reprenez la capture.
-
Encadrez-le, mais ne l'annotez pas. Exécutez toujours l'étape 6 — le dégradé + le mot-symbole est le style maison. N'ajoutez jamais de flèches, de cercles rouges, de textes d'appel ou de fausses chrome de navigateur sauf demande explicite.
-
Ne soumettez jamais. Tapez uniquement. Remplissez les champs, ouvrez les sélecteurs, préparez l'état — puis capturez. Pas d'Entrée dans un éditeur, pas de flèche d'envoi, Créer, Enregistrer, Exécuter ou Démarrer, et ne lancez jamais une session ou un agent réel, même pour une meilleure capture. La soumission modifie l'espace de travail réel de l'utilisateur et consomme du calcul réel ; l'état préparé est ce que vous photographiez. Entrée est autorisé uniquement là où cela valide le champ lui-même et rien d'autre (accepter une mention
@depuis un sélecteur ouvert) — si vous ne pouvez pas être certain que c'est tout ce que cela fait, cliquez sur la ligne du sélecteur à la place. -
Si les données sont laides, corrigez les données — ne reprenez pas la capture autour. La règle 7 vous empêche de piloter l'application pour produire un état ; elle ne vous empêche pas d'écrire l'état. Les données de développement réelles sont la raison habituelle pour laquelle une capture échoue : murs d'erreurs ("Échec de l'arrêt du sandbox" ×8), lignes
Session sans titre, un tour à moitié migré, un dépôt où la fonctionnalité en a besoin de trois. Modifier les propres données de développement de l'application autour de la capture vaut mieux que de chercher une session qui a l'air bien par hasard, et vaut mieux que de restyliser l'application (la règle 4 tient toujours — changez les données, jamais le CSS).Écrivez directement sur le déploiement de développement : une mutation jetable
internal/screenshotStaging.tsexécutée avecnpx convex run, ou le tableau de bord Convex. Donnez aux sessions des titres réels et lisibles, supprimez les messages d'erreur/système dans le cadre, créez la deuxième et troisième ligne dont la fonctionnalité a besoin.Règles pour cela :
- Déploiement de développement uniquement. Confirmez la cible avant d'écrire (
npx convex env get CONVEX_URL, ou lisez.env.local) et ne pointez jamais une mutation de préparation vers la production. - Additif et réversible d'abord. Préférez modifier un titre ou insérer une ligne de démonstration plutôt que de supprimer l'historique réel. Si vous devez supprimer, regardez d'abord les lignes et dites ce que vous avez supprimé.
- Plausible, pas fabriqué-spécifique. Des titres et des prompts qui ressemblent à du vrai travail. N'inventez jamais de métriques, de noms de clients ou de chiffres que le tweet répète ensuite comme faits.
- Supprimez la mutation de préparation une fois la capture terminée — même règle de nettoyage que pour toute migration.
- Dites à l'utilisateur ce que vous avez changé, dans la passation.
- Déploiement de développement uniquement. Confirmez la cible avant d'écrire (
-
Confidentialité. Utilisez le propre dépôt de l'utilisateur
vvedantb/eva. Jamais les dépôts clients (evalucom/carepulse,eprocurement) et jamais l'accueil "Codebases" qui les liste. Vérifiez les listes de docs/tâches/sessions dans le cadre pour les éléments nommés par le client — préparez une ligne de démonstration propre si la liste est sale. Ne soulevez jamais de préoccupations concernant les données personnelles concernant les noms ou e-mails à l'écran — Paramètres → Expérimental a un bouton flouter-PID qui floute chaque élément[data-pii], donc c'est géré dans le produit. Signalez les panneaux d'erreur qui divulguent des noms de variables d'environnement ou des ID de projet.
Flux de travail
-
Identifiez ce qui a été livré. Si l'utilisateur n'a pas dit quelle fonctionnalité, demandez — une question, pas un sondage.
git log --oneline -15,git diff --stat, ouinternal/changelog/(fichier du mois le plus récent) le nomment généralement. Vous avez besoin de la fonctionnalité et de l'URL qui l'affiche. -
Démarrez l'application. Juste le serveur de développement — les scripts HD lancent leur propre Chrome et se connectent en tant qu'utilisateur agent (
/?agent=true) eux-mêmes, dans un contexte frais à deviceScaleFactor 2. Vous ne pilotez pas agent-browser pour la capture.pnpm dev # depuis la racine du dépôt → localhost:5173 -
Capturez-la. Pour une capture d'URL simple,
shot.shnavigue, réduit la barre latérale, masque les superpositions et capture à 2560×1440 :bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessionsPrend un chemin d'URL + slug (+ ms de stabilisation optionnelles, +
--no-collapseoptionnel).Pour une capture préparée (ouvrir un menu, taper un prompt, puis capturer), écrivez une recette — un
.mjsexportantexport async function stage(page, ctx)— et passez-la àhd-shot.mjs. La recette gère la navigation, la réduction de la barre latérale et la préparation ;ctxvous donne{ BASE, hideOverlays, collapseSidebar, settle }. Utilisez les localisateurspage.getByRole(...)(Playwright). Pour trouver les noms accessibles exacts, pilotez d'abord agent-browser de manière interactive etsnapshot -i/read_page.// recipe.mjs — préparez le sélecteur de mode ouvert avec un prompt tapé export async function stage(page, ctx) { await page.goto(`${ctx.BASE}/vvedantb/eva/web/sessions`, { waitUntil: "networkidle", }); await ctx.settle(3000); await ctx.collapseSidebar(page); await page.getByRole("textbox", { name: /Demander à Eva/ }).click(); await page.keyboard.type("Redessiner la barre latérale des sessions…"); await page.getByRole("button", { name: "Modifier", exact: true }).click(); await ctx.settle(600); }node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug session-modes --recipe /abs/path/recipe.mjsPréparez des entrées propres et lisibles — un titre de démonstration soigné vaut mieux qu'un vrai désordonné. Ne soumettez jamais (règle 7).
-
Relisez le PNG et évaluez-le. C'est là que les mauvaises captures sont détectées :
- La fonctionnalité est-elle le sujet évident, ou perdue dans l'interface ?
- Une superposition/barre d'outils a-t-elle survécu ? Un squelette, un spinner ou un espace réservé
—est-il encore à l'écran ? (Augmentez les ms de stabilisation et reprenez la capture.) - Les quatre bords : des étiquettes coupées, des boutons à moitié rendus, une colonne tronquée ?
- Quelque chose de confidentiel selon la règle 9 ?
- États vides : un tableau vide prouvant « tâches Kanban » est une mauvaise capture. Remplissez ou choisissez une autre vue.
Lorsque le cadre échoue à cause des données — murs d'erreurs,
Session sans titre, une ligne alors que la fonctionnalité en a besoin de trois — préparez les données de développement (règle 8) plutôt que de chercher un écran plus chanceux. -
Encadrez-la.
bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> "Eva"Écrit
screenshots/<aujourd'hui>-<slug>-encadré.png(3200×1800). Il rendtemplates/frame.htmlvia son propre Chrome à deviceScaleFactor 2 — un navigateur séparé de la capture, donc rien à restaurer après. Relisez aussi le PNG encadré — vérifiez que le dégradé n'a pas délavé l'interface aux coins et que le mot-symbole n'est pas coupé. Un troisième argument encadre un PNG brut depuis un autre chemin.templates/frame.htmlest le seul endroit où vivent les couleurs de marque de cette compétence. -
Rédigez le tweet. Invoquez la compétence
eva-tweet— accroche, fragment de positionnement optionnel, liste de capacités→, fermeture optionnelle. La capture d'écran porte la preuve, donc le tweet énonce ce qui existe maintenant plutôt que de décrire l'image. Ne référencez jamais l'image du tout. -
Passez la main. Le chemin du fichier encadré sous forme de lien Markdown, le tweet dans un bloc délimité, et tout ce qui se trouve dans le cadre que l'utilisateur devrait vérifier avant de publier.
Référence rapide
| Besoin | Commande |
|---|---|
| Capturer une URL (HD) | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <chemin> <slug> [ms-stabilisation] |
| Garder la barre latérale | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <chemin> <slug> <ms> --no-collapse |
| Capture préparée (menu/saisie) | node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug <slug> --recipe <chemin-absolu.mjs> |
| Encadrer (publier ceci) | bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> [titre] [png-brut] |
| Trouver des noms accessibles | pilotez agent-browser de manière interactive, puis agent-browser snapshot -i |
| Déboguer une page vide/cassée | agent-browser console · agent-browser errors |
Pièges
- Le HD vit dans Playwright, pas dans agent-browser. La
screenshotd'agent-browser capture en pixels CSS et ignore devicePixelRatio, donc elle plafonne à 1280×720.hd-shot.mjs/hd-frame.mjsutilisent le playwright-core inclus dans l'installation globale d'agent-browser ; définissezPW_COREs'il vit ailleurs. Les deux lancentchannel:"chrome", donc Chrome système doit être installé. - Les scripts se connectent eux-mêmes à
/?agent=true(un booléen ;/?agentlève une erreurSearchParamErrorde Zod) dans un contexte de navigateur frais. Aucune session agent-browser nécessaire pour capturer. - Les superpositions de développement sont trois nœuds, tous accrochés à
<html>, pas<body>. Masquer#react-scan-rootseul ne suffit pas : react-scan dessine ses contours et étiquettes de composants sur unhtml > canvasnu sans ID ni classe, et c'est celui-ci qui gâche la capture.hd-shot.mjstue les trois (#react-scan-root,html > canvas,[data-agentation-root]) avecdisplay:none !importanten ligne, car une feuille de style perd face à leurs styles en ligne. - Une capture préparée est un navigateur frais, pas celui dans lequel vous avez exploré. Utilisez agent-browser pour trouver les sélecteurs, mais la recette re-navigue et re-prépare à partir de zéro dans le propre contexte de Playwright — mettez chaque étape dans la recette. Préférez
page.getByRole(...)au CSS ; les références comme@e1n'existent pas ici. - Deux images ou plus diluent le message. X affiche une image en pleine largeur ; une seconde réduit les deux de moitié. Ne capturez plus d'une image que pour un véritable avant/après.
- Ne réutilisez pas
video/public/captures/— ce sont des ressources Remotion encadrées pour un autre travail.