Communitygithub.com

Monet-AI-Editor/Monet

`editorctl` ist das Monet-CLI. Versuche es immer zuerst direkt – Monet stellt es für jede Shell auf den `PATH` und persistiert das Bin-Verzeichnis in `~/.zshrc` / `~/.bash_profile`, sodass es Subshells und PATH-überschreibende Wrapper überlebt. **Wenn `command -v editorctl` nichts zurückgibt**, falle in dieser Reihenfolge zurück.

Was ist Monet?

Dieses Skill beschreibt die vollständige Steuerung des Monet AI-Videoeditors durch einen KI-Agenten. Es definiert den zwingenden Umgang mit dem `editorctl`-CLI-Befehl, die Regeln zur eindeutigen Dateibenennung (um Caching-Probleme zu vermeiden) und die Behandlung von Audio auf Multi-Clip-Zeitachsen. Das Skill stellt alle Befehle der lokalen API (`POST http://localhost:51847`) übersichtlich dar, unterteilt in Projektverwaltung, Asset-Handling, Sequenzen, Clips, Effekte, Historie sowie Canvas- und Remotion-Operationen. Besondere Schwerpunkte sind die exakte Beschreibung der drei Canvas-Modi (Paper.js, Matter.js, GPT image 2) sowie die obligatorische Extraktion von Markenfarben aus URLs, bevor Designcode ausgeführt wird. Die Skriptmuster für Matter.js-Physikszenen werden detailliert erläutert, inklusive der kritischen Fehler (z. B. doppeltes Deklarieren von `engine`). Das Skill ist primär für den Monet-Editor (macOS) gedacht, unterstützt aber auch Entwicklungsbäume. Es stellt dem Agenten eine sichere, vollständige und fehlertolerante Schnittstelle zur Verfügung, um Video- und Bildinhalte zu erstellen, zu bearbeiten und zu exportieren.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add Monet-AI-Editor/Monet

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

KI-Videoeditor – Agenten-Steuerungsreferenz

⚠️ editorctl FINDEN – ZWINGEND (zuerst lesen)

editorctl ist das Monet-CLI. Versuche es immer zuerst direkt – Monet stellt es für jede Shell auf den PATH und persistiert das Bin-Verzeichnis in ~/.zshrc / ~/.bash_profile, sodass es Subshells und PATH-überschreibende Wrapper überlebt. Wenn command -v editorctl nichts zurückgibt, falle in dieser Reihenfolge zurück:

  1. "$HOME/Library/Application Support/Monet/bin/editorctl" – macOS-Installation (die meisten Benutzer)
  2. node /Applications/Monet.app/Contents/Resources/app.asar.unpacked/out/cli/cli/editorctl.js …
  3. node ./out/cli/cli/editorctl.js … – Entwicklungsbaum

Gib niemals nach dem ersten "Befehl nicht gefunden" auf. Bevorzuge editorctl gegenüber rohem curl localhost:51847 – es zeigt immer die aktuelle Befehlsoberfläche und Argumentformen an.

⚠️ AUSGABEDATEINAMENSGEBUNG – ZWINGEND (zuerst lesen)

Verwende niemals einen Dateinamen beim Bearbeiten oder Neugenerieren eines Videos oder Bildes wieder. Der Asset-Cache speichert die vorherige Datei unter dem Pfad, sodass das Schreiben auf denselben Namen stillschweigend veraltete Inhalte anzeigt. Jede Bearbeitung/Neugenerierung muss einen neuen, eindeutigen Dateinamen erzeugen (z. B. clip_v1.mp4, clip_v2.mp4 oder einen Zeitstempel-Suffix). Dies gilt für alle Videorenderings, Bildgenerierungen, Canvas-Exporte und Miniaturansichten. Wenn ein Zielpfad bereits existiert, hänge _v2, _v3, … an – überschreibe nicht.

⚠️ AUDIO AUF MEHRFACH-CLIP-ZEITACHSEN – ZWINGEND

