capture

Par factory-ai · factory-plugins

Connaissances de base pour les workflows de contrôle de droïde — non invoqué directement. Enregistrement du cycle de vie des sessions terminal et navigateur.

npx skills add https://github.com/factory-ai/factory-plugins --skill capture

Capture

L'orchestrateur t'a routé ici. Cet atom possède le cycle de vie complet de l'enregistrement : lancer une cible, exécuter un script d'interaction, collecter les sorties brutes.

Tu devrais déjà avoir un driver atom chargé (tuistory, true-input, ou agent-browser) et optionnellement un target atom (droid-cli). Cet atom superpose la discipline d'enregistrement par-dessus.

Entrées

La commande qui t'a invoqué devrait avoir fourni :

  • Target : ce qu'il faut lancer et sur quelle(s) branche(s)
  • Script d'interaction : la séquence d'actions à effectuer
  • Ce qu'il faut capturer : enregistrements (.cast/.mp4), captures d'écran, snapshots texte, séquences d'octets
  • Logging des touches clavier : s'il faut émettre un TSV de frappe pour superposition ultérieure

Cycle de vie de l'enregistrement

1. Pré-vol

Avant d'enregistrer quoi que ce soit :

  • La taille du terminal est cohérente dans toutes les sessions (--cols 120 --rows 36)
  • La taille du viewport du navigateur correspond à la disposition de la composition (voir « Browser viewport sizing » ci-dessous) — des aspects mal appariés créent un letterboxing dans la vidéo finale
  • Les chemins des branches/worktrees et les variables d'env sont corrects
  • Le format d'enregistrement correspond au driver : .cast pour tuistory, .mp4 pour true-input, captures pour agent-browser
  • Si tu compares des branches, les deux sessions utilisent des dimensions de terminal / viewport identiques et les mêmes paramètres de lancement
  • Pour les captures droid-dev, --repo-root est obligatoiretctl refusera de lancer sans lui
  • Les variables d'env de couleur sont définies (voir ci-dessous)

Browser viewport sizing

Le ratio d'aspect du panneau dans la composition finale est dépendant de la disposition. Avec la sortie par défaut 1920×1080 et les marges du preset usine, les panneaux window-chrome dans lesquels clips rend se retrouvent à peu près :

Disposition Ratio d'aspect du panneau Viewport du navigateur recommandé
single ~1760×920 (≈16:9 paysage) 1280×720 ou 1440×810
side-by-side ~872×920 par panneau (≈8:9, quasi-carré / léger portrait) 960×1000, 900×1000, ou 1024×1080

Alimenter un enregistrement paysage 16:9 dans un panneau side-by-side quasi-carré déclenche un letterboxing objectFit: "contain" — tu obtiens une fine bande de contenu avec des barres noires géantes au-dessus et au-dessous. Deux façons de l'éviter :

  1. Faire correspondre les aspects au moment de la capture (préféré) — choisis le viewport du tableau ci-dessus selon la disposition validée.
  2. Opter pour un recadrage au moment de la composition — passe "objectFit": "cover" dans les props showcase. Recadre les bords du clip au lieu du letterboxing. À utiliser quand l'UI pertinente est centrée et les bords du clip sont dispensables.

Si tu n'es pas sûr de la disposition lors de la capture, défaut à 960×1000 — c'est utilisable dans les deux dispositions (léger letterbox horizontal en single, pas de letterbox en side-by-side).

TCTL=${DROID_PLUGIN_ROOT}/bin/tctl
# RUN_ID et RUN_DIR devraient déjà être définis par le parent (voir règle fondamentale droid-control 5)

2. Lancer et enregistrer

CRITIQUE : le PTY virtuel de tuistory n'annonce pas la prise en charge des couleurs par défaut. Les apps Node.js (Ink/chalk) le détectent et suppriment TOUTES les séquences d'échappement de couleur, produisant un enregistrement monochrome. Tu dois passer FORCE_COLOR=3 et COLORTERM=truecolor pour forcer une sortie couleur 24-bit complète. Sans cela, agg n'a rien à thématiser et la vidéo aura l'air grise/désaturée quel que soit le thème agg choisi.

Branche unique :

$TCTL launch "droid-dev" -s ${RUN_ID}-demo --backend tuistory \
  --repo-root /path/to/worktree \
  --cols 120 --rows 36 --record ${RUN_DIR}/demo.cast \
  --env FORCE_COLOR=3 --env COLORTERM=truecolor

Comparaison (avant/après) :

