Communitygithub.com

Monet-AI-Editor/Monet

`editorctl` est l'interface CLI de Monet. Essayez-la toujours directement en premier — Monet la garde sur le `PATH` pour chaque shell qu'il lance et persiste le répertoire binaire dans `~/.zshrc` / `~/.bash_profile` pour qu'elle survive aux sous-shells et aux wrappers qui réécrivent le PATH. **Si `command -v editorctl` ne retourne rien**, passez à la solution de repli dans l'ordre suivant :

Qu'est-ce que Monet ?

Ce skill fournit un contrôle complet de l'éditeur vidéo Monet via une interface CLI (`editorctl`) ou une API REST locale. Il permet aux agents IA de manipuler des projets vidéo : importer des médias, gérer des séquences, ajouter/supprimer/déplacer des clips, appliquer des effets (fondus, étalonnage, flou), des transitions, et de travailler avec des modes canvas avancés (Paper.js, Matter.js, images IA). Le skill inclut des règles impératives pour la gestion des fichiers de sortie (noms uniques), le traitement audio sur les timelines multi-clips, et l'extraction de tokens de marque à partir d'URLs. Il prend en charge la génération d'animations vidéo via Remotion (React) et l'intégration de scènes physiques Matter.js. Idéal pour les tâches d'édition vidéo automatisées par IA, le skill garantit la cohérence du projet en vérifiant systématiquement l'état après chaque mutation et en suivant des règles de sécurité strictes.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add Monet-AI-Editor/Monet

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Éditeur Vidéo IA — Référence de Contrôle Agent