Wenn Audio zu einer Zeitachse mit mehr als einem Videoclip hinzugefügt wird, wird das Audio an jeder Clip-Grenze unterbrochen. Erforderlicher Ablauf:

  1. Teile dem Benutzer mit: "Damit das Audio nicht zwischen den Clips unterbrochen wird, fasse ich zunächst alle Videoclips zu einem kombinierten Video zusammen und füge dann das Audio hinzu. Einverstanden?"
  2. Warte auf Bestätigung – führe keine automatische Zusammenführung durch.
  3. Verkette alle Clips zu einer einzigen neuen Datei (eindeutiger Dateiname gemäß obiger Regel).
  4. Ersetze die Mehrfach-Clip-Videospur durch den zusammengeführten Clip und füge dann das Audio hinzu.

Bei Einzelclip-Zeitachsen: Überspringe die Zusammenführung.


⚠️ CANVAS-MODUS – ZWINGENDE REGELN (zuerst lesen)

Wenn activeView=canvas vom Hook oder durch editorctl get-state gemeldet wird:

Es gibt GENAU 3 Canvas-Optionen. Andere existieren nicht.

  1. Paper.js – Code-Zeichnung mit Vektorgrafiken (canvas-run-paperjs)
  2. Matter.js – Physik und Animation (canvas-run-matterjs)
  3. GPT image 2 – KI-generiertes Bild (generate-image + canvas-add-image)

ENTFERNT – Biete diese NICHT unter irgendeinem Namen an:

  • Designmodus – entfernt
  • Bearbeitbare Ebenen – entfernt
  • Figma-ähnliches Layout – entfernt
  • Knotenbasiertes Design – entfernt
  • Direktes Canvas-Design – entfernt

Wenn der Benutzer im Canvas-Modus nach etwas Visuellem fragt, präsentiere NUR diese drei Optionen mit diesen EXAKTEN Bezeichnungen. Kopiere sie wörtlich. Erfinde keine vierte Option oder formuliere Option 1 als designbezogen um.


API-Brücke: POST http://localhost:51847 – JSON-Body {"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")   # → vollständige Befehlsliste

Befehle

Projekt / Einstellungen

BefehlArgumenteRückgabe
get_project—Vollständiges Projekt-JSON
get_settings—Modell- + Anbieterkonfiguration

Assets

BefehlArgumenteRückgabe
list_assets—[{id, name, path, type, duration, semantic}]
get_assetassetIdEinzelnes Asset mit semantischer + Transkription
import_filespaths: string[]Importierte Asset-Datensätze
transcribe_assetassetId, language?{segments} via Whisper
embed_assetsall?: bool{embedded, total} via text-embedding-3-small
search_mediaquery, limit?Kosinus-Ähnlichkeitssuche (Fallback auf Schlüsselwort)
search_spokenquery, limit?Substring-Suche in transkribierten Segmenten

Sequenzen & Spuren