$TCTL launch "droid-dev" -s ${RUN_ID}-before --backend tuistory \
  --repo-root /path/to/baseline-worktree \
  --cols 120 --rows 36 --record ${RUN_DIR}/before.cast \
  --env FORCE_COLOR=3 --env COLORTERM=truecolor

$TCTL launch "droid-dev" -s ${RUN_ID}-after --backend tuistory \
  --repo-root /path/to/candidate-worktree \
  --cols 120 --rows 36 --record ${RUN_DIR}/after.cast \
  --env FORCE_COLOR=3 --env COLORTERM=truecolor

Navigateur : ajuste le viewport pour correspondre à la disposition de la composition (voir tableau ci-dessus).

# disposition side-by-side → panneau quasi-carré
agent-browser open <url> --viewport 960x1000
agent-browser record start ${RUN_DIR}/demo.webm

# disposition single → panneau 16:9
agent-browser open <url> --viewport 1280x720
agent-browser record start ${RUN_DIR}/demo.webm

3. Exécuter le script d'interaction

Filme pour un spectateur sans contexte. Tu es un réalisateur, pas un opérateur.

  • Enregistre avant la configuration — l'état de base est l'acte 1.
  • Reste après les changements d'état — 2-3 secondes pour que le texte soit lisible. Utilise snapshot --trim comme vérification naturelle.
  • Vérifie entre les étapeswait ou snapshot pour confirmer l'état avant de continuer. Ne tire pas aveuglément la touche suivante.
  • La vérification EST la preuve. Un snapshot montrant que rien n'a changé après avoir appuyé sur ESC prouve que la session est figée. Un snapshot montrant un message d'erreur prouve que la commande a été bloquée. Snapshot toujours après les actions où l'absence de réponse est le point — le spectateur a besoin de le voir aussi.

Pour les enregistrements de comparaison, les deux branches exécutent des interactions identiques — seul le comportement diffère.

4. Logging des touches clavier

Si le workflow nécessite une superposition de touches clavier, émets un fichier TSV pendant l'enregistrement. Puisque chaque interaction est scriptée, les données de timing sont déjà connues.

Écris pour chaque touche son timestamp (secondes depuis le début de l'enregistrement) et une étiquette lisible :

0.5 droid --fork
1.2 Enter
2.8 Ctrl+C
4.0 Esc

Utilise des noms de touches lisibles (Ctrl+C, pas \x03). Sauvegarde aux côtés de l'enregistrement (p. ex. /tmp/keys.tsv).

5. Fermer et vérifier les sorties brutes

$TCTL -s demo close    # finalise le .cast / arrête l'enregistrement

Avant de passer le relais, confirme que chaque fichier de sortie attendu existe et n'est pas vide :

  • Fichiers d'enregistrement (.cast, .mp4, .webm)
  • Fichiers de capture d'écran (.png)
  • TSV de frappe (si commité)
  • Logs de snapshot texte (si nécessaire pour le rapport)

Modèles de capture de preuves

Type de preuve Comment le capturer
Comportement fonctionnel Snapshots texte : $TCTL -s <name> snapshot --trim
Rendu visuel Captures d'écran : $TCTL -s <name> screenshot -o /tmp/proof-N.png
Encodage clavier Octets PTY : ${DROID_PLUGIN_ROOT}/scripts/capture-terminal-bytes.py --backend <terminal> --combo <keys>
Web/Electron Captures d'écran : agent-browser screenshot --annotate /tmp/proof-N.png
Avant/après Exécute la même séquence sur les deux branches aux mêmes points de capture

Sorties

Remets-les à l'étape compose :

## Capture outputs
- clips: [/tmp/before.cast, /tmp/after.cast]
- screenshots: [/tmp/proof-1.png, /tmp/proof-2.png]
- keys: /tmp/keys.tsv (si keystroke logging a été demandé)
- driver: tuistory | true-input | agent-browser
- terminal_size: 120x36          # pour tuistory / true-input
- viewport: 960x1000             # pour agent-browser; rapporte-le pour que compose connaisse l'aspect du clip

Récupération

Si une session se bloque en cours d'enregistrement :

$TCTL -s <name> press esc         # sors du dialogue bloqué
$TCTL -s <name> snapshot --trim   # vérifie l'état visible
$TCTL -s <name> close             # réinitialisation forcée

Pour navigateur : agent-browser close.

Puis relance et réenregistre. Les enregistrements partiels ne sont pas utilisables.

Skills similaires