⚠️ TROUVER editorctl — OBLIGATOIRE (lire ceci d'abord)

editorctl est l'interface CLI de Monet. Essayez-la toujours directement en premier — Monet la garde sur le PATH pour chaque shell qu'il lance et persiste le répertoire binaire dans ~/.zshrc / ~/.bash_profile pour qu'elle survive aux sous-shells et aux wrappers qui réécrivent le PATH. Si command -v editorctl ne retourne rien, passez à la solution de repli dans l'ordre :

  1. "$HOME/Library/Application Support/Monet/bin/editorctl" — installation macOS (la plupart des utilisateurs)
  2. node /Applications/Monet.app/Contents/Resources/app.asar.unpacked/out/cli/cli/editorctl.js …
  3. node ./out/cli/cli/editorctl.js … — arbre de développement

N'abandonnez jamais après le premier "command not found". Préférez editorctl à curl localhost:51847 brut — il expose toujours la surface de commande et les formes d'arguments actuelles.

⚠️ NOMENCLATURE DES FICHIERS DE SORTIE — OBLIGATOIRE (lire ceci d'abord)

Ne réutilisez jamais un nom de fichier lors de l'édition ou de la régénération d'une vidéo ou d'une image. Le cache des ressources conserve le fichier précédent par chemin, donc écrire dans le même nom affiche silencieusement un contenu obsolète. Chaque édition/régénération doit produire un nouveau nom de fichier unique (par exemple clip_v1.mp4, clip_v2.mp4, ou un suffixe temporel). Cela s'applique à tous les rendus vidéo, générations d'images, exportations de canvas et miniatures. Si un chemin cible existe déjà, ajoutez _v2, _v3, … — ne l'écrasez pas.

⚠️ AUDIO SUR LES TIMELINES MULTI-CLIPS — OBLIGATOIRE

Lors de l'ajout d'audio à une timeline avec plus d'un clip vidéo, l'audio est coupé à chaque limite de clip. Flux requis :

  1. Informez l'utilisateur : "Pour empêcher l'audio de se couper entre les clips, je vais d'abord fusionner tous les clips vidéo en une seule vidéo combinée, puis ajouter l'audio. OK pour continuer ?"
  2. Attendez la confirmation — ne fusionnez pas automatiquement.
  3. Concaténez tous les clips en un seul nouveau fichier (nom unique selon la règle ci-dessus).
  4. Remplacez la piste vidéo multi-clips par ce clip fusionné, puis ajoutez l'audio.

Timelines à clip unique : ignorez la fusion.


⚠️ MODE CANVAS — RÈGLES OBLIGATOIRES (lire ceci d'abord)

Lorsque activeView=canvas est signalé par le hook ou editorctl get-state :

Il y a EXACTEMENT 3 options canvas. Aucune autre n'existe.

  1. Paper.js — dessin de code avec graphiques vectoriels (canvas-run-paperjs)
  2. Matter.js — physique et animation (canvas-run-matterjs)
  3. Image GPT 2 — image générée par IA (generate-image + canvas-add-image)

SUPPRIMÉES — ne proposez PAS celles-ci sous quelque nom que ce soit :

  • Mode design — supprimé
  • Calques modifiables — supprimé
  • Disposition Figma — supprimé
  • Design basé sur les nœuds — supprimé
  • Conception directe du canvas — supprimé

Lorsque l'utilisateur demande quelque chose de visuel en mode canvas, présentez UNIQUEMENT ces trois options en utilisant ces ÉTIQUETTES EXACTES. Copiez-les textuellement. N'inventez pas une quatrième option et ne reformulez pas l'option 1 comme quelque chose de lié au design.


Pont API : POST http://localhost:51847 — Corps JSON {"command":"<name>","args":{...}}

import urllib.request, json

def call(command, **args):
    data = json.dumps({"command": command, "args": args}).encode()
    req = urllib.request.Request(
        "http://localhost:51847", data=data,
        headers={"Content-Type": "application/json"}, method="POST"
    )
    return json.loads(urllib.request.urlopen(req).read())["result"]

call("ping")   # → {"status":"ok","version":"1.0.0","port":51847}
call("help")   # → liste complète des commandes

Commandes

Projet / Paramètres

CommandeArgumentsRetourne
get_project—Projet JSON complet
get_settings—Configuration du modèle + fournisseur

Ressources

CommandeArgumentsRetourne
list_assets—[{id, name, path, type, duration, semantic}]
get_assetassetIdRessource unique avec sémantique + transcription
import_filespaths: string[]Enregistrements de ressources importées
transcribe_assetassetId, language?{segments} via Whisper
embed_assetsall?: bool{embedded, total} via text-embedding-3-small
search_mediaquery, limit?Recherche de similarité cosinus (repli sur mot-clé)
search_spokenquery, limit?Recherche de sous-chaîne dans les segments transcrits

Séquences et Pistes

CommandeArgumentsRetourne
list_sequences—Toutes les séquences
create_sequencenameNouvelle séquence
activate_sequencesequenceIdSéquence activée
get_tracks—[{id, name, kind, clipCount}] pour la séquence active
add_track`kind: videoaudio

Clips

CommandeArgumentsRetourne
list_clipssequenceId?Tous les clips triés par startTime, avec trackKind
add_clipassetId, trackId, startTime, duration?, inPoint?{clipId, clip}
remove_clipclipId{success}
move_clipclipId, startTime{success}
trim_clipclipId, inPoint?, duration?, startTime?Clip mis à jour
split_clipclipId, timeSéquence mise à jour
duplicate_clipclipId, offsetSeconds?{clipId, clip}
update_clip_labelclipId, label{success}

Effets et Propriétés

CommandeArgumentsRetourne
list_effects—Effets disponibles + documentation des paramètres
add_effectclipId, effectType, parametersProjet mis à jour
remove_effectclipId, effectIdProjet mis à jour
set_speedclipId, speedProjet mis à jour (lecture 0.1–10×)
set_volumeclipId, volumeProjet mis à jour (0–4, 1=normal)
set_transition`clipId, side: inout, type, duration?`

Historique

CommandeArguments
undo—
redo—

Types d'Effets

TypeParamètres
fade_induration (sec)
fade_outduration (sec)
color_gradebrightness (-1→1), contrast (0.5→2), saturation (0→3)
blurradius (px, défaut 5)
sharpenamount (0→3, défaut 1)

Types de Transitions

crossfade · dip_to_black · wipe · slide


Concepts Clés

  • inPoint = position dans le fichier source où la lecture du clip commence
  • startTime = position sur la timeline où le clip est placé
  • duration = durée de lecture du clip (peut être plus courte que la source)
  • Chaque mutation pousse instantanément project:updated → l'interface utilisateur reflète les changements en direct
  • Les effets sont prévisualisés en temps réel (CSS) et cuits via FFmpeg lors de l'exportation

Règles de Sécurité d'Édition

  • Traitez les espaces vides dans la timeline comme un bogue, sauf si l'utilisateur demande explicitement une pause, un temps, ou un espace noir.
  • Après avoir créé une séquence ou déplacé des clips, vérifiez la continuité avec list_clips(sequenceId) et assurez-vous que chaque clip commence exactement là où le clip précédent se termine si l'édition est censée être continue.
  • Ne supposez pas que create_sequence ou activate_sequence suffit seul. Vérifiez toujours la séquence active ensuite avec list_sequences ou get_project.
  • Lors de la construction d'un montage de moments forts parlés, déplacez la vidéo, l'audio, les légendes et les marqueurs ensemble. Ne laissez pas de légendes ou de marqueurs sur d'anciens timings après avoir resserré le montage.
  • Si la lecture semble s'arrêter entre les clips, inspectez d'abord la timeline pour détecter des espaces vides avant de supposer que le lecteur d'aperçu est cassé.
  • Préférez des débuts cibles exacts plutôt que des calculs de décalage cumulatifs lors du resserrement d'un montage. Recalculez le startTime prévu de chaque clip à partir du plan de montage.

Esthétique de Marque à partir d'une URL

OBLIGATOIRE — AUCUNE EXCEPTION : Si le message de l'utilisateur contient une URL ou un nom de domaine, vous DEVEZ exécuter les commandes de récupération ci-dessous et extraire les tokens de marque avant d'écrire tout code de canvas/design. N'utilisez pas de couleurs de marque supposées ou mémorisées. Récupérez d'abord, concevez ensuite — à chaque fois. Si la récupération échoue, demandez à l'utilisateur de coller les valeurs hexadécimales ; ne recourez jamais à des suppositions.

curl -sL "<url>" | grep -Eo '(#[0-9a-fA-F]{3,8}|font-family:[^";}]+|font-size:[^";}]+|border-radius:[^";}]+)' | sort -u | head -60

Extrayez : couleurs d'arrière-plan, couleurs de surface, couleurs primaires/d'accentuation, couleurs de texte, polices de caractères, tailles de police/poids, rayons de bordure, espacements et ombres de boîte. Trouvez également le logo — c'est la vérité terrain pour les couleurs de la marque et le ton visuel. Codez ces valeurs exactes — ne devinez jamais lorsqu'une URL réelle est disponible.

# Trouver le logo
curl -sL "<url>" | grep -Eo '(src|href)="[^"]*logo[^"]*"' | head -10
curl -sL "<url>" | grep 'og:image'

Canvas — Images Physiques Matter.js

Utilisez canvas_run_matterjs pour placer une scène physique interactive en direct sur le canvas.

Outils MCP

OutilArguments
canvas_run_matterjsid? (id de l'image à mettre à jour), name?, script (chaîne JS), width?, height?
canvas_add_framename, width, height, mode: 'matterjs'
canvas_matterjs_scenestyle (balls/stacks/pendulum/bridge/ragdoll), gravity?, count?, colors?
canvas_frames— → {frames: [{id, name, mode, width, height}]}

Modèles de script — choisissez-en UN

Modèle A — Autonome (interfaces utilisateur riches, dessin 2D personnalisé, boucle rAF)

const { Engine, Bodies, Composite, Mouse, MouseConstraint, Events } = Matter;
const W = 390, H = 844;
const engine = Engine.create({ gravity: { y: 1.5 } });
const canvas = document.querySelector('canvas'); // ← utilisez toujours ceci ; ne créez jamais de nouveau canvas
canvas.width = W; canvas.height = H;
const ctx = canvas.getContext('2d');
// ... ajoutez des corps, configurez la souris ...
function loop() {
  Engine.update(engine, 1000/60);
  ctx.fillStyle = '#121212'; ctx.fillRect(0, 0, W, H);
  // dessinez avec ctx
  requestAnimationFrame(loop);
}
loop();

Modèle B — Corps uniquement (le modèle gère engine/render/runner)

// engine, render, width, height, et toutes les variables Matter sont déjà déclarées — ne les redéclarez PAS
var ground = Bodies.rectangle(width/2, height+25, width, 50, { isStatic: true, render: { fillStyle: '#334155' } });
var ball = Bodies.circle(width/2, 50, 30, { restitution: 0.8, render: { fillStyle: '#5b82f7' } });
Composite.add(engine.world, [ground, ball]);
engine.gravity.y = 1;
// Runner.run et Render.run sont appelés automatiquement après ce script — ne les appelez pas ici

Règles critiques

  • Runner.run nécessite deux arguments : Runner.run(Runner.create(), engine) — Runner.run(engine) à un seul argument ne fait rien silencieusement dans Matter.js 0.20.0
  • Ne jamais utiliser element: document.body dans Render.create — cela crée un deuxième canvas invisible ; utilisez canvas: document.querySelector('canvas') à la place
  • Ne jamais déclarer const engine ou let engine dans le Modèle B — le modèle a déjà var engine ; le redéclarer avec const/let provoque une SyntaxError qui vide silencieusement le canvas
  • Ne jamais appeler Render.run / Runner.run dans le Modèle B — le modèle le fait après l'exécution de votre script ; les appeler deux fois provoque une vitesse double ou un rendu cassé
  • Ne jamais importer ou redéclarer les variables Matter dans le Modèle B — Engine, Bodies, Composite, etc. sont déjà déstructurés ; const { Engine } = Matter provoquera une SyntaxError

Variables globales disponibles dans le Modèle B

engine · render · width · height · Engine · Render · Runner · Bodies · Composite · World · Body · Events · Constraint · Mouse · MouseConstraint

CLI

editorctl canvas-add-frame "Nom" 390 844 matterjs        # matterjs|paperjs|html
editorctl canvas-run-matterjs <frameId> "$(cat script.js)"
editorctl canvas-run-paperjs  <frameId> "$(cat script.js)"
editorctl canvas-run-html     <frameId> "$(cat scene.html)"
editorctl canvas-frames
editorctl canvas-done

Remotion — Composition Vidéo React

Utilisez Remotion pour générer des ressources vidéo animées (cartes de titre, tiers inférieurs, diaporamas, graphiques animés) et les importer directement dans la timeline.

Outils MCP

OutilArgumentsRetourne
video_editor_list_remotion_compositions—Liste des IDs de composition
video_editor_render_remotioncompositionId, outputFilename?, props?, durationInFrames?, fps?{outputPath, assetId}

CLI

npm run remotion:studio                                          # prévisualisation en direct à localhost:3000
npx remotion render remotion/src/index.ts <ID> out.mp4 --props '{"key":"value"}'

Compositions intégrées

IDPropriétés
TitleCardtitle (str), subtitle? (str), backgroundColor, textColor, accentColor — 150 images @ 30ips
Slideshowimages (chemins abs[]), frameDuration (images), transitionDuration (images) — 300 images @ 30ips
HtmlInCanvasGlitchtitle, subtitle, glitchIntensity (0–40), backgroundColor, textColor, accentColor — 180 images @ 30ips. Glitch RVB via <HtmlInCanvas>

HTML-dans-canvas (Remotion ≥ 4.0.455)

⚠️ Conflit de dénomination — lisez d'abord. Le <HtmlInCanvas> de Remotion (cette section) produit un fichier vidéo pour la timeline. Les images HTML du canvas Monet (canvas-add-frame ... html, canvas_update_frame) produisent une scène HTML en direct dans le tableau de bord de l'onglet canvas. Systèmes différents. Choisissez selon la destination : timeline → Remotion ; onglet canvas → image HTML Monet. Ne mélangez jamais les deux dans une même tâche.

Utilisez <HtmlInCanvas> pour dessiner une sous-arborescence DOM dans un <canvas> et post-traiter avec Canvas 2D / WebGL / WebGPU. Idéal pour les effets de glitch, loupe, CRT, déplacement, rotation de teinte.

import { HtmlInCanvas, type HtmlInCanvasOnPaint } from 'remotion'

const onPaint: HtmlInCanvasOnPaint = ({ canvas, element, elementImage }) => {
  const ctx = canvas.getContext('2d')!
  ctx.reset()
  ctx.filter = 'blur(8px)'
  const transform = ctx.drawElementImage(elementImage, 0, 0)
  element.style.transform = transform.toString() // <-- toujours réappliquer
}

<HtmlInCanvas width={1920} height={1080} onPaint={onPaint}>
  <YourDomTree />
</HtmlInCanvas>

Règles :

  • Toujours réappliquer la valeur de retour de drawElementImage à element.style.transform pour que la disposition et les entrées restent correctes.
  • Ne jamais imbriquer <HtmlInCanvas> dans un autre — Chrome ne peint que l'extérieur et Remotion lève une erreur. Fusionnez les effets dans un seul onPaint.
  • Config.setChromiumOpenGlRenderer('angle') est déjà défini dans

Skills associés