Que fait agentshot : captures d'écran et vidéos de démonstration ?
L'outil se trouve dans /path/to/agentshot. Exécutez-le comme suit :
node /path/to/agentshot/bin/agentshot.mjs <commande> ...
Ci-dessous, agentshot désigne cette commande. Chaque commande imprime une ligne JSON ("ok": true|false). Les longs rendus impriment également la progression sur stderr.
Exécutez agentshot help pour la liste des commandes.
Flux de travail
- Lisez d'abord les règles du produit :
agentshot style <produit>imprimestyle.json(aspect par défaut) etguidelines.md(ce que l'utilisateur aime). Suivez-les. Si le produit est nouveau, exécutezagentshot style <produit> --init. - Capturez (choisissez une option) :
- Application Web ou Expo → écrivez un JSON de scénario avec
"url", exécutezagentshot capture scenario.json. - Application iOS sur Mac → un scénario avec
"simulator"(l'application native réelle dans le simulateur iOS, voir "Simulateur iOS") ; une image fixe rapide →agentshot sim snap --name <capture> --clean-status-bar. - Programme de bureau → un scénario avec
"window": vous contrôlez la souris/le clavier pendant qu'il enregistre (voir "Application de bureau"). Juste une image fixe →agentshot snap --window "<titre>" --name <capture>. L'utilisateur effectue les actions →agentshot record start/stop. - L'utilisateur a déjà un fichier (capture d'écran iPhone / enregistrement d'écran) →
agentshot import <fichier> --name <capture>.
- Application Web ou Expo → écrivez un JSON de scénario avec
- Inspectez :
agentshot inspect <capture>liste les scènes, les boîtes d'éléments (points écran), les clics, la durée et, pour les vidéos, lesmoves(déplacements du pointeur),changes(changements de page : grands sauts visuels),quiet(rien ne bouge : coupe ou accélère) et latimelinedu scénario. Planifiez les coupes et les zooms à partir de ces nombres, puis confirmez avecagentshot frames <capture> --from a --to b(une planche contact avec horodatages ; Lisez le PNG qu'il imprime). Regardez le PNG de la scène avec l'outil Read avant de styliser. - Écrivez une recette JSON et
agentshot render recipe.json --note "<ce qui a changé>". - Vérifiez vous-même le résultat : Lisez le PNG ; pour MP4,
agentshot frames <produit>/<ressource>(vidéo entière) etagentshot frames <produit>/<ressource> --from 3 --to 4 --every 0.033 --crop x,y,w,h(image par image autour d'une coupe ou d'un clic). Corrigez et rendez à nouveau (une nouvelle version est ajoutée). Lorsque l'utilisateur souhaite parcourir ou modifier lui-même une recette, exécutezagentshot preview recipe.jsonen arrière-plan : cela ouvre une page locale avec la scène et un curseur de défilement et se met à jour en direct lorsque la recette (ou lestyle.jsondu produit) est modifiée. Cela imprime une ligne JSON avec l'urlet continue de servir. - Signalez le chemin de sortie (
results[].output).--copy-to <dir>le copie également dans le projet de l'utilisateur. - Apprenez : lorsque l'utilisateur corrige ou félicite quelque chose, ajoutez une ligne datée au
guidelines.mddu produit (et mettez à jour les paramètres par défaut destyle.jsons'il s'agit d'un aspect par défaut). Relisez-le la prochaine fois.
Conservez les scénarios et les recettes dans le projet de l'utilisateur (par exemple docs/shots/) afin qu'ils puissent être réexécutés après des modifications de l'interface utilisateur.
Scénario (capturer une application web)
Les commentaires dans les exemples JSON ci-dessous sont des explications uniquement ; les fichiers réels doivent être du JSON simple.
{
"name": "ellie-today-drag", // nom de la capture, unique ; préfixez avec le produit
"url": "http://localhost:8081", // ou un chemin de fichier
"device": "iphone", // iphone | iphone-max | ipad | desktop | laptop
"safeArea": true, // Expo/RN web : Chrome signale les marges de sécurité iPhone, l'application se dispose
// comme sur un appareil ("pad" = force le remplissage pour les applications qui ignorent les marges)
"css": "[class*='navigationMenuRoot'] { display: none }", // masque le chrome web uniquement (les onglets Expo Router s'affichent comme un menu en haut sur le web)
"waitFor": "today-list", // attend cet élément avant de commencer
"track": { "row": "text=Plan a birthday" }, // boîtes d'éléments nommées supplémentaires à enregistrer
"steps": [
{ "shot": "main" }, // image fixe en pleine résolution (pour les captures d'écran)
{ "wait": 0.6 },
{ "tap": "add-button" }, // cliquer/appuyer sur une cible (s'y déplace d'abord)
{ "type": "Buy milk", "into": "title-input" },
{ "press": "Enter" },
{ "drag": "task-birthday", "to": "slot-11am", "duration": 1.4 },
{ "scroll": 400, "duration": 0.8 },
{ "move": [200, 300], "duration": 0.6 },
{ "goto": "/settings" },
{ "waitFor": "settings-title" },
{ "shot": "after" }
]
}
Cibles : un nom nu correspond à data-shot="..." ou data-testid="..." (le testID React Native devient data-testid sur le web, donc ajoutez des testID aux éléments que vous souhaitez cibler), ou tout sélecteur Playwright (text=Save, role=button[name="Save"], #id, .class), ou [x, y] en px CSS.
Tous les éléments avec data-shot/data-testid sont enregistrés avec leurs boîtes, ainsi que les entrées track.
Timing : par défaut ("timing": "frame"), l'horloge de la page est mise en pause et avancée exactement d'une image à la fois (60 ips) avec une capture d'écran en pleine résolution par image, de sorte que les animations de l'application sont fluides à n'importe quelle résolution ; la capture prend quelques fois plus de temps que le scénario. Utilisez "timing": "real" uniquement si l'application se brise avec une horloge contrôlée (une étape expire alors). agentshot capture signale les temps de clic (clicks) pour planifier les cuts/zoom, et les erreurs/avertissements de la console (console). Les superpositions de développement (toast Expo LogBox, indicateur Next.js) sont masquées ; "devOverlays": true les conserve.
Préférez un segment cuts continu plutôt que plusieurs coupes dures : les sauts entre les segments donnent un aspect saccadé.
Trouver des cibles dans une application sans testIDs : ouvrez la page avec Playwright et listez les boutons/entrées (role, aria-label, texte), puis utilisez text=..., role=button[name=/^My daughter/] ou [aria-label='Your prayer'], et nommez les boîtes que vous souhaitez surélever/louper via track.
La saisie dans un champ recouvert par un pied de page collant fonctionne toujours (le champ obtient le focus).
Expo : démarrez d'abord la version web (npx expo start --web, généralement http://localhost:8081). Les modules natifs uniquement peuvent ne pas fonctionner sur le web ; si un écran se brise, demandez à l'utilisateur une capture d'écran/enregistrement iPhone et importez-le.
Application de bureau (scénario avec "window")
agentshot windows liste les fenêtres (titre, processus, taille). La fenêtre est identifiée par son titre, puis par son nom de processus, restaurée si elle est minimisée et amenée au premier plan. Les coordonnées sont en pixels de la fenêtre : regardez d'abord une image fixe (agentshot snap --window "X" --name x-probe, Lisez le PNG) et nommez les boîtes que vous utilisez dans track.
{
"name": "notes-tour",
"window": "Notes", // partie du titre ou nom du processus
"track": { "nav-recent": [20, 200, 190, 40], "nav-search": [20, 96, 190, 40], "content": [232, 40, 1030, 650], "profile": [16, 718, 150, 62] },
"cursor": [1000, 330], // où le pointeur commence
"steps": [
{ "shot": "home" }, // image fixe = l'image enregistrée à ce moment
{ "wait": 1 },
{ "click": "nav-recent", "duration": 0.9 }, // glisser là (assoupli, léger arc), cliquer immédiatement
{ "waitStill": 0.6, "region": "content" }, // attendre que l'écran change, puis se stabilise
{ "shot": "recent" },
{ "wheel": 4, "at": [760, 460] }, // faire défiler 4 crans vers le bas (négatif = vers le haut)
{ "click": "nav-search" }, { "press": "ctrl+a" },
{ "type": "Weekly plan", "cps": 12 }, // n'importe quel texte, scripts non latins inclus
{ "press": "Enter" }, // touches : enter esc tab space backspace delete arrows home end f1..f12, ctrl/alt/shift/win+x
{ "drag": [100, 300], "to": [400, 300], "duration": 1.2 },
{ "click": [640, 400], "button": "right" }, { "click": [640, 400], "double": true },
{ "note": "beat 2" } // marqueur dans la timeline
]
}
-
Le résultat a une
timeline(début/fin de chaque étape en secondes vidéo,at= moment du clic) et desshots(images fixes extraites de la vidéo). Les recettes utilisent les nomstrackcomme cibles ("blur"sur"profile"etc.). -
waitStillattend d'abord (jusqu'àchangeTimeout, 3 s) que la région diffère de ce qu'elle était (change, différence de pixel moyenne, par défaut 6 ;"change": falsepour seulement la laisser se stabiliser), puis jusqu'à ce que rien n'ait changé pendant les secondes données (threshold0.6). Utilisez uneregionsans parties animées (lecteurs, arrière-plans en direct). -
Cliquez immédiatement après l'arrivée : un curseur reposant sur un contrôle ~0,5 s fait apparaître des info-bulles Windows dans la vidéo.
-
Champs qui conservent l'ancien texte :
press ctrl+aavanttype. -
Le pilote démarre avant l'enregistrement (il a besoin de quelques secondes) et déplace le curseur réel : n'utilisez pas la machine pendant ce temps. Les captures de bureau sont en 1x, donc une loupe semble molle ; préférez
lift. -
Images fixes à tout moment d'un enregistrement :
agentshot snap <capture> --at 12.4 --shot name. -
Les petits changements (fermeture d'une popup) peuvent ne pas atteindre
changesur toute la fenêtre : donnezregionautour d'eux. -
Raccourcis :
modest Ctrl sur Windows et Cmd sur macOS ("press": "mod+a"), donc un scénario fonctionne sur les deux.
Enregistrement manuel (l'utilisateur effectue les actions ; le curseur est enregistré et dessiné par le moteur de rendu) :
agentshot record --name app-filter --window "Figma" --duration 12 # enregistre 12 s, puis s'arrête
agentshot record start --name app-filter --window "Figma" # ou démarrer ...
agentshot record stop # ... et arrêter plus tard
macOS
Mêmes commandes et scénarios que sous Windows ; recorder/mac.swift est compilé lors de la première utilisation (nécessite les outils de ligne de commande Xcode et macOS 14+). Exécutez d'abord agentshot doctor : l'application qui exécute l'agent (Terminal, iTerm, Claude, VS Code) a besoin des autorisations Screen Recording et Accessibility dans Réglages Système > Confidentialité et sécurité (agentshot doctor --request ouvre les invites ; redémarrez cette application après avoir accordé). Sans Screen Recording, les titres de fenêtre sont juste des noms d'application et l'enregistrement échoue ; sans Accessibility, le pilote ne peut pas cliquer ni taper.
- Les coordonnées (
track, étapes, cibles de recette) sont des points ; les images fixes et les vidéos sont à l'échelle de pixels de l'écran (2 sur Retina,inspectmontrescale), donc les surélévations et les zooms restent nets. - ScreenCaptureKit enregistre la fenêtre elle-même : elle peut être partiellement couverte, mais ne doit pas être minimisée.
node scripts/selftest-mac.mjsvérifie tout sur TextEdit (et le simulateur s'il est démarré) et imprime ce qui a échoué. Vérification de synchronisation :agentshot record ... --show-cursorgrave le curseur réel ; comparez-le avec le pointeur enregistré (agentshot framesvsinspect) comme tout enregistrement.
Simulateur iOS (macOS)
L'application native au lieu de sa version web : polices réelles, modules natifs, animations iOS. Démarrez un simulateur (open -a Simulator), exécutez l'application dedans (npx expo run:ios ou une build de développement), puis :
agentshot sim devices # simulateurs démarrés
agentshot sim snap --name app-home --clean-status-bar # image fixe sans perte, 9:41 / batterie pleine
agentshot sim record start --name app-flow # quelqu'un d'autre pilote ...
agentshot sim record stop
Un scénario le pilote avec idb (brew install facebook/fb/idb-companion, pipx install fb-idb) ; les coordonnées sont en points de l'appareil (Lisez un sim snap et divisez ses pixels par scale) :
{
"name": "app-onboarding",
"simulator": "booted", // ou un UDID ou une partie du nom de l'appareil
"statusBar": "clean", // 9:41 pendant la capture, effacé après
"appearance": "light", // ou "dark"
"openUrl": "exp://127.0.0.1:8081/--/today", // lien profond avant l'enregistrement (ou "launch": "<bundle id>")
"track": { "add": [330, 760, 48, 48], "title": [24, 120, 340, 44] },
"steps": [
{ "shot": "today" },
{ "tap": "add" },
{ "waitStill": 0.5 },
{ "type": "Buy milk" }, // dans le champ focalisé
{ "press": "enter" }, // enter esc backspace tab space arrows home lock
{ "swipe": [200, 600], "to": [200, 250], "duration": 0.4 },
{ "openUrl": "exp://127.0.0.1:8081/--/settings" },
{ "waitStill": 0.6 },
{ "shot": "settings" }
]
}
Les images fixes sont des captures d'écran du simulateur sans perte ; les tapotements et les balayages deviennent le pointeur tactile et les clics, donc les recettes utilisent "pointer": "touch" et "device": "iphone-black" comme pour les captures de navigateur. Sans idb, seules les étapes wait/waitStill/agentshot/openUrl/launch fonctionnent.
Recette (style et rendu)
{
"name": "today-drag", // nom de la ressource dans la bibliothèque
"product": "ellie", // dossier de la bibliothèque ; les valeurs par défaut de style.json s'appliquent
"capture": "ellie-today-drag",
"shot": "main", // défini pour une image PNG ; omettez pour une vidéo MP4
"size": "16:9", // 16:9 16:10 4:3 3:2 1:1 4:5 9:16, ou largeur/hauteur
"background": "lavender", // lavender peach sage sky rose mint neutral midnight ink white,
// toute couleur CSS/dégradé, ou une image sous public/ (backgrounds/x.jpg)
"backgroundBlur": 0.02, // pour les arrière-plans photo, part du petit côté
"device": "iphone-black", // iphone-black iphone-natural iphone-white browser window none
"url": "app.ellie.so/today", // texte de la barre de navigateur ; "title": titre de fenêtre pour "window"
"padding": 0.08, "tilt": 12, // marge de l'appareil ; inclinaison 3D en degrés
"position": [0.69, 0.5], // centre de l'appareil sur le canevas, laisse de la place pour un titre à côté
"accent": "#6d5ce8", // couleur des étapes, contours, étiquettes, ondulations de clic
"font": "Gilda Display", "labelFont": "Inter", // titres / étiquettes de surélévation : Inter Manrope Poppins Nunito Fraunces Lora
// "Playfair Display" "DM Serif Display" "Gilda Display" "Cormorant Garamond" Caveat
"lift": { "target": "task-row", "label": "Glissez-le sur votre journée", "start": 3.9, "pad": 10, "dim": 0.1 },
"loupe": { "target": "label-chip", "anchor": [0.2, 0.5], "zoom": 2.3, "size": 0.12, "offset": [-0.15, 0.12] },
"annotations": [
{ "type": "arrow", "from": [0.7, 0.15], "to": [0.35, 0.42], "note": "Ajoutez une tâche", "start": 2.3, "duration": 1.5, "outline": 0.01 },
{ "type": "step", "at": [0.12, 0.05], "number": 1, "label": "Ouvrir aujourd'hui", "start": 0.6, "duration": 2.5 },
{ "type": "highlight", "target": "slot-11am", "start": 7.8, "duration": 1.2 },
{ "type": "label", "at": [0.7, 0.92], "label": "Déplacement d'une tâche", "start": 7, "duration": 2.5, "outline": 0.006 },
{ "type": "blur", "target": "profile", "start": 8, "duration": 5 },
{ "type": "cut", "start": 5, "duration": 1 },
{ "type": "delay", "start": 5, "duration": 1 },
{ "type": "speed", "start": 1.5, "duration": 6.7, "rate": 2 }
]
}
- Sauf
cut, les annotations commencent lorsque le compteur vidéo atteint leurstart(et durentdurationsecondes, ou"fade": 0pour disparaître immédiatement). Les annotations omettentstart/durationsi elles sont affichées tout le temps (utilisezmaxStart/minDurationdans l'annotation d'image PNG). cutetdelay: voir ci-dessous.speed:rate2 = 2× plus rapide, 0,5 = 2× plus lent ;"rate": 0coupe (jette) ce segment.blurethighlightciblent des élémentstracknommés ;highlightencadre la cible,blurrend tout flou sauf la cible."blur": 0.08utilise des rectangles de flou au lieu d'un masque de gradient (pas de rupture de l'effet de profondeur de champ).stepconnaît le compte :step 2continue là oùstep 1s'est arrêté (connaît les trous de timing)."step": { "target": "task-row", "number": 3, "label": "of 4", "anchor": "below" }.steppeut être placé hors de la vidéo, en ayant unstartavant/après le métrage, en utilisant un nombre négatif pour l'ordre des étapes.arrowen points utilisateur (de l'image ; 0…1 x, puis y = centre) ou"target": "add-button"pour pointer sur l'écran capturé.label: idem.- Tout
outline(contour en fraction de la largeur, 0,01 ≈ 12 px sur un écran Retina) ajoute une bordure lumineuse. Omettre = pas de bordure. Les annotations qui omettentoutlinen'en ont pas ; définir"outline": 0.006dessine un trait de 7 px.
Coupes et délais
Les annotations cut / delay sont différentes : elles n'ont pas d'effet visuel mais contrôlent le métrage.
{ "type": "cut", "start": 3, "duration": 1.2, "fade": 0.15 }
{ "type": "delay", "start": 6.8, "duration": 0.35 }
cut: flou de transition entrestartetstart + duration; la vidéo coupe les images à la fin (les images 5 x,fade0,15 s). Pour une coupe dure avec le curseur au même endroit, utilisezduration: 0.16.fadepar défaut =duration * 0.3(la première bosse ralentit donc les choses). À l'intérieur descutsla vidéo est mise en pause (lesstepssont ignorées) ; après la coupe, lesstepscontinuent normalement.delay: la vidéo se fige (la dernière image avant le délai) pendantduration. Pour permettre à une animation de se terminer, utilisezdelayavantcut.
Utilisez les informations des inspect et frames : les changes (sauts visuels) et quiet (pauses) indiquent où couper, et les moves indiquent le déplacement du curseur que vous pouvez ignorer.
Aperçu
Lors du débogage, exécutez agentshot preview recipe.json en arrière-plan pendant que l'utilisateur modifie la recette avec un éditeur. Ouvrez l'URL imprimée : la page affiche la scène avec un curseur de défilement. Chaque fois que la recette ou le style.json du produit est enregistré, la page se recharge. L'aperçu imprime une ligne JSON avec l'url et continue de servir.
Guide de style (style.json)
Exécutez agentshot style <produit> pour voir le style actuel. Les recettes omettent les champs et les valeurs par défaut viennent d'ici. Les valeurs par défaut initiales de agentshot style --init : agentshot style <produit> --init > style.json.
{
"accent": "#6d5ce8",
"font": "Inter",
"labelFont": "Inter",
"background": "mint",
"device": "iphone-black",
"size": "16:9",
"padding": 0.08,
"tilt": 0,
"position": [0.5, 0.5],
"backgroundBlur": 0.02,
"pointer": "hand",
"cornerRadius": 16,
"shadow": 0.08,
"brandPosition": "bottom left",
"brandLogo": null
}
Tous les champs des recettes et ici sont facultatifs ; les valeurs par défaut codées en dur complètent le reste.
pointer:hand,touch,none(pointeur de souris / cercle tactile).shadow: ombre de l'appareil (partage de la largeur).brandPosition:top left,top right,bottom right,bottom leftounone.brandLogoest un chemin d'accès à un fichier image souspublic/; par défautbrand.svgdans le dossier du produit, ou un visuel générique."brandLogo": nullmasque la marque,brandPosition: "none"aussi.backgroundBlurest ignoré pour les couleurs unies (lavender, mint, …).
Photos comme arrière-plan
Placez les images d'arrière-plan sous public/backgrounds/ (ou dans le dossier du produit).
{
"background": "pexels-kampus.jpg",
"backgroundBlur": 0.08
}
Référencez-les par leur nom de fichier (pexels-kampus.jpg) ou leur chemin relatif (../shared/prints.jpg).
Commandes CLI
Ces commandes aident à trouver des cibles, tester des recettes et résoudre des problèmes.
agentshot doctor
Vérifie l'environnement : versions de Node.js, Playwright, macOS Screen Recording / Accessibility. Recommande des correctifs.
agentshot doctor
agentshot doctor --request # Demande les autorisations macOS (redémarrez l'application après)
agentshot style <produit> [--init]
Imprime style.json et guidelines.md pour le produit. --init les initialise avec les valeurs par défaut.
agentshot capture <scenario.json>
Exécute le scénario de capture et enregistre la capture dans la bibliothèque.
agentshot inspect <capture>
Liste les scènes, les boîtes d'éléments, les clics, la timeline et les métadonnées.
agentshot frames <capture> [--from s] [--to e] [--every s] [--crop x,y,w,h] [--shots]
Génère une planche contact PNG (par défaut une image par seconde du métrage principal). --shots affiche uniquement les images fixes nommées. --crop x,y,w,h recadre – utile pour inspecter la région quiet / change autour des coupes.
agentshot list [<produit>] [--all-users]
Liste les captures et les ressources rendues.
agentshot render <recipe.json> [--note <msg>] [--version l] [--no-version] [--copy-to <dossier>]
Rend la ressource. --note est stocké dans le journal des versions. --version 0 écrase une version existante.
agentshot preview <recipe.json>
Lance un serveur local avec une page de prévisualisation interactive.
agentshot snap <capture> [--at s] [--shot name]
Image PNG fixe à partir d'une capture existante.
agentshot windows
Liste les fenêtres de bureau (titre, processus, taille).
agentshot snap --window "<titre>" --name <capture>
Capture d'écran fixe d'une fenêtre de bureau.
agentshot import <fichier> --name <capture>
Importe une image/vidéo existante.
agentshot record start/stop
Enregistrement manuel d'une fenêtre de bureau.
agentshot sim devices
Liste les simulateurs iOS démarrés.
agentshot sim snap/record
Capture d'écran/enregistrement du simulateur iOS.
agentshot help [<commande>]
Aide détaillée.
Bibliothèque et versionnement
Les captures et les ressources sont stockées sous ~/.agentshot/<produit>/. Tous les fichiers sont versionnés :
~/.agentshot/ellie/
├── captures/
│ └── ellie-today-drag/v1/
│ ├── snap.mp4 # vidéo brute
│ ├── scenario.json
│ └── meta.json
├── today-drag/v1/
│ ├── recipe.json
│ ├── snap.png # ressource rendue
│ └── meta.json
├── today-drag/v2/
│ └── …
├── style.json
└── guidelines.md
agentshot render crée automatiquement la prochaine version v{n+1}, sauf si --version est spécifié. --no-version l'écrit directement sans numéro de version (pour les exports uniques). --copy-to <dossier> copie le(s) fichier(s) de sortie (snap.png, snap.mp4) vers le projet de l'utilisateur.
agentshot list n'affiche que les ressources (pas captures).
Notes techniques
- Pilote de bureau : utilise
node-ffi(Windows) ou un binaire Swift compilé (macOS) pour déplacer la souris et taper. Un délai de 3 s au démarrage pour laisser l'utilisateur dégager la main. - Web : Playwright avec une horloge contrôlée (ou en temps réel). Les captures sont en pleine résolution (pas de facteur d'échelle).
- Simulateur iOS : idb via son interface REST. L'agent doit démarrer un simulateur (ou l'utilisateur l'a déjà fait).
- Rendu : Sharp (images) et FFmpeg (vidéos) avec un calque de composition SVG pour les annotations, les cadres, les ombres et les arrière-plans.
- Presse-papiers : Pour
typesur desktop, agentshot copie le texte dans le presse-papiers et colle (Ctrl+V / Cmd+V).
Dépannage
- Desktop : aucune fenêtre listée → l'agent n'a pas la permission Screen Recording (macOS) ou l'application est en mode admin (Windows).
- Desktop : les clics ne fonctionnent pas → absence d'autorisation Accessibility (macOS).
- Web : la page ne se charge pas → le serveur de développement n'est pas en cours d'exécution ou l'URL est incorrecte.
- Simulateur : idb non trouvé →
brew install facebook/fb/idb-companion && pipx install fb-idb. - Erreur de rendu : font introuvable → installez la police localement (Google Fonts, etc.). Les polices sont référencées par leur nom de famille.
- La vidéo rendue est saccadée → utilisez
"timing": "frame"dans le scénario (par défaut) et évitez lescutsqui dépassent les segments de capture.
Meilleures pratiques
- Lisez toujours d'abord
guidelines.md– il contient les préférences de style du produit et des commentaires antérieurs. - Prévisualisez avant de rendre – utilisez
agentshot previewpour itérer rapidement. - Gardez les fichiers de capture/recette dans le projet – ils peuvent être réexécutés après des modifications de l'interface utilisateur.
- Utilisez
trackpour les cibles clés – cela évite de coder en dur les coordonnées qui changent avec la mise en page. - Pour les applications Expo – testez d'abord sur le web (
npx expo start --web) ; utilisez le simulateur pour les modules natifs. - Apprenez des retours – ajoutez des lignes à
guidelines.mdlorsque l'utilisateur corrige ou félicite un résultat. - Versionnez tout –
agentshot rendercrée automatiquement des versions, ce qui permet de comparer et de revenir en arrière.