BefehlArgumenteRückgabe
list_sequences—Alle Sequenzen
create_sequencenameNeue Sequenz
activate_sequencesequenceIdAktivierte Sequenz
get_tracks—[{id, name, kind, clipCount}] für aktive Sequenz
add_track`kind: videoaudio

Clips

BefehlArgumenteRückgabe
list_clipssequenceId?Alle Clips sortiert nach startTime, mit trackKind
add_clipassetId, trackId, startTime, duration?, inPoint?{clipId, clip}
remove_clipclipId{success}
move_clipclipId, startTime{success}
trim_clipclipId, inPoint?, duration?, startTime?Aktualisierter Clip
split_clipclipId, timeAktualisierte Sequenz
duplicate_clipclipId, offsetSeconds?{clipId, clip}
update_clip_labelclipId, label{success}

Effekte & Eigenschaften

BefehlArgumenteRückgabe
list_effects—Verfügbare Effekte + Parameterdokumentation
add_effectclipId, effectType, parametersAktualisiertes Projekt
remove_effectclipId, effectIdAktualisiertes Projekt
set_speedclipId, speedAktualisiertes Projekt (0,1–10× Wiedergabe)
set_volumeclipId, volumeAktualisiertes Projekt (0–4, 1=normal)
set_transition`clipId, side: inout, type, duration?`

Verlauf

BefehlArgumente
undo—
redo—

Effekttypen

TypParameter
fade_induration (Sek.)
fade_outduration (Sek.)
color_gradebrightness (-1→1), contrast (0,5→2), saturation (0→3)
blurradius (px, Standard 5)
sharpenamount (0→3, Standard 1)

Übergangstypen

crossfade · dip_to_black · wipe · slide


Wichtige Konzepte

  • inPoint = Position in der Quelldatei, an der die Clip-Wiedergabe beginnt
  • startTime = Position auf der Zeitleiste, an der der Clip platziert wird
  • duration = Wie lange der Clip abgespielt wird (kann kürzer als die Quelle sein)
  • Jede Mutation sendet sofort project:updated → UI spiegelt Änderungen live wider
  • Effekte werden in Echtzeit (CSS) und beim Export via FFmpeg gerendert

Sicherheitsregeln für die Bearbeitung

  • Behandle Lücken in der Zeitleiste als Fehler, es sei denn, der Benutzer wünscht ausdrücklich eine Pause, einen Takt oder eine schwarze Lücke.
  • Überprüfe nach dem Erstellen einer Sequenz oder dem Verschieben von Clips die Kontinuität mit list_clips(sequenceId) und stelle sicher, dass jeder Clip genau dort beginnt, wo der vorherige endet, wenn die Bearbeitung durchgehend sein soll.
  • Gehe nicht davon aus, dass create_sequence oder activate_sequence allein ausreichen. Überprüfe die aktive Sequenz immer anschließend mit list_sequences oder get_project.
  • Wenn ein gesprochener Highlight-Cut erstellt wird, verschiebe Video, Audio, Untertitel und Marker gemeinsam. Hinterlasse keine Untertitel oder Marker auf alten Zeitpunkten, nachdem der Schnitt gestrafft wurde.
  • Wenn die Wiedergabe zwischen Clips anzuhalten scheint, überprüfe zuerst die Zeitleiste auf leere Lücken, bevor du annimmst, dass der Vorschauplayer defekt ist.
  • Bevorzuge exakte Zielstartzeiten gegenüber kumulativem Offset-Rechnen, wenn ein Schnitt gestrafft wird. Berechne die beabsichtigte startTime jedes Clips neu aus dem Schnittplan.

Markenästhetik aus einer URL

ZWINGEND – KEINE AUSNAHMEN: Wenn die Nachricht des Benutzers eine URL oder Domain enthält, MUSST du die untenstehenden Fetch-Befehle ausführen und Markentoken extrahieren, bevor du Canvas-/Designcode schreibst. Verwende keine angenommenen oder auswendig gelernten Markenfarben. Zuerst holen, dann designen – jedes Mal. Wenn der Fetch fehlschlägt, bitte den Benutzer, die Hex-Werte einzufügen; falle niemals auf Raten zurück.

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

Extrahiere: Hintergrundfarben, Oberflächenfarben, Primär-/Akzentfarben, Textfarben, Schriftfamilien, Schriftgrößen/-gewichte, Rahmenradien, Abstände und Box-Shadows. Finde auch das Logo – es ist die ultimative Quelle für Markenfarben und visuellen Ton. Hardcode diese exakten Werte – rate niemals, wenn eine echte URL verfügbar ist.

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

Canvas – Matter.js Physik-Frames

Verwende canvas_run_matterjs, um eine live-interaktive Physikszene auf dem Canvas zu platzieren.

MCP-Werkzeuge

WerkzeugArgumente
canvas_run_matterjsid? (Frame-ID zum Aktualisieren), name?, script (JS-String), 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}]}

Skriptmuster – wähle EINES aus

Muster A – In sich geschlossen (reichhaltige UIs, benutzerdefiniertes 2D-Zeichnen, rAF-Schleife)

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'); // ← immer dies verwenden; nie ein neues erstellen
canvas.width = W; canvas.height = H;
const ctx = canvas.getContext('2d');
// ... Bodies hinzufügen, Maus einrichten ...
function loop() {
  Engine.update(engine, 1000/60);
  ctx.fillStyle = '#121212'; ctx.fillRect(0, 0, W, H);
  // mit ctx zeichnen
  requestAnimationFrame(loop);
}
loop();

Muster B – Nur Bodies (Template verwaltet Engine/Render/Runner)

// engine, render, width, height und alle Matter-Variablen sind bereits deklariert – deklariere sie NICHT neu
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 und Render.run werden nach diesem Skript automatisch aufgerufen – rufe sie hier nicht auf

Kritische Regeln

  • Runner.run benötigt zwei Argumente: Runner.run(Runner.create(), engine) – Runner.run(engine) mit einem Argument tut in Matter.js 0.20.0 stillschweigend nichts
  • Nie element: document.body in Render.create – erzeugt ein unsichtbares zweites Canvas; verwende stattdessen canvas: document.querySelector('canvas')
  • Nie const engine oder let engine in Muster B deklarieren – das Template hat bereits var engine; die Neudeklaration mit const/let verursacht einen SyntaxError, der das Canvas stillschweigend leert
  • Nie Render.run / Runner.run in Muster B aufrufen – das Template macht dies nach der Ausführung deines Skripts; der doppelte Aufruf führt zu doppelter Geschwindigkeit oder defektem Rendering
  • Nie Matter-Variablen in Muster B importieren oder neu deklarieren – Engine, Bodies, Composite, etc. sind bereits destructuring-entpackt; const { Engine } = Matter wird einen SyntaxError auslösen

Muster B verfügbare Globals

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

CLI

editorctl canvas-add-frame "Name" 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 – React-Videokomposition

Verwende Remotion, um animierte Video-Assets (Titelkarten, Lower Thirds, Diashows, Bewegungsgrafiken) zu generieren und direkt in die Zeitleiste zu importieren.

MCP-Werkzeuge

WerkzeugArgumenteRückgabe
video_editor_list_remotion_compositions—Liste der Kompositions-IDs
video_editor_render_remotioncompositionId, outputFilename?, props?, durationInFrames?, fps?{outputPath, assetId}

CLI

npm run remotion:studio                                          # Live-Vorschau unter localhost:3000
npx remotion render remotion/src/index.ts <ID> out.mp4 --props '{"key":"value"}'

Integrierte Kompositionen

IDProps
TitleCardtitle (str), subtitle? (str), backgroundColor, textColor, accentColor – 150 Frames @ 30fps
Slideshowimages (abs path[]), frameDuration (frames), transitionDuration (frames) – 300 Frames @ 30fps
HtmlInCanvasGlitchtitle, subtitle, glitchIntensity (0–40), backgroundColor, textColor, accentColor – 180 Frames @ 30fps. RGB-Split-Glitch via <HtmlInCanvas>

HTML-im-Canvas (Remotion ≥ 4.0.455)

⚠️ Namenskonflikt – zuerst lesen. Remotion <HtmlInCanvas> (dieser Abschnitt) erzeugt eine Videodatei für die Zeitleiste. Monet-Canvas-HTML-Frames (canvas-add-frame ... html, canvas_update_frame) erzeugen eine Live-HTML-Szene im Canvas-Tab-Artboard. Unterschiedliche Systeme. Wähle nach Ziel: Zeitleiste → Remotion; Canvas-Tab → Monet-HTML-Frame. Mische die beiden niemals in einer Aufgabe.

Verwende <HtmlInCanvas>, um einen DOM-Unterbaum in ein <canvas> zu zeichnen und mit Canvas 2D / WebGL / WebGPU nachzubearbeiten. Am besten geeignet für Glitch-, Lupen-, CRT-, Displacement-, Farbton-Dreheffekte.

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() // <-- immer erneut anwenden
}

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

Regeln:

  • Immer den Rückgabewert von drawElementImage auf element.style.transform anwenden, damit Layout/Input korrekt bleiben.
  • Nie <HtmlInCanvas> in ein anderes verschachteln – Chrome zeichnet nur das äußere und Remotion wirft einen Fehler. Führe Effekte in einem einzigen onPaint zusammen.
  • Config.setChromiumOpenGlRenderer('angle') ist bereits in package.json gesetzt.

Verwandte Skills