Anlass: Ein KI-Agent (z. B. Claude Code) soll den Editor über einen MCP-Server bedienen können. Er arbeitet dabei im offenen Editor mit, sodass der User live sieht, was passiert.
Was der MCP können soll (Randnotiz des Users)
Den Editor komplett bedienen.
Kein Kabelsalat: Wenn der Agent Behaviors anlegt oder bearbeitet, muss der Graph lesbar bleiben.
Der Agent weiß, was der User gerade sieht: welcher Tab offen ist, welches Objekt ausgewählt ist usw.
Stand heute (im Code nachgesehen)
Der ganze Zustand lebt im Browser-Tab: Projekt, Auswahl, offene Tabs, Play-Modus. Der Server kennt nur die gespeicherte Projektdatei.
Jede Änderung läuft als Command über den Undo-Stack (EditorState, src/editor/state.ts:476). Es gibt 113 Command-Klassen.
window.__gm (src/editor/debugHook.ts) ist die Brücke der e2e-Tests. Sie findet Widgets über ihren sichtbaren Text und liest den Zustand. Gedacht ist sie für Tests, als stabile API taugt sie nicht.
Die Plugin-API (#113, src/editor/plugins/pluginApi.ts) kann bisher nur Assets auflisten, Änderungen melden und Tabs anlegen.
Graphen kennen Gruppen und Notizen (GraphAnnotation). Eine automatische Anordnung von Nodes gibt es nicht. Wer einen Node anlegt, gibt seine Position selbst vor.
Die CSP aus #427 erlaubt connect-src 'self' data: blob:. Eine Verbindung zum eigenen Host (auch wss:) geht damit, zu anderen Hosts nicht.
Grundsatz: der Agent arbeitet im offenen Editor, nicht an der Datei
Würde der MCP die Projektdatei auf dem Server direkt bearbeiten, gäbe es zwei Probleme. Er käme dem Autosave eines offenen Tabs in die Quere, und Punkt 3 wäre gar nicht machbar. Deshalb läuft alles über den offenen Tab:
Jede Änderung des Agenten ist ein ganz normales Command. Der User sieht sie sofort und kann sie mit Strg+Z rückgängig machen.
Gespeichert wird wie immer über das Autosave des Tabs.
Verbindung: MCP-Endpunkt auf stein2 (entschieden, Kommentar 4716)
Relay-Dienst feuerwerk-mcp: ein kleiner Node-Dienst im eigenen Container, gehärtet wie feuerwerk-video. PHP-FPM kann keine dauerhaften Verbindungen halten, deshalb nicht in der API.
nginx leitet /mcp dorthin (auf beiden Adressen: feuerwerk.nockal.com/mcp und nockal.com/feuerwerk/mcp). Die Whitelist aus #427 bekommt genau diesen Pfad dazu.
Agent → Relay: MCP über Streamable HTTP.
Tab → Relay: WebSocket auf derselben Origin. Die CSP aus #427 (connect-src 'self') erlaubt das schon, 'self' deckt wss: auf demselben Host ab.
Ob ein Token oder eine Sitzung gültig ist, entscheidet weiterhin die PHP-API. Es gibt also nur eine Stelle, die Konten kennt.
Gemessen am 2026-10-17 mit einem Wegwerf-Endpunkt hinter nginx, danach wieder entfernt: Die Brandmauer reicht den WebSocket-Upgrade durch (101, Sec-WebSocket-Accept korrekt, echter Client bekommt die Nachricht), und SSE kommt ungepuffert an (je Event 2–3 ms). Beides auf beiden Adressen.
Authentifizierung
Agent → Relay: persönlicher Agent-Token je Konto
Im Kontomenü gibt es Agent tokens…: anlegen (wird nur einmal angezeigt), Name, Ablaufdatum, letzte Nutzung, widerrufen.
Gespeichert wird nur sha256 des Tokens, Dateien 0640 wie die Sitzungen.
Einrichten in Claude Code: claude mcp add --transport http feuerwerk https://feuerwerk.nockal.com/mcp --header "Authorization: Bearer fwa_…"
Der Token gilt nur für /mcp, nicht für die REST-API.
Falsche Tokens zählen in die Login-Bremse aus #427 (5 Fehlversuche, 15 min Sperre).
Bewusst kein OAuth: eigener Authorization-Server, Dynamic Client Registration, Consent-Seite und Refresh sind für „erstmal nur Claude Code“ zu viel. Kommt es später dazu, bleiben die Werkzeuge dieselben.
Tab → Relay: die normale Sitzung
Secure-Cookie plus Origin-Prüfung, kein neuer Schlüssel.
Verbunden wird erst, wenn der User im Editor Agent on einschaltet. Je Konto ist nur ein Tab aktiv, ein neuer übernimmt.
Ist kein Tab an, bekommt der Agent „no editor connected“. Ohne offenen Tab arbeitet der Agent nicht (Autosave).
Gäste (#428): kein Agent. Ohne Konto gibt es keinen Token, und ein anonymer Zugang zum Relay wäre Mehraufwand samt Missbrauchsfläche.
Werkzeuge (Entwurf)
Nicht 113 einzelne Tools, denn so viele Tools verwirren einen Agenten. Besser sind wenige allgemeine Tools und ein Katalog, den er abfragen kann:
screenshot: das Canvas als PNG, also genau das, was der User sieht.
Eine MCP-Resource feuerwerk://view mit Abo. Der Agent wird dann benachrichtigt, wenn der User den Tab oder die Auswahl wechselt.
Lesen:list_assets, get_asset, get_scene, get_graph und catalog (Node-Typen samt Ports, Property-Typen, Asset-Arten).
Ändern:run_command mit Name und Argumenten, geprüft gegen ein Schema je Command. Mehrere Commands lassen sich zu einem Undo-Schritt bündeln, damit ein „bau mir ein Jump-Behavior“ auch mit einem einzigen Strg+Z wieder weg ist.
Play-Tests (Wunsch des Users, 2026-10-18):press_keys schickt Tasten ins laufende Spiel (drücken, halten, loslassen, mit Dauer), pointer Mausbewegung und Klicks in Weltkoordinaten der Spielkamera. get_runtime liest den Zustand zur Laufzeit: Objekte mit Position, Rotation und Variablen, dazu die Konsole. So prüft der Agent selbst, ob das Gebaute tut, was es soll.
Klicks auf Koordinaten im Editor sind kein Weg für den Agenten. Sie sind zu brüchig, und dafür gibt es den Test-Hook. Eingaben ins laufende Spiel sind etwas anderes, siehe oben.
Grundlage ist eine Editor-API aus Commands und Abfragen, die MCP und Plugins (#117) gemeinsam nutzen. Das Relay reicht die Tool-Aufrufe nur an den Tab durch, die Werkzeuge selbst leben im Editor. __gm bleibt für die Tests.
Kein Kabelsalat (Punkt 2)
Der Agent gibt keine Koordinaten vor. Er legt Nodes und Kanten an, und der Editor ordnet sie an. Das ist eine reine Funktion graph/arrange.ts: Der Fluss läuft von links nach rechts (Ereignis → Bedingung → Aktion), die Anordnung ist in Schichten, und Nodes überlappen nie.
Was der User von Hand angeordnet hat, bleibt stehen. Neue Nodes kommen in eine freie Fläche daneben.
Regeln für den Agenten, im Tool-Text und im Katalog beschrieben:
Einen Wert lieber mit einem zweiten Get-Node holen, als ein Kabel quer über den Graph zu ziehen.
Zusammengehöriges kommt in eine Gruppe mit Notiz.
Ein Ausgang hängt an höchstens wenigen Eingängen.
Messbar machen:lint_graph liefert die Zahl der Kantenkreuzungen, die Überlappungen und die längsten Kanten. Damit kann der Agent selbst nachbessern, und die Tests haben eine Zahl.
Dieselbe Anordnung bekommt auch der User als Knopf Arrange im Graph.
Sicherheit
Der Agent hat genau die Rechte der angemeldeten Sitzung, nicht mehr. An Konto, Login und andere Projekte kommt er nicht heran.
Das Relay ist ein neuer öffentlicher Dienst und bekommt dieselbe Härtung wie #427: Auth, Bremse, Origin-Prüfung, Rechte-Matrix, Scan von außen.
Verbunden ist er nur, solange der User im Tab Agent on geschaltet hat. Eine sichtbare Anzeige zeigt das an, und mit einem Klick ist die Verbindung getrennt.
Prompt Injection: Der Agent liest Projektinhalte wie Asset-Namen, Notizen und Texte. Bei geteilten Projekten (#181) kann dort Fremdtext stehen. Löschen von Assets oder des Projekts sollte deshalb im Editor bestätigt werden müssen.
Etappen
Relay und Kontext: Container feuerwerk-mcp, nginx-Pfad /mcp, Agent-Tokens samt Verwaltung, Tab-Verbindung mit Agent on, dazu get_view, screenshot, View-Abo.
Lesen und run_command über die Commands, mit Undo-Bündelung.
arrange und lint_graph, dazu der Knopf Arrange.
Play-Tests: press_keys, pointer, get_runtime. Dazu ein Hinweis, wenn der Startszene eine Kamera fehlt.
Die übrigen Bereiche durchgehen (Pixel Art, Vector Art, DAW, Composition …), bis jedes Command im Katalog steht.
Tests
Unit: arrange (keine Überlappung, Kreuzungen auf Beispielgraphen unter einer festen Grenze, Handplatziertes bleibt stehen), Schema-Prüfung von run_command, Undo-Bündelung.
Relay: Protokolltest mit einem Fake-Tab, ohne Browser. Token gültig, falsch, abgelaufen, widerrufen. Fremde Origin abgewiesen. Zwei Konten sehen nie den Tab des anderen.
PHP: Token-Store und die neuen Routen in der Rechte-Matrix.
Play-Tests: Der Agent hält im laufenden Spiel eine Pfeiltaste, liest die Position über get_runtime und sieht sie wandern. Ein Klick über pointer löst ein Klick-Ereignis am getroffenen Objekt aus.
e2e: Ein MCP-Client-Skript meldet sich mit einem Agent-Token an, verbindet sich über das Relay mit dem Tab, legt ein Objekt samt Behavior „mit den Pfeiltasten bewegen“ an und startet Play. get_view muss nach einem Tabwechsel stimmen, und ein Strg+Z nimmt den Agenten-Schritt komplett zurück.
Fertig, wenn
Claude Code baut über den MCP ein kleines Spiel (Szene, Objekt, Behavior, Play), ohne dass der User klickt.
get_view und das View-Abo spiegeln Tab und Auswahl des Users.
Vom Agenten angelegte Graphen haben keine Überlappung, die Kreuzungen bleiben unter der Grenze aus den Tests.
Jede Änderung des Agenten lässt sich mit Strg+Z zurücknehmen.
Der Agent prüft ein gebautes Spiel selbst: Eingaben schicken, Laufzeitzustand lesen, ohne dass der User Tasten drückt.
Ein falscher, abgelaufener oder widerrufener Token kommt nicht durch, und ein Konto erreicht nie den Tab eines anderen.
Der ZAP-Scan von außen (wie in #427) zeigt am Relay keine neuen Befunde.
Es gibt eine Wiki-Seite MCP (Einrichten, Token, Werkzeuge, Regeln).
Entscheidungen (Kommentar 4716 und folgende)
Verbindung: B, MCP-Endpunkt auf stein2.
Client: vorerst nur Claude Code.
Ohne offenen Tab: nein, wegen des Autosave.
Bestätigung: nur beim Löschen.
Gäste: kein Agent (wäre Mehraufwand).
Etappen: alles in diesem Issue.
Authentifizierung: Agent-Token je Konto für /mcp, normale Sitzung für den Tab, kein OAuth.
Play-Tests: Der Agent soll Tasten und Maus im laufenden Spiel simulieren können (Wunsch des Users, 2026-10-18). Eigene Etappe 4.
Anlass: Ein KI-Agent (z. B. Claude Code) soll den Editor über einen MCP-Server bedienen können. Er arbeitet dabei im offenen Editor mit, sodass der User live sieht, was passiert.
## Was der MCP können soll (Randnotiz des Users)
1. **Den Editor komplett bedienen.**
2. **Kein Kabelsalat:** Wenn der Agent Behaviors anlegt oder bearbeitet, muss der Graph lesbar bleiben.
3. **Der Agent weiß, was der User gerade sieht:** welcher Tab offen ist, welches Objekt ausgewählt ist usw.
## Stand heute (im Code nachgesehen)
- Der ganze Zustand lebt im Browser-Tab: Projekt, Auswahl, offene Tabs, Play-Modus. Der Server kennt nur die gespeicherte Projektdatei.
- Jede Änderung läuft als Command über den Undo-Stack (`EditorState`, `src/editor/state.ts:476`). Es gibt 113 Command-Klassen.
- `window.__gm` (`src/editor/debugHook.ts`) ist die Brücke der e2e-Tests. Sie findet Widgets über ihren sichtbaren Text und liest den Zustand. Gedacht ist sie für Tests, als stabile API taugt sie nicht.
- Die Plugin-API (#113, `src/editor/plugins/pluginApi.ts`) kann bisher nur Assets auflisten, Änderungen melden und Tabs anlegen.
- Graphen kennen Gruppen und Notizen (`GraphAnnotation`). Eine automatische Anordnung von Nodes gibt es nicht. Wer einen Node anlegt, gibt seine Position selbst vor.
- Die CSP aus #427 erlaubt `connect-src 'self' data: blob:`. Eine Verbindung zum eigenen Host (auch `wss:`) geht damit, zu anderen Hosts nicht.
## Grundsatz: der Agent arbeitet im offenen Editor, nicht an der Datei
Würde der MCP die Projektdatei auf dem Server direkt bearbeiten, gäbe es zwei Probleme. Er käme dem Autosave eines offenen Tabs in die Quere, und Punkt 3 wäre gar nicht machbar. Deshalb läuft alles über den offenen Tab:
- Jede Änderung des Agenten ist ein ganz normales Command. Der User sieht sie sofort und kann sie mit Strg+Z rückgängig machen.
- Gespeichert wird wie immer über das Autosave des Tabs.
## Verbindung: MCP-Endpunkt auf stein2 (entschieden, Kommentar 4716)
- **Relay-Dienst `feuerwerk-mcp`:** ein kleiner Node-Dienst im eigenen Container, gehärtet wie `feuerwerk-video`. PHP-FPM kann keine dauerhaften Verbindungen halten, deshalb nicht in der API.
- nginx leitet `/mcp` dorthin (auf beiden Adressen: `feuerwerk.nockal.com/mcp` und `nockal.com/feuerwerk/mcp`). Die Whitelist aus #427 bekommt genau diesen Pfad dazu.
- **Agent → Relay:** MCP über Streamable HTTP.
- **Tab → Relay:** WebSocket auf derselben Origin. Die CSP aus #427 (`connect-src 'self'`) erlaubt das schon, `'self'` deckt `wss:` auf demselben Host ab.
- Ob ein Token oder eine Sitzung gültig ist, entscheidet weiterhin die PHP-API. Es gibt also nur eine Stelle, die Konten kennt.
- **Gemessen am 2026-10-17** mit einem Wegwerf-Endpunkt hinter nginx, danach wieder entfernt: Die Brandmauer reicht den WebSocket-Upgrade durch (101, `Sec-WebSocket-Accept` korrekt, echter Client bekommt die Nachricht), und SSE kommt ungepuffert an (je Event 2–3 ms). Beides auf beiden Adressen.
## Authentifizierung
**Agent → Relay: persönlicher Agent-Token je Konto**
- Im Kontomenü gibt es *Agent tokens…*: anlegen (wird nur einmal angezeigt), Name, Ablaufdatum, letzte Nutzung, widerrufen.
- Gespeichert wird nur `sha256` des Tokens, Dateien 0640 wie die Sitzungen.
- Einrichten in Claude Code: `claude mcp add --transport http feuerwerk https://feuerwerk.nockal.com/mcp --header "Authorization: Bearer fwa_…"`
- Der Token gilt **nur für `/mcp`**, nicht für die REST-API.
- Falsche Tokens zählen in die Login-Bremse aus #427 (5 Fehlversuche, 15 min Sperre).
- Bewusst kein OAuth: eigener Authorization-Server, Dynamic Client Registration, Consent-Seite und Refresh sind für „erstmal nur Claude Code“ zu viel. Kommt es später dazu, bleiben die Werkzeuge dieselben.
**Tab → Relay: die normale Sitzung**
- `Secure`-Cookie plus Origin-Prüfung, kein neuer Schlüssel.
- Verbunden wird erst, wenn der User im Editor *Agent on* einschaltet. Je Konto ist nur ein Tab aktiv, ein neuer übernimmt.
- Ist kein Tab an, bekommt der Agent „no editor connected“. Ohne offenen Tab arbeitet der Agent nicht (Autosave).
**Gäste (#428):** kein Agent. Ohne Konto gibt es keinen Token, und ein anonymer Zugang zum Relay wäre Mehraufwand samt Missbrauchsfläche.
## Werkzeuge (Entwurf)
Nicht 113 einzelne Tools, denn so viele Tools verwirren einen Agenten. Besser sind wenige allgemeine Tools und ein Katalog, den er abfragen kann:
- **Kontext (Punkt 3):**
- `get_view`: aktiver Tab, offenes Dokument, Auswahl (Objekt, Node, Keyframe …), Kamera und Zoom, Play-Status, offener Dialog.
- `screenshot`: das Canvas als PNG, also genau das, was der User sieht.
- Eine MCP-Resource `feuerwerk://view` mit Abo. Der Agent wird dann benachrichtigt, wenn der User den Tab oder die Auswahl wechselt.
- **Lesen:** `list_assets`, `get_asset`, `get_scene`, `get_graph` und `catalog` (Node-Typen samt Ports, Property-Typen, Asset-Arten).
- **Ändern:** `run_command` mit Name und Argumenten, geprüft gegen ein Schema je Command. Mehrere Commands lassen sich zu einem Undo-Schritt bündeln, damit ein „bau mir ein Jump-Behavior“ auch mit einem einzigen Strg+Z wieder weg ist.
- **Bedienen:** Tab öffnen, auswählen, Play/Stop, Undo/Redo.
- **Play-Tests (Wunsch des Users, 2026-10-18):** `press_keys` schickt Tasten ins laufende Spiel (drücken, halten, loslassen, mit Dauer), `pointer` Mausbewegung und Klicks in Weltkoordinaten der Spielkamera. `get_runtime` liest den Zustand zur Laufzeit: Objekte mit Position, Rotation und Variablen, dazu die Konsole. So prüft der Agent selbst, ob das Gebaute tut, was es soll.
- Klicks auf Koordinaten **im Editor** sind kein Weg für den Agenten. Sie sind zu brüchig, und dafür gibt es den Test-Hook. Eingaben ins laufende Spiel sind etwas anderes, siehe oben.
Grundlage ist eine Editor-API aus Commands und Abfragen, die MCP und Plugins (#117) gemeinsam nutzen. Das Relay reicht die Tool-Aufrufe nur an den Tab durch, die Werkzeuge selbst leben im Editor. `__gm` bleibt für die Tests.
## Kein Kabelsalat (Punkt 2)
- **Der Agent gibt keine Koordinaten vor.** Er legt Nodes und Kanten an, und der Editor ordnet sie an. Das ist eine reine Funktion `graph/arrange.ts`: Der Fluss läuft von links nach rechts (Ereignis → Bedingung → Aktion), die Anordnung ist in Schichten, und Nodes überlappen nie.
- **Was der User von Hand angeordnet hat, bleibt stehen.** Neue Nodes kommen in eine freie Fläche daneben.
- **Regeln für den Agenten**, im Tool-Text und im Katalog beschrieben:
- Einen Wert lieber mit einem zweiten Get-Node holen, als ein Kabel quer über den Graph zu ziehen.
- Zusammengehöriges kommt in eine Gruppe mit Notiz.
- Ein Ausgang hängt an höchstens wenigen Eingängen.
- **Messbar machen:** `lint_graph` liefert die Zahl der Kantenkreuzungen, die Überlappungen und die längsten Kanten. Damit kann der Agent selbst nachbessern, und die Tests haben eine Zahl.
- Dieselbe Anordnung bekommt auch der User als Knopf *Arrange* im Graph.
## Sicherheit
- Der Agent hat genau die Rechte der angemeldeten Sitzung, nicht mehr. An Konto, Login und andere Projekte kommt er nicht heran.
- Das Relay ist ein neuer öffentlicher Dienst und bekommt dieselbe Härtung wie #427: Auth, Bremse, Origin-Prüfung, Rechte-Matrix, Scan von außen.
- Verbunden ist er nur, solange der User im Tab *Agent on* geschaltet hat. Eine sichtbare Anzeige zeigt das an, und mit einem Klick ist die Verbindung getrennt.
- **Prompt Injection:** Der Agent liest Projektinhalte wie Asset-Namen, Notizen und Texte. Bei geteilten Projekten (#181) kann dort Fremdtext stehen. Löschen von Assets oder des Projekts sollte deshalb im Editor bestätigt werden müssen.
## Etappen
1. Relay und Kontext: Container `feuerwerk-mcp`, nginx-Pfad `/mcp`, Agent-Tokens samt Verwaltung, Tab-Verbindung mit *Agent on*, dazu `get_view`, `screenshot`, View-Abo.
2. Lesen und `run_command` über die Commands, mit Undo-Bündelung.
3. `arrange` und `lint_graph`, dazu der Knopf *Arrange*.
4. Play-Tests: `press_keys`, `pointer`, `get_runtime`. Dazu ein Hinweis, wenn der Startszene eine Kamera fehlt.
5. Die übrigen Bereiche durchgehen (Pixel Art, Vector Art, DAW, Composition …), bis jedes Command im Katalog steht.
## Tests
- Unit: `arrange` (keine Überlappung, Kreuzungen auf Beispielgraphen unter einer festen Grenze, Handplatziertes bleibt stehen), Schema-Prüfung von `run_command`, Undo-Bündelung.
- Relay: Protokolltest mit einem Fake-Tab, ohne Browser. Token gültig, falsch, abgelaufen, widerrufen. Fremde Origin abgewiesen. Zwei Konten sehen nie den Tab des anderen.
- PHP: Token-Store und die neuen Routen in der Rechte-Matrix.
- Play-Tests: Der Agent hält im laufenden Spiel eine Pfeiltaste, liest die Position über `get_runtime` und sieht sie wandern. Ein Klick über `pointer` löst ein Klick-Ereignis am getroffenen Objekt aus.
- e2e: Ein MCP-Client-Skript meldet sich mit einem Agent-Token an, verbindet sich über das Relay mit dem Tab, legt ein Objekt samt Behavior „mit den Pfeiltasten bewegen“ an und startet Play. `get_view` muss nach einem Tabwechsel stimmen, und ein Strg+Z nimmt den Agenten-Schritt komplett zurück.
## Fertig, wenn
- Claude Code baut über den MCP ein kleines Spiel (Szene, Objekt, Behavior, Play), ohne dass der User klickt.
- `get_view` und das View-Abo spiegeln Tab und Auswahl des Users.
- Vom Agenten angelegte Graphen haben keine Überlappung, die Kreuzungen bleiben unter der Grenze aus den Tests.
- Jede Änderung des Agenten lässt sich mit Strg+Z zurücknehmen.
- Der Agent prüft ein gebautes Spiel selbst: Eingaben schicken, Laufzeitzustand lesen, ohne dass der User Tasten drückt.
- Ein falscher, abgelaufener oder widerrufener Token kommt nicht durch, und ein Konto erreicht nie den Tab eines anderen.
- Der ZAP-Scan von außen (wie in #427) zeigt am Relay keine neuen Befunde.
- Es gibt eine Wiki-Seite *MCP* (Einrichten, Token, Werkzeuge, Regeln).
## Entscheidungen (Kommentar 4716 und folgende)
1. **Verbindung:** B, MCP-Endpunkt auf stein2.
2. **Client:** vorerst nur Claude Code.
3. **Ohne offenen Tab:** nein, wegen des Autosave.
4. **Bestätigung:** nur beim Löschen.
5. **Gäste:** kein Agent (wäre Mehraufwand).
6. **Etappen:** alles in diesem Issue.
7. **Authentifizierung:** Agent-Token je Konto für `/mcp`, normale Sitzung für den Tab, kein OAuth.
8. **Play-Tests:** Der Agent soll Tasten und Maus im laufenden Spiel simulieren können (Wunsch des Users, 2026-10-18). Eigene Etappe 4.
meleki
added the new label 2026-10-16 10:41:55 +02:00
admin
added this to the Development project 2026-10-16 13:33:49 +02:00
admin
removed the new label 2026-10-16 13:34:10 +02:00
ich würde gleich mit B gehen: sprich es gibt einen mcp endpoint(s) mit dem ein agent arbeiten kann. dann müssten wir uns nur die authentifizierung überlegen
es reicht erstmal claude code
vorerst nicht - eben wegen autosave geschichten
ja, erstmal nur bei löschen
im prinzip kann das ruhig möglich sein, außer es ist extra mehraufwand, dann kann man es mal weglassen
alles hier
1. ich würde gleich mit B gehen: sprich es gibt einen mcp endpoint(s) mit dem ein agent arbeiten kann. dann müssten wir uns nur die authentifizierung überlegen
2. es reicht erstmal claude code
3. vorerst nicht - eben wegen autosave geschichten
4. ja, erstmal nur bei löschen
5. im prinzip kann das ruhig möglich sein, außer es ist extra mehraufwand, dann kann man es mal weglassen
6. alles hier
Danke, damit ist der Plan komplett. Den Issue-Text oben habe ich auf B umgestellt (Abschnitte Verbindung, Authentifizierung, Etappen, Tests, Fertig, wenn, Entscheidungen).
Entschieden
B: Relay-Dienst feuerwerk-mcp auf stein2, nginx leitet /mcp dorthin.
Agent-Token je Konto für /mcp, im Kontomenü unter Agent tokens…. Er wird nur einmal angezeigt, gespeichert wird nur sha256. Er gilt nicht für die REST-API, und Fehlversuche zählen in die Login-Bremse aus #427.
Der Tab verbindet sich mit der normalen Sitzung per WebSocket, erst nach Agent on. Je Konto ist nur ein Tab aktiv.
Kein OAuth vorerst, nur Claude Code, kein Betrieb ohne Tab, Bestätigung nur beim Löschen, keine Gäste, alles in diesem Issue.
Gemessen am 2026-10-17 (nach der Umstellung am Reverse Proxy)
Ich habe kurz einen Wegwerf-Endpunkt hinter nginx gestellt (location = /feuerwerk/mcp auf einen Node-Container) und danach wieder entfernt. nginx.conf ist wieder byteweise wie vorher, /mcp liefert wieder 404.
Prüfung
feuerwerk.nockal.com/mcp
nockal.com/feuerwerk/mcp
WebSocket-Upgrade (curl --http1.1)
101, Sec-WebSocket-Accept korrekt
101, Sec-WebSocket-Accept korrekt
Echter Client (Node WebSocket)
OPEN, Nachricht kommt an
OPEN, Nachricht kommt an
SSE, 5 Events im Sekundentakt
ungepuffert, 2–3 ms je Event
ungepuffert, 2–3 ms je Event
Damit passt der Transport für beide Richtungen: Streamable HTTP mit SSE für den Agenten, WebSocket für den Tab.
Hinweis für Etappe 1: X-Forwarded-For kommt am Relay an. Das Relay darf dem Header aber nur vertrauen, wenn die Verbindung von der Brandmauer kommt, genau wie bei der Login-Bremse in #427.
Danke, damit ist der Plan komplett. Den Issue-Text oben habe ich auf B umgestellt (Abschnitte *Verbindung*, *Authentifizierung*, *Etappen*, *Tests*, *Fertig, wenn*, *Entscheidungen*).
## Entschieden
- **B:** Relay-Dienst `feuerwerk-mcp` auf stein2, nginx leitet `/mcp` dorthin.
- **Agent-Token je Konto** für `/mcp`, im Kontomenü unter *Agent tokens…*. Er wird nur einmal angezeigt, gespeichert wird nur `sha256`. Er gilt nicht für die REST-API, und Fehlversuche zählen in die Login-Bremse aus #427.
- **Der Tab** verbindet sich mit der normalen Sitzung per WebSocket, erst nach *Agent on*. Je Konto ist nur ein Tab aktiv.
- Kein OAuth vorerst, nur Claude Code, kein Betrieb ohne Tab, Bestätigung nur beim Löschen, keine Gäste, alles in diesem Issue.
## Gemessen am 2026-10-17 (nach der Umstellung am Reverse Proxy)
Ich habe kurz einen Wegwerf-Endpunkt hinter nginx gestellt (`location = /feuerwerk/mcp` auf einen Node-Container) und danach wieder entfernt. nginx.conf ist wieder byteweise wie vorher, `/mcp` liefert wieder 404.
| Prüfung | feuerwerk.nockal.com/mcp | nockal.com/feuerwerk/mcp |
|---|---|---|
| WebSocket-Upgrade (`curl --http1.1`) | 101, `Sec-WebSocket-Accept` korrekt | 101, `Sec-WebSocket-Accept` korrekt |
| Echter Client (Node `WebSocket`) | OPEN, Nachricht kommt an | OPEN, Nachricht kommt an |
| SSE, 5 Events im Sekundentakt | ungepuffert, 2–3 ms je Event | ungepuffert, 2–3 ms je Event |
Damit passt der Transport für beide Richtungen: Streamable HTTP mit SSE für den Agenten, WebSocket für den Tab.
Hinweis für Etappe 1: `X-Forwarded-For` kommt am Relay an. Das Relay darf dem Header aber nur vertrauen, wenn die Verbindung von der Brandmauer kommt, genau wie bei der Login-Bremse in #427.
Etappe 1 fertig: Relay und Kontext (48ec722, Wiki 5bb0780)
Gebaut
Agent-Token: Kontomenü → Agent tokens…. Anlegen mit Name und Laufzeit (30 Tage, 90 Tage, 1 Jahr), einmalige Anzeige mit fertiger claude mcp add …-Zeile, widerrufen. Gespeichert wird nur sha256 (api/lib/AgentTokens.php). Der Token öffnet nur /mcp. Falsche Tokens zählen in die Login-Bremse. Passwortwechsel, Umbenennen und Löschen des Kontos beenden seine Tokens.
Relaytools/mcp/: Node ohne Pakete, auch der WebSocket-Server. Container feuerwerk-mcp auf 172.16.0.1:8091, nginx leitet /feuerwerk/mcp dorthin. Token und Tab-Ticket prüft weiter die PHP-API, über zwei Routen, die nur mit dem Relay-Schlüssel antworten.
Tab: Kontomenü → Agent. WebSocket auf derselben Origin mit Sitzung, Origin-Prüfung und Einmal-Ticket. Ein Tab je Konto, ein neuer übernimmt. Nach einem Reload bleibt der Agent an, beim Abmelden geht er aus. Gäste bekommen nichts.
Werkzeuge:get_view (Projekt, Tab, Dokument, Auswahl mit Namen, Kamera, Play-Status, offener Dialog), screenshot, Resource feuerwerk://view mit Abo. Weil Claude Code Abos nicht verlässlich auswertet, hängt das Relay an die nächste Antwort eine Zeile, wenn sich die Ansicht geändert hat.
Badge neben dem Kontomenü mit der Zahl der Agenten, ein Klick schaltet ab.
CI startet das Relay vor php -S (tools/ci/serve.sh), e2e 71 fährt den ganzen Weg im Browser.
Wiki: neue Seite MCP, dazu API, Architecture, Development.
Tests
Prüfung
Ergebnis
Gate (atx)
316 Dateien, 4888 Tests
Relay-Protokolltest (Fake-API, Fake-Tabs)
23/23
get_view, Werkzeuge, socketUrl
16/16
PHP agents / rights
29 / 103 Checks
e2e 71 auf atx und gegen live
je 10/10, kein CSP-Verstoß
Echte Claude-CLI gegen live
get_view korrekt beantwortet
ZAP gegen /mcp
nichts der Stufe High oder Medium
Sechs Gegenproben (Besitzer beim Widerruf, Relay-Schlüssel, Origin, Sitzung je Konto, Namens-Rückfall, Agentenzählung): jede wird ohne ihre Prüfung rot. Am 18.10. habe ich mich außerdem selbst über Claude Code mit dem echten Tab verbunden, get_view und screenshot passten zueinander.
Funde
Beim Live-Test zeigte das Badge „Agent · 4“: Alte Sitzungen widerrufener Tokens wurden mitgezählt. Jetzt zählen nur Agenten mit offenem Stream oder einer Anfrage in den letzten 2 Minuten.
Die Brandmauer-Route nockal.com hat UseYarp: false. Dort kommt der Handshake durch, aber keine Nachricht vom Browser. Der Agent-Tab geht deshalb nur auf feuerwerk.nockal.com, so steht es im Wiki.
Beim offenen Popup ist title leer. Das ziehe ich in Etappe 2 nach.
Weiter mit Etappe 2: Lesen und run_command mit Undo-Bündelung.
## Etappe 1 fertig: Relay und Kontext (`48ec722`, Wiki `5bb0780`)
**Gebaut**
- **Agent-Token:** Kontomenü → *Agent tokens…*. Anlegen mit Name und Laufzeit (30 Tage, 90 Tage, 1 Jahr), einmalige Anzeige mit fertiger `claude mcp add …`-Zeile, widerrufen. Gespeichert wird nur `sha256` (`api/lib/AgentTokens.php`). Der Token öffnet nur `/mcp`. Falsche Tokens zählen in die Login-Bremse. Passwortwechsel, Umbenennen und Löschen des Kontos beenden seine Tokens.
- **Relay** `tools/mcp/`: Node ohne Pakete, auch der WebSocket-Server. Container `feuerwerk-mcp` auf `172.16.0.1:8091`, nginx leitet `/feuerwerk/mcp` dorthin. Token und Tab-Ticket prüft weiter die PHP-API, über zwei Routen, die nur mit dem Relay-Schlüssel antworten.
- **Tab:** Kontomenü → *Agent*. WebSocket auf derselben Origin mit Sitzung, Origin-Prüfung und Einmal-Ticket. Ein Tab je Konto, ein neuer übernimmt. Nach einem Reload bleibt der Agent an, beim Abmelden geht er aus. Gäste bekommen nichts.
- **Werkzeuge:** `get_view` (Projekt, Tab, Dokument, Auswahl mit Namen, Kamera, Play-Status, offener Dialog), `screenshot`, Resource `feuerwerk://view` mit Abo. Weil Claude Code Abos nicht verlässlich auswertet, hängt das Relay an die nächste Antwort eine Zeile, wenn sich die Ansicht geändert hat.
- **Badge** neben dem Kontomenü mit der Zahl der Agenten, ein Klick schaltet ab.
- CI startet das Relay vor `php -S` (`tools/ci/serve.sh`), e2e 71 fährt den ganzen Weg im Browser.
- Wiki: neue Seite *MCP*, dazu *API*, *Architecture*, *Development*.
**Tests**
| Prüfung | Ergebnis |
|---|---|
| Gate (atx) | 316 Dateien, 4888 Tests |
| Relay-Protokolltest (Fake-API, Fake-Tabs) | 23/23 |
| `get_view`, Werkzeuge, `socketUrl` | 16/16 |
| PHP agents / rights | 29 / 103 Checks |
| e2e 71 auf atx und gegen live | je 10/10, kein CSP-Verstoß |
| Echte Claude-CLI gegen live | `get_view` korrekt beantwortet |
| ZAP gegen `/mcp` | nichts der Stufe High oder Medium |
Sechs Gegenproben (Besitzer beim Widerruf, Relay-Schlüssel, Origin, Sitzung je Konto, Namens-Rückfall, Agentenzählung): jede wird ohne ihre Prüfung rot. Am 18.10. habe ich mich außerdem selbst über Claude Code mit dem echten Tab verbunden, `get_view` und `screenshot` passten zueinander.
**Funde**
- Beim Live-Test zeigte das Badge „Agent · 4“: Alte Sitzungen widerrufener Tokens wurden mitgezählt. Jetzt zählen nur Agenten mit offenem Stream oder einer Anfrage in den letzten 2 Minuten.
- Die Brandmauer-Route `nockal.com` hat `UseYarp: false`. Dort kommt der Handshake durch, aber keine Nachricht vom Browser. Der Agent-Tab geht deshalb nur auf `feuerwerk.nockal.com`, so steht es im Wiki.
- Beim offenen Popup ist `title` leer. Das ziehe ich in Etappe 2 nach.
Weiter mit Etappe 2: Lesen und `run_command` mit Undo-Bündelung.
Etappe 2 fertig: Lesen und Ändern über run_commands
Commit 25af0642, Wiki b8f8921 (Seite MCP, Abschnitt Changing the project, dazu Architecture). Gebaut und live, das Relay auf stein2 ist neu gestartet.
Was der Agent jetzt kann
Lesen:list_assets, get_asset (Eigenschaften mit ihren Feldern, Objekte einer Szene mit Namen), get_graph (Nodes mit ihren aktuellen Ports, Kanten, Gruppen) und catalog (Commands mit Argumenten, Nodes eines Graphen aus derselben Palette wie im Editor, Asset-Typen, Variablenarten).
Ändern:run_commands führt alle Schritte eines Aufrufs als einen Undo-Schritt aus („Agent: …“ im Edit-Verlauf). Scheitert ein Schritt, wird alles davor zurückgerollt, und die Antwort nennt Schritt und Grund, z. B. Step 8 (connect): Cannot connect number to exec.
Verweise: Ein Schritt mit "as": "walk" gibt späteren Schritten seine Id als "$walk". So legt ein Aufruf ein Behavior an und befüllt es gleich.
23 Commands für Assets, Variablen, Szenen-Objekte und Graphen. Texturen, Fonts, Sounds und Videos brauchen eine Datei und gehen noch nicht.
Bedienen:open, select, play (play/pause/resume/stop), undo/redo.
Löschen fragt nach: Dialog „The agent asks: Delete …?“ mit demselben Text wie beim eigenen Löschen. Der Aufruf wartet bis zu 110 s, der Tab meldet dem Relay wait, das ihm dafür 2 Minuten statt 30 s gibt.
Die Argument-Schemas stehen nur in tools.json, der Editor prüft jeden Aufruf dagegen (argCheck.ts).
Fund aus Etappe 1 behoben: Ein offenes Menü nennt in get_view jetzt seine ersten Einträge statt eines leeren Titels.
Tests
Prüfung
Ergebnis
Gate (melektaus-atx)
CHECK EXIT 0, 317 Dateien, 4903 Tests
agent-edit / agent-view
14/14 / 10/10
Relay-Test mit wait
24/24
e2e 71 auf atx
16/16
e2e 71 gegen die Live-Seite
16/16
Der Fertig-Fall läuft in e2e 71: Ein Aufruf baut Sprite und Behavior („On key held“ → „Move“ ← „Owner“) und startet Play. Bei gedrückter Pfeiltaste läuft das Objekt von x 0 auf −125. Ein Strg+Z stellt die Assets exakt wieder her.
Vier Gegenproben sind rot geworden: ohne Zurückrollen, mit einem Undo, das nur einen Teil zurücknimmt, ohne Löschfrage und mit einem Relay, das wait ignoriert.
Beim Testen gefunden: e2e 71 hing nach einem Fehler 30 s in Page.navigate, weil der beforeunload-Schutz bei ungespeichertem Projekt die Seite festhielt und den eigentlichen Fehler überdeckte. Das Modul meldet jetzt zuerst den Fehler und wartet vor dem Navigieren aufs Speichern.
Offen
Mit einer echten Claude-Code-Sitzung sind die neuen Werkzeuge noch nicht gefahren worden. Die e2e-Tests nutzen einen MCP-Client per Skript. Ob ein Agent allein aus den Beschreibungen ein Spiel baut, ist damit nicht gezeigt.
Neue Nodes ohne Position landen vorerst in einer Reihe rechts vom Bestehenden. Anordnung (arrange) und lint_graph sind Etappe 3.
Der CI-Lauf zu 25af0642 ist zum Zeitpunkt dieses Kommentars noch nicht gelesen.
## Etappe 2 fertig: Lesen und Ändern über `run_commands`
Commit `25af0642`, Wiki `b8f8921` (Seite *MCP*, Abschnitt *Changing the project*, dazu *Architecture*). Gebaut und live, das Relay auf stein2 ist neu gestartet.
### Was der Agent jetzt kann
- **Lesen:** `list_assets`, `get_asset` (Eigenschaften mit ihren Feldern, Objekte einer Szene mit Namen), `get_graph` (Nodes mit ihren aktuellen Ports, Kanten, Gruppen) und `catalog` (Commands mit Argumenten, Nodes eines Graphen aus derselben Palette wie im Editor, Asset-Typen, Variablenarten).
- **Ändern:** `run_commands` führt alle Schritte eines Aufrufs als **einen Undo-Schritt** aus („Agent: …“ im Edit-Verlauf). Scheitert ein Schritt, wird alles davor zurückgerollt, und die Antwort nennt Schritt und Grund, z. B. `Step 8 (connect): Cannot connect number to exec`.
- **Verweise:** Ein Schritt mit `"as": "walk"` gibt späteren Schritten seine Id als `"$walk"`. So legt ein Aufruf ein Behavior an und befüllt es gleich.
- **23 Commands** für Assets, Variablen, Szenen-Objekte und Graphen. Texturen, Fonts, Sounds und Videos brauchen eine Datei und gehen noch nicht.
- **Bedienen:** `open`, `select`, `play` (play/pause/resume/stop), `undo`/`redo`.
- **Löschen fragt nach:** Dialog „The agent asks: Delete …?“ mit demselben Text wie beim eigenen Löschen. Der Aufruf wartet bis zu 110 s, der Tab meldet dem Relay `wait`, das ihm dafür 2 Minuten statt 30 s gibt.
- Die Argument-Schemas stehen nur in `tools.json`, der Editor prüft jeden Aufruf dagegen (`argCheck.ts`).
- **Fund aus Etappe 1 behoben:** Ein offenes Menü nennt in `get_view` jetzt seine ersten Einträge statt eines leeren Titels.
### Tests
| Prüfung | Ergebnis |
|---|---|
| Gate (melektaus-atx) | `CHECK EXIT 0`, 317 Dateien, 4903 Tests |
| `agent-edit` / `agent-view` | 14/14 / 10/10 |
| Relay-Test mit `wait` | 24/24 |
| e2e 71 auf atx | 16/16 |
| e2e 71 gegen die Live-Seite | 16/16 |
- Der Fertig-Fall läuft in e2e 71: Ein Aufruf baut Sprite und Behavior („On key held“ → „Move“ ← „Owner“) und startet Play. Bei gedrückter Pfeiltaste läuft das Objekt von x 0 auf −125. Ein Strg+Z stellt die Assets exakt wieder her.
- Vier Gegenproben sind rot geworden: ohne Zurückrollen, mit einem Undo, das nur einen Teil zurücknimmt, ohne Löschfrage und mit einem Relay, das `wait` ignoriert.
- Beim Testen gefunden: e2e 71 hing nach einem Fehler 30 s in `Page.navigate`, weil der `beforeunload`-Schutz bei ungespeichertem Projekt die Seite festhielt und den eigentlichen Fehler überdeckte. Das Modul meldet jetzt zuerst den Fehler und wartet vor dem Navigieren aufs Speichern.
### Offen
- Mit einer echten Claude-Code-Sitzung sind die neuen Werkzeuge noch nicht gefahren worden. Die e2e-Tests nutzen einen MCP-Client per Skript. Ob ein Agent allein aus den Beschreibungen ein Spiel baut, ist damit nicht gezeigt.
- Neue Nodes ohne Position landen vorerst in einer Reihe rechts vom Bestehenden. Anordnung (`arrange`) und `lint_graph` sind Etappe 3.
- Der CI-Lauf zu `25af0642` ist zum Zeitpunkt dieses Kommentars noch nicht gelesen.
Claude Code hat über den MCP in einem leeren Projekt ein Objekt gebaut, das mit den Pfeiltasten läuft. Der User hat es im Spiel ausprobiert: funktioniert.
4 Undo-Schritte, alle „Agent: …“: Szene Main samt Startszene, Sprite Player, Behavior Arrow keys walk unter dem Player. Dann der Graph in einemrun_commands-Aufruf mit 21 Schritten: 4× On key held → je ein Move (±200 px/s, dt vom Ereignis), object von einem gemeinsamen Owner. Dazu eine Kamera und das Aufräumen des Graphen.
Argumente, Ports aus catalog und die $name-Verweise haben auf Anhieb gepasst. Kein Schritt ist gescheitert.
open und die Meldung zur geänderten Ansicht funktionieren. Der offene Punkt aus Etappe 1 ist damit bestätigt.
Funde
Kabelsalat, wie erwartet: Ohne Position landen alle 9 Nodes in einer Reihe (x 0 bis 2080, y 0). Der Owner zieht Kabel über 2000 px quer durch alle anderen Nodes. Das Aufräumen von Hand hat 9 move_node gekostet, die Node-Höhen musste der Agent raten. Das ist Etappe 3.
Die fehlende Kamera meldet niemand. Ein leeres Projekt hat keine Kamera, und weder catalog noch die Anweisungen des Relays erwähnen, dass eine Szene eine braucht. Aufgefallen ist es erst am Screenshot („No active camera“). Kommt als Hinweis in Etappe 4.
Der Agent kann sein Ergebnis nicht selbst prüfen. Es fehlen Eingaben ins laufende Spiel und das Lesen des Laufzeitzustands.
Neu im Plan: Play-Tests (Wunsch des Users)
Der Agent soll Tasten und Maus im laufenden Spiel simulieren können, damit er Play-Tests selbst fahren kann. Der Issue-Text hat dafür eine eigene Etappe 4 bekommen, die bisherige Etappe 4 heißt jetzt 5:
press_keys: Tasten drücken, halten, loslassen, mit Dauer.
pointer: Mausbewegung und Klicks in Weltkoordinaten der Spielkamera.
get_runtime: Objekte mit Position, Rotation und Variablen, dazu die Konsole.
Tests und Fertig, wenn sind im Issue-Text nachgezogen. Weiter geht es jetzt mit Etappe 3 (arrange, lint_graph, Knopf Arrange).
## Echter Agententest zu Etappe 2
Claude Code hat über den MCP in einem leeren Projekt ein Objekt gebaut, das mit den Pfeiltasten läuft. Der User hat es im Spiel ausprobiert: funktioniert.
- 4 Undo-Schritte, alle „Agent: …“: Szene *Main* samt Startszene, Sprite *Player*, Behavior *Arrow keys walk* unter dem Player. Dann der Graph in **einem** `run_commands`-Aufruf mit 21 Schritten: 4× *On key held* → je ein *Move* (±200 px/s, `dt` vom Ereignis), `object` von einem gemeinsamen *Owner*. Dazu eine Kamera und das Aufräumen des Graphen.
- Argumente, Ports aus `catalog` und die `$name`-Verweise haben auf Anhieb gepasst. Kein Schritt ist gescheitert.
- `open` und die Meldung zur geänderten Ansicht funktionieren. Der offene Punkt aus Etappe 1 ist damit bestätigt.
## Funde
1. **Kabelsalat, wie erwartet:** Ohne Position landen alle 9 Nodes in einer Reihe (x 0 bis 2080, y 0). Der Owner zieht Kabel über 2000 px quer durch alle anderen Nodes. Das Aufräumen von Hand hat 9 `move_node` gekostet, die Node-Höhen musste der Agent raten. Das ist Etappe 3.
2. **Die fehlende Kamera meldet niemand.** Ein leeres Projekt hat keine Kamera, und weder `catalog` noch die Anweisungen des Relays erwähnen, dass eine Szene eine braucht. Aufgefallen ist es erst am Screenshot („No active camera“). Kommt als Hinweis in Etappe 4.
3. **Der Agent kann sein Ergebnis nicht selbst prüfen.** Es fehlen Eingaben ins laufende Spiel und das Lesen des Laufzeitzustands.
## Neu im Plan: Play-Tests (Wunsch des Users)
Der Agent soll Tasten und Maus im laufenden Spiel simulieren können, damit er Play-Tests selbst fahren kann. Der Issue-Text hat dafür eine eigene **Etappe 4** bekommen, die bisherige Etappe 4 heißt jetzt 5:
- `press_keys`: Tasten drücken, halten, loslassen, mit Dauer.
- `pointer`: Mausbewegung und Klicks in Weltkoordinaten der Spielkamera.
- `get_runtime`: Objekte mit Position, Rotation und Variablen, dazu die Konsole.
Tests und *Fertig, wenn* sind im Issue-Text nachgezogen. Weiter geht es jetzt mit Etappe 3 (`arrange`, `lint_graph`, Knopf *Arrange*).
Commits b9d1602b (Etappe 3) und 0dd671ea (Zählung im Badge), Wiki 9873ee6 (MCP, Behaviors).
Gebaut
Der Agent gibt keine Koordinaten mehr vor. Nodes ohne x/y ordnet der Editor am Ende des run_commands-Aufrufs an, im selben Undo-Schritt. Nodes, die schon da waren, bleiben stehen.
src/editor/graph/arrange.ts (reine Funktion): Fluss in Spalten von links nach rechts, Owner/Get direkt vor dem ersten Node, den er speist, je Spalte die Reihenfolge mit den wenigsten Kreuzungen, Höhen nach den verbundenen Ports, keine Überlappung. Gemessen wird am gezeichneten NodeView.
Knopf Arrange neben dem Magneten in allen 8 Graph-Tabs. Mit Auswahl nur die ausgewählten Nodes, sonst alle. Ein Undo-Schritt Arrange nodes.
Werkzeug lint_graph (Überlappungen, Kreuzungen, Kabel durch fremde Nodes, Rückwärts-Kanten, längste Kabel, je mit Beispiel-Ids) und Command arrange_graph.
Neue Regel in den Relay-Anweisungen: Ein Wert, der weit weg gebraucht wird, kommt von einem zweiten Get/Owner daneben, nicht über ein langes Kabel.
Live am Testprojekt über MCP geprüft
vorher (von Hand angeordnet)
nach arrange_graph
Überlappungen
0
0
Kreuzungen
16
8
Kabel durch Nodes
0
0
längstes Kabel
1030 px
317 px
Drei neue Nodes ohne Position landen rechts neben dem Bestand, der Bestand verrutscht nicht. Ein undo nimmt Nodes, Kanten und Anordnung zusammen zurück.
Funde
lint_graph hat eine Kreuzung übersehen: Tauschen zwei Links genau spiegelbildlich ihre Zeilen, treffen sie sich exakt auf einem Stützpunkt, und gezählt wurde nur ein Durchkreuzen zwischen zwei Punkten. Behoben (segmentsMeet), der neue Test war vorher rot.
Korrektur zu meiner Zahl von gestern: Der Pfeiltasten-Graph mit einem Owner für vier Moves kommt nicht unter 8 Kreuzungen (nicht 7). Der Owner speist object in Zeile 2 des Moves, zwischen exec und dt der Taste.
Badge zeigte „Agent · 2/3“ bei einer Sitzung. Zwei Ursachen: Ein Stream, den Claude Code während der Token-Prüfung abbricht, blieb für immer gezählt, und die zwei Ersatz-Sessions, die Claude Code bei jedem Verbinden anlegt, zählten je 2 Minuten mit. Jetzt zählt eine Session nur mit offenem Stream oder einem Werkzeugaufruf in den letzten 2 Minuten. Rest: Nach einem Relay-Neustart steht das Badge manchmal 2 Minuten auf 2.
Tests
graph-arrange, agent-edit, snap-toggle: 33/33. relay.test.ts: 27/27 (drei neue zur Zählung).
Gegenproben: vier an Anordnung und Edit-Plan, zwei an der Zählung, alle rot.
e2e 71 auf melektaus-atx: 18/18. Gate: CHECK EXIT 0, 318 Dateien, 4917 Tests (vor dem Lint-Fix gemessen).
Nächstes: Wunsch des Users von heute: Der Agent soll die Tabs so öffnen und wechseln, dass man sieht, was er gerade bearbeitet. Danach Etappe 4 (Play-Tests).
## Etappe 3 fertig: Anordnen und `lint_graph`
Commits `b9d1602b` (Etappe 3) und `0dd671ea` (Zählung im Badge), Wiki `9873ee6` (*MCP*, *Behaviors*).
**Gebaut**
- Der Agent gibt keine Koordinaten mehr vor. Nodes ohne `x`/`y` ordnet der Editor am Ende des `run_commands`-Aufrufs an, im selben Undo-Schritt. Nodes, die schon da waren, bleiben stehen.
- `src/editor/graph/arrange.ts` (reine Funktion): Fluss in Spalten von links nach rechts, Owner/Get direkt vor dem ersten Node, den er speist, je Spalte die Reihenfolge mit den wenigsten Kreuzungen, Höhen nach den verbundenen Ports, keine Überlappung. Gemessen wird am gezeichneten `NodeView`.
- Knopf **Arrange** neben dem Magneten in allen 8 Graph-Tabs. Mit Auswahl nur die ausgewählten Nodes, sonst alle. Ein Undo-Schritt *Arrange nodes*.
- Werkzeug `lint_graph` (Überlappungen, Kreuzungen, Kabel durch fremde Nodes, Rückwärts-Kanten, längste Kabel, je mit Beispiel-Ids) und Command `arrange_graph`.
- Neue Regel in den Relay-Anweisungen: Ein Wert, der weit weg gebraucht wird, kommt von einem zweiten Get/Owner daneben, nicht über ein langes Kabel.
**Live am Testprojekt über MCP geprüft**
| | vorher (von Hand angeordnet) | nach `arrange_graph` |
|---|---|---|
| Überlappungen | 0 | 0 |
| Kreuzungen | 16 | 8 |
| Kabel durch Nodes | 0 | 0 |
| längstes Kabel | 1030 px | 317 px |
Drei neue Nodes ohne Position landen rechts neben dem Bestand, der Bestand verrutscht nicht. Ein `undo` nimmt Nodes, Kanten und Anordnung zusammen zurück.
**Funde**
- `lint_graph` hat eine Kreuzung übersehen: Tauschen zwei Links genau spiegelbildlich ihre Zeilen, treffen sie sich exakt auf einem Stützpunkt, und gezählt wurde nur ein Durchkreuzen zwischen zwei Punkten. Behoben (`segmentsMeet`), der neue Test war vorher rot.
- Korrektur zu meiner Zahl von gestern: Der Pfeiltasten-Graph mit einem Owner für vier Moves kommt nicht unter **8** Kreuzungen (nicht 7). Der Owner speist `object` in Zeile 2 des Moves, zwischen `exec` und `dt` der Taste.
- Badge zeigte „Agent · 2/3“ bei einer Sitzung. Zwei Ursachen: Ein Stream, den Claude Code während der Token-Prüfung abbricht, blieb für immer gezählt, und die zwei Ersatz-Sessions, die Claude Code bei jedem Verbinden anlegt, zählten je 2 Minuten mit. Jetzt zählt eine Session nur mit offenem Stream oder einem Werkzeugaufruf in den letzten 2 Minuten. Rest: Nach einem Relay-Neustart steht das Badge manchmal 2 Minuten auf 2.
**Tests**
- `graph-arrange`, `agent-edit`, `snap-toggle`: 33/33. `relay.test.ts`: 27/27 (drei neue zur Zählung).
- Gegenproben: vier an Anordnung und Edit-Plan, zwei an der Zählung, alle rot.
- e2e 71 auf `melektaus-atx`: 18/18. Gate: `CHECK EXIT 0`, 318 Dateien, 4917 Tests (vor dem Lint-Fix gemessen).
- Live: Badge „Agent · 1“, `lint_graph` meldet 8 Kreuzungen, passend zum Screenshot.
**Nächstes:** Wunsch des Users von heute: Der Agent soll die Tabs so öffnen und wechseln, dass man sieht, was er gerade bearbeitet. Danach Etappe 4 (Play-Tests).
Der Editor geht mit dem Agenten mit, und der CI-Fix zu Etappe 3
Commits 732989a4 (CI-Fix) und 97e0d931 (Mitgehen und Kamera), Wiki 3e7956c.
CI-Fix: Suite 719 zu 0dd671e war rot
e2e 65 (Song): mein Fehler aus Etappe 3. Der Knopf Arrange steht in jeder Graph-Kopfzeile, also auch im Song-Tab. Dort hat er Bake und Fit über den rechten Rand des Tabs geschoben. Der Fit-Klick ging ins Leere, die letzte Spur blieb unter der Kante, und ihr Menü mit „Add track below“ ging nie auf.
Fix: Der Song-Tab zeigt Arrange nur in der Routing-Ansicht. Auf der Zeitleiste war er ohnehin ausgegraut. SnapToggle.setArrangeShown blendet ihn aus und legt die Kopfzeile neu aus. Der Magnet bleibt, wo er war.
e2e 65 auf melektaus-atx: vorher rot (derselbe Fehler wie in CI), jetzt 59/59.
e2e 34 „the pause holds the stream“: der offene Wackler aus Task 712 (5b9d084), nicht durch #429. Der damals eingebaute Wert zeigt diesmal, dass der Stream schon vor der Pause hinterherlief (skipped 12950). Die Pause hat ihn also nicht aus dem Tritt gebracht. Auf atx lief der Check grün. Die Ursache bleibt offen.
Mitgehen: Du siehst, woran der Agent arbeitet
Nach jedem run_commands zeigt der Editor, woran der letzte Schritt gearbeitet hat:
Graph: Der Tab geht auf, die angefassten Nodes sind ausgewählt, gelöschte nicht.
Szene oder Container: Er erscheint mit den Objekten ausgewählt. Liegt das Objekt in einer anderen Szene, wechselt der Editor dorthin, und zwar im selben Undo-Schritt. Sonst hätte Strg+Z zuerst nur den Szenenwechsel zurückgenommen.
Anderes Asset: Es erscheint im Inspector.
Kamera: Ist der Graph-Tab schon offen, fährt die Kamera den Nodes nach. Sind sie im Bild, bleibt sie stehen. Sonst fährt sie nur so weit wie nötig und behält den Zoom. Nur was bei diesem Zoom nicht hineinpasst, wird wie mit Fit eingerahmt.
Schalter Follow agent im Kontomenü unter Agent. Er ist standardmäßig an und bleibt im Browser gespeichert. Während das Spiel läuft, geht der Editor nie mit.
20/20. Neu 71g4: Ein Node 3000 px rechts liegt danach 24 px innerhalb des Rands, Zoom bleibt 1
e2e 65 auf atx
59/59
Gate auf atx
CHECK EXIT 0, 318 Dateien, 4931 Tests
Live über eine echte MCP-Sitzung
Tab geht auf, Nodes und Objekt sind ausgewählt. Die Kamera fährt erst mit dem neuen Build hin, der alte ließ den Node draußen
Live gebaut ist der Stand. Den CI-Lauf zu 97e0d93 lese ich, bevor etwas daraufkommt.
## Der Editor geht mit dem Agenten mit, und der CI-Fix zu Etappe 3
Commits `732989a4` (CI-Fix) und `97e0d931` (Mitgehen und Kamera), Wiki `3e7956c`.
### CI-Fix: Suite 719 zu `0dd671e` war rot
- **e2e 65 (Song): mein Fehler aus Etappe 3.** Der Knopf *Arrange* steht in jeder Graph-Kopfzeile, also auch im Song-Tab. Dort hat er *Bake* und *Fit* über den rechten Rand des Tabs geschoben. Der Fit-Klick ging ins Leere, die letzte Spur blieb unter der Kante, und ihr Menü mit „Add track below“ ging nie auf.
- Fix: Der Song-Tab zeigt *Arrange* nur in der Routing-Ansicht. Auf der Zeitleiste war er ohnehin ausgegraut. `SnapToggle.setArrangeShown` blendet ihn aus und legt die Kopfzeile neu aus. Der Magnet bleibt, wo er war.
- e2e 65 auf `melektaus-atx`: vorher rot (derselbe Fehler wie in CI), jetzt 59/59.
- **e2e 34 „the pause holds the stream“: der offene Wackler aus Task 712** (`5b9d084`), nicht durch #429. Der damals eingebaute Wert zeigt diesmal, dass der Stream schon **vor** der Pause hinterherlief (`skipped` 12950). Die Pause hat ihn also nicht aus dem Tritt gebracht. Auf atx lief der Check grün. Die Ursache bleibt offen.
### Mitgehen: Du siehst, woran der Agent arbeitet
- Nach jedem `run_commands` zeigt der Editor, woran der letzte Schritt gearbeitet hat:
- **Graph:** Der Tab geht auf, die angefassten Nodes sind ausgewählt, gelöschte nicht.
- **Szene oder Container:** Er erscheint mit den Objekten ausgewählt. Liegt das Objekt in einer anderen Szene, wechselt der Editor dorthin, und zwar **im selben Undo-Schritt**. Sonst hätte Strg+Z zuerst nur den Szenenwechsel zurückgenommen.
- **Anderes Asset:** Es erscheint im Inspector.
- **Kamera:** Ist der Graph-Tab schon offen, fährt die Kamera den Nodes nach. Sind sie im Bild, bleibt sie stehen. Sonst fährt sie nur so weit wie nötig und behält den Zoom. Nur was bei diesem Zoom nicht hineinpasst, wird wie mit *Fit* eingerahmt.
- **Schalter *Follow agent*** im Kontomenü unter *Agent*. Er ist standardmäßig an und bleibt im Browser gespeichert. Während das Spiel läuft, geht der Editor nie mit.
### Tests
| Prüfung | Ergebnis |
|---|---|
| `agent-edit` (3 neue), `graph-framing` (6 neue), `snap-toggle` (1 neuer) | grün, jeder neue Test mit Gegenprobe rot |
| e2e 71 auf atx | 20/20. Neu 71g4: Ein Node 3000 px rechts liegt danach 24 px innerhalb des Rands, Zoom bleibt 1 |
| e2e 65 auf atx | 59/59 |
| Gate auf atx | `CHECK EXIT 0`, 318 Dateien, 4931 Tests |
| Live über eine echte MCP-Sitzung | Tab geht auf, Nodes und Objekt sind ausgewählt. Die Kamera fährt erst mit dem neuen Build hin, der alte ließ den Node draußen |
Live gebaut ist der Stand. Den CI-Lauf zu `97e0d93` lese ich, bevor etwas daraufkommt.
Mein Kommentar 4730 nannte die Ursache des Wacklers in e2e 34 („the pause holds the stream“) noch offen. Suite 721 zu 97e0d93 war dann wieder rot, nur noch mit diesem Check, jetzt mit 0 Unterläufen vor und 6745 nach der Pause.
Ursache: Direkt vor dem Check erzwingt der Test eine volle Garbage Collection für die Speichermessung. Auf dem CI-Runner hielt sie die Seite sekundenlang an, und der Player lief leer, bevor die Pause geklickt wurde: 0,02 s bzw. 0,05 s Vorlauf in 719/721, statt ~2 s in grünen CI-Läufen. Das Worklet zählt einen Unterlauf erst, wenn die Samples nachkommen, deshalb tauchte er erst nach dem Fortsetzen auf. Mit #429 hat das nichts zu tun, betroffen waren auch Läufe davor (Task 712).
Fixf296f427: Die Pause wird zuerst gemessen, an einem Stream mit mindestens 1 s Vorlauf. GC und Speichermessung kommen danach, während das Spiel noch läuft. Bewertet wird, was die Pause an Unterläufen hinzufügt.
Nachweis auf atx mit einem 5-s-Hänger der Seite an der alten GC-Stelle: 12375 Unterläufe vor der Pause, genauso viele danach. Die alte Bedingung wäre an diesen Werten rot, die neue ist grün (e2e 34: 148/148).
CI zu f296f42: Gate 723 und Suite 724 grün, 2119 e2e-Checks, Smokes 24/19/21. Der Check selbst lief mit 0 Unterläufen und ~2,2 s Vorlauf.
## Nachtrag: CI wieder grün
Mein Kommentar 4730 nannte die Ursache des Wacklers in e2e 34 („the pause holds the stream“) noch offen. Suite 721 zu `97e0d93` war dann wieder rot, nur noch mit diesem Check, jetzt mit 0 Unterläufen vor und 6745 nach der Pause.
**Ursache:** Direkt vor dem Check erzwingt der Test eine volle Garbage Collection für die Speichermessung. Auf dem CI-Runner hielt sie die Seite sekundenlang an, und der Player lief leer, bevor die Pause geklickt wurde: 0,02 s bzw. 0,05 s Vorlauf in 719/721, statt ~2 s in grünen CI-Läufen. Das Worklet zählt einen Unterlauf erst, wenn die Samples nachkommen, deshalb tauchte er erst nach dem Fortsetzen auf. Mit #429 hat das nichts zu tun, betroffen waren auch Läufe davor (Task 712).
**Fix** `f296f427`: Die Pause wird zuerst gemessen, an einem Stream mit mindestens 1 s Vorlauf. GC und Speichermessung kommen danach, während das Spiel noch läuft. Bewertet wird, was die Pause an Unterläufen hinzufügt.
- Nachweis auf atx mit einem 5-s-Hänger der Seite an der alten GC-Stelle: 12375 Unterläufe vor der Pause, genauso viele danach. Die alte Bedingung wäre an diesen Werten rot, die neue ist grün (e2e 34: 148/148).
- **CI zu `f296f42`: Gate 723 und Suite 724 grün**, 2119 e2e-Checks, Smokes 24/19/21. Der Check selbst lief mit 0 Unterläufen und ~2,2 s Vorlauf.
Der Agent kann ein gebautes Spiel jetzt selbst prüfen: Play starten, Tasten und Maus schicken, Zustand lesen. Der User muss keine Taste mehr drücken.
Neue Werkzeuge
play_input schickt Schritte ins laufende Spiel: Taste halten (hold), antippen, gedrückt lassen oder loslassen (keep), Maus klicken, drücken, loslassen, bewegen, Mausrad, warten. Halten und Warten zählen Spielsekunden.
Ziel der Maus ist ein Punkt in Welteinheiten oder ein Objekt (Id oder Name). Bei einem Klick auf ein Objekt meldet die Antwort, ob er getroffen hat.
Die Antwort nennt die verbrauchte Spielzeit, die noch gehaltenen Tasten, die Maus und neue Konsolenzeilen.
get_runtime liest das laufende Spiel: Objekte mit Id, Typ und Position, die eigenen Variablen der Behaviors, die Variables-Assets, Kamera, Tasten, Maus und Konsole. Benannte Objekte kommen mit allen Properties.
get_view und play melden, wenn die Szene keine aktive Kamera hat. Das war Fund 2 aus dem ersten Agententest (4724).
Abweichung vom Plan: Statt press_keys und pointer gibt es ein Werkzeug play_input. So kann eine Schrittfolge Tasten und Maus mischen, z. B. Shift halten und dabei klicken.
Grenzen
Der Editor-Tab muss im Vordergrund sein. Ein Hintergrund-Tab bekommt keine Frames, das Werkzeug sagt das sofort. Steht die Spielzeit 25 s still, bricht es ab, nennt den Schritt und lässt alle gehaltenen Tasten los.
Die echte Maus des Users über dem Game-Tab verschiebt die Spiel-Maus weiterhin. Steht im Wiki.
Live am Testprojekt gefunden und behoben
Ein Klick über den Namen des Objekts meldete hit: false, die Trefferprüfung suchte nur nach der Id.
get_runtime zeigte die eingebauten Schalter eines Behaviors (enabled, runInEditor …) als Variablen.
Danach live: 0,5 s →, 0,5 s ↑, 1 s ←, 0,25 s ↓ bei 200 px/s, der Player steht bei x −100, y −50, genau wie gerechnet. Der Klick über den Namen trifft.
Tests
Prüfung
Ergebnis
agent-play (neu), agent-edit, agent-view, relay
grün
Gegenproben
5 Verbiegungen, alle rot
e2e 71 (atx)
21/21. Der Agent hält ← 0,5 s (x −120 → −270) und klickt das Objekt (hit: true)
Gate (atx)
CHECK EXIT 0, 319 Dateien, 4944 Tests
e2e 71 lief vor den beiden Fixes, die sind durch Unit-Tests, Gate und den Live-Test abgedeckt. Den CI-Lauf zu 1943539 habe ich nicht abgewartet.
Wiki: MCP, neuer Abschnitt Playing the game.
Offen: Etappe 5 (die übrigen Bereiche in den Katalog). #429 bleibt bis dahin offen.
## Etappe 4: Play-Tests, fertig (`1943539`)
Der Agent kann ein gebautes Spiel jetzt selbst prüfen: Play starten, Tasten und Maus schicken, Zustand lesen. Der User muss keine Taste mehr drücken.
**Neue Werkzeuge**
- `play_input` schickt Schritte ins laufende Spiel: Taste halten (`hold`), antippen, gedrückt lassen oder loslassen (`keep`), Maus klicken, drücken, loslassen, bewegen, Mausrad, warten. Halten und Warten zählen Spielsekunden.
- Ziel der Maus ist ein Punkt in Welteinheiten oder ein Objekt (Id oder Name). Bei einem Klick auf ein Objekt meldet die Antwort, ob er getroffen hat.
- Die Antwort nennt die verbrauchte Spielzeit, die noch gehaltenen Tasten, die Maus und neue Konsolenzeilen.
- `get_runtime` liest das laufende Spiel: Objekte mit Id, Typ und Position, die eigenen Variablen der Behaviors, die Variables-Assets, Kamera, Tasten, Maus und Konsole. Benannte Objekte kommen mit allen Properties.
- `get_view` und `play` melden, wenn die Szene keine aktive Kamera hat. Das war Fund 2 aus dem ersten Agententest (4724).
**Abweichung vom Plan:** Statt `press_keys` und `pointer` gibt es ein Werkzeug `play_input`. So kann eine Schrittfolge Tasten und Maus mischen, z. B. Shift halten und dabei klicken.
**Grenzen**
- Der Editor-Tab muss im Vordergrund sein. Ein Hintergrund-Tab bekommt keine Frames, das Werkzeug sagt das sofort. Steht die Spielzeit 25 s still, bricht es ab, nennt den Schritt und lässt alle gehaltenen Tasten los.
- Die echte Maus des Users über dem Game-Tab verschiebt die Spiel-Maus weiterhin. Steht im Wiki.
**Live am Testprojekt gefunden und behoben**
- Ein Klick über den Namen des Objekts meldete `hit: false`, die Trefferprüfung suchte nur nach der Id.
- `get_runtime` zeigte die eingebauten Schalter eines Behaviors (`enabled`, `runInEditor` …) als Variablen.
Danach live: 0,5 s →, 0,5 s ↑, 1 s ←, 0,25 s ↓ bei 200 px/s, der Player steht bei x −100, y −50, genau wie gerechnet. Der Klick über den Namen trifft.
**Tests**
| Prüfung | Ergebnis |
|---|---|
| `agent-play` (neu), `agent-edit`, `agent-view`, `relay` | grün |
| Gegenproben | 5 Verbiegungen, alle rot |
| e2e 71 (atx) | 21/21. Der Agent hält ← 0,5 s (x −120 → −270) und klickt das Objekt (`hit: true`) |
| Gate (atx) | `CHECK EXIT 0`, 319 Dateien, 4944 Tests |
e2e 71 lief vor den beiden Fixes, die sind durch Unit-Tests, Gate und den Live-Test abgedeckt. Den CI-Lauf zu `1943539` habe ich nicht abgewartet.
Wiki: *MCP*, neuer Abschnitt *Playing the game*.
**Offen:** Etappe 5 (die übrigen Bereiche in den Katalog). #429 bleibt bis dahin offen.
admin
moved this to Next in Development on 2026-10-18 15:58:41 +02:00
Bewusst nicht für den Agenten: Datei-Assets (kein Upload), Einfügen aus der Zwischenablage, interne Hüllen-Commands und Plugins einschalten (würde fremden Code starten).
Gebaut
85 Commands in 5 Bereichen.catalog listet ohne query nur Namen und Beschreibungen, mit query (Bereich oder Command-Namen) die Argumente. Alle Schemas auf einmal wären über die 60 000-Zeichen-Grenze einer Antwort gegangen.
Variablen im Graphen:add_port lässt einen Variables-Node auf eine Variable zeigen. Der Port übernimmt ihre Art, ein falscher Name wird mit der Liste der vorhandenen abgelehnt.
Gruppen und Kommentare (add_group, add_comment) nehmen Nodes statt Koordinaten und rücken nach dem Anordnen nach, im selben Undo-Schritt.
Dazu Ports, Übergänge, Struct-Typen, Objekt-Gruppen, Container, Overrides übernehmen, Collider/Rigidbody/Joint und die Projekt-Einstellungen.
Lesen:list_assets liefert die Projekt-Einstellungen, get_asset den Inhalt platzierter Container, get_graph die deklarierten Ports und die Rahmenfarben.
Platzregel für neue Nodes: Ein neuer Node kommt auf die Höhe seines Ports, an den freien Platz, an dem seine Kabel am wenigsten kreuzen. Eine Quelle kommt links vor ihren Abnehmer. Vorher kamen neue Nodes immer rechts neben den Bestand.
Arrange: Bei gleich vielen Kreuzungen gewinnt die Reihenfolge mit dem Fluss oben.
Anweisungen: Der Agent soll in lint_graph auch die Kreuzungen ansehen und arrange_graph aufrufen, wenn es mehr sind als nötig.
Funde
Ein nachträglich gesetzter Variables-Node landete rechts vom Move (1 rückwärts) und danach über der Spalte (7 statt 4 Kreuzungen). Beides behebt die Platzregel oben. Der zweite Fall kam aus dem Vergleich mit der Anordnung des Users.
Ein Kommentar über einer Gruppe ragte in deren Titelleiste, jetzt hat er Abstand.
Variablen-Commands auf einem Struct-Asset liefen nicht über WithStructTypes, neue Felder kamen bei Variablen dieses Typs nicht an.
query: "variables" traf auch set_variables_scope. Ein Wort, das ein Bereich ist, meint jetzt nur den Bereich.
Live an Project 6
Variable speed = 300 statt der festen 200 im Move: → 0,5 s bringt den Player auf x 150,03 (mit 200 wären es 100).
Variables entfernt und ohne Position neu gesetzt: landet unter Axis input, 4 Kreuzungen (das Minimum), 0 rückwärts. Arrange danach: On update oben, ebenfalls 4.
22/22, neuer Check: Port speed und Gruppe um alle 4 gezeichneten Nodes
Gate (atx)
CHECK EXIT 0, 320 Dateien, 4958 Tests
Den CI-Lauf zu 0d8fd6f habe ich nicht abgewartet.
Offen
Gruppen wachsen nicht mit. Ein neuer Node, dessen Partner in einer Gruppe liegt, landet außerhalb, und Arrange passt eine bestehende Gruppe nicht an. In Project 6 habe ich Gruppe und Kommentar deshalb von Hand neu angelegt.
5b, 5c, 5d. Das Issue bleibt bis zum Ende von Etappe 5 offen.
## Etappe 5a fertig: Graph, Variablen, Szene, Projekt (`0d8fd6f`)
Wiki `55a0ab0` (*MCP*, *Behaviors*).
### Zuschnitt von Etappe 5
Der Agent kannte 23 von rund 135 Commands. Etappe 5 ist in Bereiche geteilt, je ein Commit:
- **5a (dieser Commit):** Graph-Rest, Variablen, Szene, Collider, Projekt
- **5b:** Animation, Kurven, Sprite-Frames, Tiles, Tilemaps
- **5c:** Pixel Art, Vector Art
- **5d:** Song, Pattern, Clips, Routing, Composition
Bewusst nicht für den Agenten: Datei-Assets (kein Upload), Einfügen aus der Zwischenablage, interne Hüllen-Commands und Plugins einschalten (würde fremden Code starten).
### Gebaut
- **85 Commands in 5 Bereichen.** `catalog` listet ohne `query` nur Namen und Beschreibungen, mit `query` (Bereich oder Command-Namen) die Argumente. Alle Schemas auf einmal wären über die 60 000-Zeichen-Grenze einer Antwort gegangen.
- **Variablen im Graphen:** `add_port` lässt einen *Variables*-Node auf eine Variable zeigen. Der Port übernimmt ihre Art, ein falscher Name wird mit der Liste der vorhandenen abgelehnt.
- **Gruppen und Kommentare** (`add_group`, `add_comment`) nehmen Nodes statt Koordinaten und rücken nach dem Anordnen nach, im selben Undo-Schritt.
- Dazu Ports, Übergänge, Struct-Typen, Objekt-Gruppen, Container, Overrides übernehmen, Collider/Rigidbody/Joint und die Projekt-Einstellungen.
- **Lesen:** `list_assets` liefert die Projekt-Einstellungen, `get_asset` den Inhalt platzierter Container, `get_graph` die deklarierten Ports und die Rahmenfarben.
- **Platzregel für neue Nodes:** Ein neuer Node kommt auf die Höhe seines Ports, an den freien Platz, an dem seine Kabel am wenigsten kreuzen. Eine Quelle kommt links vor ihren Abnehmer. Vorher kamen neue Nodes immer rechts neben den Bestand.
- ***Arrange*:** Bei gleich vielen Kreuzungen gewinnt die Reihenfolge mit dem Fluss oben.
- **Anweisungen:** Der Agent soll in `lint_graph` auch die Kreuzungen ansehen und `arrange_graph` aufrufen, wenn es mehr sind als nötig.
### Funde
- Ein nachträglich gesetzter *Variables*-Node landete rechts vom Move (1 rückwärts) und danach über der Spalte (7 statt 4 Kreuzungen). Beides behebt die Platzregel oben. Der zweite Fall kam aus dem Vergleich mit der Anordnung des Users.
- Ein Kommentar über einer Gruppe ragte in deren Titelleiste, jetzt hat er Abstand.
- Variablen-Commands auf einem *Struct*-Asset liefen nicht über `WithStructTypes`, neue Felder kamen bei Variablen dieses Typs nicht an.
- `query: "variables"` traf auch `set_variables_scope`. Ein Wort, das ein Bereich ist, meint jetzt nur den Bereich.
### Live an Project 6
- Variable `speed` = 300 statt der festen 200 im Move: → 0,5 s bringt den Player auf x 150,03 (mit 200 wären es 100).
- *Variables* entfernt und ohne Position neu gesetzt: landet unter *Axis input*, 4 Kreuzungen (das Minimum), 0 rückwärts. *Arrange* danach: *On update* oben, ebenfalls 4.
### Tests
| Prüfung | Ergebnis |
|---|---|
| `agent-catalog` (neu, 10), `agent-edit`, `graph-arrange` (3 neu), `relay` | grün |
| Gegenproben | 11 Verbiegungen, alle rot |
| e2e 71 (atx) | 22/22, neuer Check: Port `speed` und Gruppe um alle 4 gezeichneten Nodes |
| Gate (atx) | `CHECK EXIT 0`, 320 Dateien, 4958 Tests |
Den CI-Lauf zu `0d8fd6f` habe ich nicht abgewartet.
### Offen
- **Gruppen wachsen nicht mit.** Ein neuer Node, dessen Partner in einer Gruppe liegt, landet außerhalb, und *Arrange* passt eine bestehende Gruppe nicht an. In Project 6 habe ich Gruppe und Kommentar deshalb von Hand neu angelegt.
- 5b, 5c, 5d. Das Issue bleibt bis zum Ende von Etappe 5 offen.
Wiki 180cc43 (Seite MCP: Bereichstabelle, Hinweise, Tests).
Gebaut: 3 neue Bereiche mit 30 Commands, insgesamt jetzt 115.
Bereich
Inhalt
animation (12)
Wurzel, Zeilen anlegen, umhängen und relativ machen, Keys setzen, verschieben, kopieren und löschen, Easing, Frames einfügen oder entfernen, Kurvenpunkte
textures (8)
Frames anlegen, ändern und löschen, Raster schneiden, Nine-Slice, Sortierlinie, Kollisionsumriss
tiles (10)
Bilder eines Tiles, Tilemaps malen, Ebenen (anlegen, kopieren, verschieben, ändern), Rand eines platzierten Tilemaps
get_asset nennt bei einer Animation die Ziele mit ihren animierbaren Properties. Tilemaps bis 400 Zellen liefern die Zellen selbst, größere nur die Anzahl.
Nach so einem Aufruf öffnet der Editor den Tab des Assets. Bei einer Frame-Bearbeitung ist der Frame dort ausgewählt.
Malen: Rechtecke zuerst, dann einzelne Zellen. Abgelehnt werden Zellen außerhalb des Rasters, Ids, die kein Tile sind, und mehr als 20 000 Zellen pro Schritt.
Bewusst nicht für den Agenten:Generate collision (liest die Pixel der Textur) und das Einfügen von Keys (geht über die Zwischenablage).
Beim Testen gefunden und behoben:
Nine-Slice ohne fill behält jetzt die bisherige Füllung. Der Standard im Modell ist repeat, nicht stretch, wie ich zuerst beschrieben hatte.
Beim Malen haben die Rechtecke die einzelnen Zellen überschrieben, die Reihenfolge war andersherum als beschrieben.
Tests:
agent-art (neu, 11) und die übrigen Agent-Tests: 64/64. 5 Gegenproben, alle rot.
e2e 71 (atx): 23/23. Neuer Check: Die Animation des Agenten geht in ihrem Tab auf, get_asset nennt die Ziele.
Live an einem Testprojekt: Animation Spin (0 → 360° in 30 Frames, Schleife) auf dem Player. Im Spiel stimmten die Werte auf 0,01 Frames genau mit 12° pro Frame. Danach per Undo zurückgenommen.
CI zu 0d8fd6f: Suite 728 war mit 2 Video-Checks (e2e 67, 68k) rot. Ursache war mein eigenes Gate, das auf melektaus-atx zeitgleich mit der Suite lief. Mit dem Code hat das nichts zu tun. Eigene Läufe auf atx starte ich nicht mehr, solange dort eine Suite läuft.
Offen: 5c (Pixel Art, Vector Art), 5d (Song, Pattern, Clips, Routing, Composition). Gruppen wachsen beim Neusetzen eines Nodes und bei Arrange weiterhin nicht mit.
## Etappe 5b fertig: Animation, Frames, Tiles, Tilemaps (`d01e2b8`)
Wiki `180cc43` (Seite *MCP*: Bereichstabelle, Hinweise, Tests).
**Gebaut:** 3 neue Bereiche mit 30 Commands, insgesamt jetzt 115.
| Bereich | Inhalt |
|---|---|
| `animation` (12) | Wurzel, Zeilen anlegen, umhängen und relativ machen, Keys setzen, verschieben, kopieren und löschen, Easing, Frames einfügen oder entfernen, Kurvenpunkte |
| `textures` (8) | Frames anlegen, ändern und löschen, Raster schneiden, Nine-Slice, Sortierlinie, Kollisionsumriss |
| `tiles` (10) | Bilder eines Tiles, Tilemaps malen, Ebenen (anlegen, kopieren, verschieben, ändern), Rand eines platzierten Tilemaps |
- `get_asset` nennt bei einer Animation die Ziele mit ihren animierbaren Properties. Tilemaps bis 400 Zellen liefern die Zellen selbst, größere nur die Anzahl.
- Nach so einem Aufruf öffnet der Editor den Tab des Assets. Bei einer Frame-Bearbeitung ist der Frame dort ausgewählt.
- Malen: Rechtecke zuerst, dann einzelne Zellen. Abgelehnt werden Zellen außerhalb des Rasters, Ids, die kein Tile sind, und mehr als 20 000 Zellen pro Schritt.
- **Bewusst nicht für den Agenten:** *Generate collision* (liest die Pixel der Textur) und das Einfügen von Keys (geht über die Zwischenablage).
**Beim Testen gefunden und behoben:**
- Nine-Slice ohne `fill` behält jetzt die bisherige Füllung. Der Standard im Modell ist `repeat`, nicht `stretch`, wie ich zuerst beschrieben hatte.
- Beim Malen haben die Rechtecke die einzelnen Zellen überschrieben, die Reihenfolge war andersherum als beschrieben.
**Tests:**
- `agent-art` (neu, 11) und die übrigen Agent-Tests: 64/64. 5 Gegenproben, alle rot.
- e2e 71 (atx): 23/23. Neuer Check: Die Animation des Agenten geht in ihrem Tab auf, `get_asset` nennt die Ziele.
- Gate (atx): `CHECK EXIT 0`, 321 Dateien, 4969 Tests.
- Live an einem Testprojekt: Animation *Spin* (0 → 360° in 30 Frames, Schleife) auf dem Player. Im Spiel stimmten die Werte auf 0,01 Frames genau mit 12° pro Frame. Danach per Undo zurückgenommen.
**CI zu `0d8fd6f`:** Suite 728 war mit 2 Video-Checks (e2e 67, 68k) rot. Ursache war mein eigenes Gate, das auf `melektaus-atx` zeitgleich mit der Suite lief. Mit dem Code hat das nichts zu tun. Eigene Läufe auf atx starte ich nicht mehr, solange dort eine Suite läuft.
**Offen:** 5c (Pixel Art, Vector Art), 5d (Song, Pattern, Clips, Routing, Composition). Gruppen wachsen beim Neusetzen eines Nodes und bei *Arrange* weiterhin nicht mit.
Etappe 5c fertig: Pixel Art, Paletten, Vector Art (0684e76)
Wiki c611f34, Seite MCP.
Zwei neue Bereiche mit 29 Commands, der Katalog hat jetzt 144.
Bereich
Inhalt
pixelart (13)
Malen, Ebenen (anlegen, kopieren, entfernen, ändern, verschieben, nach unten zusammenführen), Frames (anlegen auch als Kopie, entfernen, verschieben), Leinwandgröße mit Anker, Palettenfarben setzen und entfernen
vectorart (16)
Formen aus Ringen oder als rect/ellipse, Umriss, Stil (Füllung, Deckkraft, Verlauf oder Bildfüllung, Kontur), verschieben/skalieren/drehen/spiegeln, kopieren, entfernen, kombinieren, umbenennen, Reihenfolge, in Gruppen verschieben, gruppieren, Ebenen
paint_pixels bearbeitet eine Ebene auf einem Frame. Die Schritte laufen der Reihe nach: rows (ein kleines Bild als Zeichen, ein Leerzeichen lässt das Pixel stehen), pixels, line, rect, ellipse, fill, clear. Abgelehnt werden ein Index, den die Palette nicht hat, ein Pixel außerhalb der Leinwand und ein unbekanntes Zeichen.
Lesen:get_asset liefert bei Pixel Art die Palette als colors. Bis 16 384 Pixel über alle Ebenen und Frames kommt jede Ebene als Zeilen, darüber nur die Zahl der gemalten Pixel. Farben kommen als #rrggbb.
Gleicher Code wie im Panel: Zusammenführen, Größe ändern und Farbe entfernen sind jetzt Builder in pixelActions.ts.
Live in Project 6: ein 8×8-Slime und ein kopierter zweiter Frame (Blinzeln über rect, line, pixels, fill) kamen über get_asset genau so zurück. Ein um 45° gedrehtes Quadrat mit Kontur und eine Kreisscheibe mit radialem Verlauf, gruppiert: Die Ecken liegen bei 7,431 und 120,569 (64 ± 40·√2). Danach per Undo zurückgenommen.
Tests:
agent-drawing (neu, 9) und die übrigen Agent-, Pixel- und Relay-Tests: 133/133.
7 Gegenproben, alle rot. Bei der Ellipse hätten die bestehenden Tests eine falsche Henkellänge nicht bemerkt, jetzt prüft der Test jeden Punkt der Kurve.
e2e 71 (atx): 24/24. Neuer Check: Die Pixel Art des Agenten geht im Tab auf, wird als Zeilen zurückgelesen, und ihre Cel liegt nach dem Speichern auf dem Server.
Gate (atx): CHECK EXIT 0, 322 Dateien, 4978 Tests. Beide atx-Läufe erst nach dem Ende von Suite 729.
## Etappe 5c fertig: Pixel Art, Paletten, Vector Art (`0684e76`)
Wiki `c611f34`, Seite *MCP*.
Zwei neue Bereiche mit 29 Commands, der Katalog hat jetzt 144.
| Bereich | Inhalt |
|---|---|
| **pixelart** (13) | Malen, Ebenen (anlegen, kopieren, entfernen, ändern, verschieben, nach unten zusammenführen), Frames (anlegen auch als Kopie, entfernen, verschieben), Leinwandgröße mit Anker, Palettenfarben setzen und entfernen |
| **vectorart** (16) | Formen aus Ringen oder als `rect`/`ellipse`, Umriss, Stil (Füllung, Deckkraft, Verlauf oder Bildfüllung, Kontur), verschieben/skalieren/drehen/spiegeln, kopieren, entfernen, kombinieren, umbenennen, Reihenfolge, in Gruppen verschieben, gruppieren, Ebenen |
- **`paint_pixels`** bearbeitet eine Ebene auf einem Frame. Die Schritte laufen der Reihe nach: `rows` (ein kleines Bild als Zeichen, ein Leerzeichen lässt das Pixel stehen), `pixels`, `line`, `rect`, `ellipse`, `fill`, `clear`. Abgelehnt werden ein Index, den die Palette nicht hat, ein Pixel außerhalb der Leinwand und ein unbekanntes Zeichen.
- **Lesen:** `get_asset` liefert bei Pixel Art die Palette als `colors`. Bis 16 384 Pixel über alle Ebenen und Frames kommt jede Ebene als Zeilen, darüber nur die Zahl der gemalten Pixel. Farben kommen als `#rrggbb`.
- **Gleicher Code wie im Panel:** Zusammenführen, Größe ändern und Farbe entfernen sind jetzt Builder in `pixelActions.ts`.
**Live in Project 6:** ein 8×8-Slime und ein kopierter zweiter Frame (Blinzeln über `rect`, `line`, `pixels`, `fill`) kamen über `get_asset` genau so zurück. Ein um 45° gedrehtes Quadrat mit Kontur und eine Kreisscheibe mit radialem Verlauf, gruppiert: Die Ecken liegen bei 7,431 und 120,569 (64 ± 40·√2). Danach per Undo zurückgenommen.
**Tests:**
- `agent-drawing` (neu, 9) und die übrigen Agent-, Pixel- und Relay-Tests: 133/133.
- 7 Gegenproben, alle rot. Bei der Ellipse hätten die bestehenden Tests eine falsche Henkellänge nicht bemerkt, jetzt prüft der Test jeden Punkt der Kurve.
- e2e 71 (atx): 24/24. Neuer Check: Die Pixel Art des Agenten geht im Tab auf, wird als Zeilen zurückgelesen, und ihre Cel liegt nach dem Speichern auf dem Server.
- Gate (atx): `CHECK EXIT 0`, 322 Dateien, 4978 Tests. Beide atx-Läufe erst nach dem Ende von Suite 729.
**Offen:** 5d (Song, Pattern, Clips, Routing, Composition). Das Issue bleibt offen.
Zwei neue Bereiche mit 24 Commands, der Katalog hat jetzt 168.
Bereich
Inhalt
music (15)
Noten hinzufügen, ändern und entfernen, Loop für Pattern und Song, Song-Spuren (anlegen, ändern, verschieben, entfernen), Song-Items, Sends, Clips von Sounds und Videos
composition (9)
Spuren, Items (Objekt, Bild oder Audio), Ändern samt Blenden, Lautstärke und Bus, Entfernen, Animations-Clips
Noten: Die Tonhöhe geht als MIDI-Zahl oder als Name wie C4 oder F#3. get_asset liest die Noten mit Namen zurück und nennt die Länge des Patterns in Ticks. Eine Note hinter dem Ende des Patterns wird abgelehnt.
Routing: Song- und Master-Routing bleiben Graphen. Verbunden wird mit connect, set_send setzt Pegel und Abgriff. get_graph zeigt jetzt bei jeder Kante ihren Send.
Längen folgen denselben Regeln wie beim Ziehen im Tab. Wie lang ein Sound ist, weiß der Editor erst nach dem Laden. get_asset zeigt das als seconds, fehlt es, verlangt der Agent eine Länge.
Composition: Ein verschobenes Item nimmt seine Clips mit. Ein Clip, der dann über einem anderen läge, wird abgelehnt. Blenden gehen nur bei Items mit Ton.
Live in Project 6: Pattern Melody (C4, E4, G4, C5, ein Takt), Song Theme spielt es zweimal, dazu Bass eine Oktave tiefer. Bass schickt mit −6 dB vor dem FX zusätzlich in Track 1, get_graph las das genau so zurück. Danach meldete lint_graph ein Kabel rückwärts (beide Spuren in einer Spalte), nach arrange_graph 0. Composition Intro: Das Pattern-Item ist 120 Frames lang (1 Takt bei 120 BPM = 2 s bei 60 fps), eine Blende am Player wurde richtig abgelehnt. Danach per Undo zurückgenommen.
Tests:
agent-music (neu, 9) und die übrigen Agent- und Relay-Tests: 109/109.
9 Gegenproben, alle rot, jeweils im passenden Test.
e2e 71 (atx): 25/25. Neuer Check: Noten werden mit Namen zurückgelesen, eine Composition mit Pattern und Sprite geht in ihrem Tab auf.
Gate (atx): CHECK EXIT 0, 323 Dateien, 4987 Tests. Beide atx-Läufe erst nach dem Ende der CI zu 0684e76.
Abschluss
Damit sind alle Etappen erledigt. Commits zu #429:
Commit
Inhalt
48ec722
Der Agent sieht den offenen Editor über MCP
25af064
Der Agent liest und bearbeitet das offene Projekt
b9d1602
Graph-Nodes anordnen, für den Agenten und per Button
0dd671e
Jeder verbundene Agent zählt im Badge nur einmal
732989a
Fit passt wieder in den Kopf des Song-Tabs
97e0d93
Der Editor folgt den Änderungen des Agenten
1943539
Der Agent spielt das Spiel und liest seinen Zustand
0d8fd6f
5a: Graph, Variablen, Szene, Collider, Projekt
d01e2b8
5b: Animation, Kurven, Frames, Tiles, Tilemaps
0684e76
5c: Pixel Art, Paletten, Vector Art
10f5e3b
5d: Pattern, Song, Sends, Clips, Composition
Der Katalog hat 168 Commands in 12 Bereichen. Bewusst nicht für den Agenten: Datei-Assets (kein Upload), alles über die Zwischenablage, interne Hüllen-Commands, Plugins einschalten (würde fremden Code starten) und Generate collision (liest die Pixel der Textur).
Bekannte Lücke, nicht Teil dieses Issues: Gruppen wachsen nicht mit, wenn ein neuer Node in sie gesetzt wird oder Arrange die Nodes neu ordnet (siehe 4738). Das Issue wird geschlossen.
## Etappe 5d fertig: Pattern, Song, Sends, Clips, Composition (`10f5e3b`)
Wiki `9154ac8`, Seite *MCP*.
Zwei neue Bereiche mit 24 Commands, der Katalog hat jetzt 168.
| Bereich | Inhalt |
|---|---|
| **music** (15) | Noten hinzufügen, ändern und entfernen, Loop für Pattern und Song, Song-Spuren (anlegen, ändern, verschieben, entfernen), Song-Items, Sends, Clips von Sounds und Videos |
| **composition** (9) | Spuren, Items (Objekt, Bild oder Audio), Ändern samt Blenden, Lautstärke und Bus, Entfernen, Animations-Clips |
- **Noten:** Die Tonhöhe geht als MIDI-Zahl oder als Name wie `C4` oder `F#3`. `get_asset` liest die Noten mit Namen zurück und nennt die Länge des Patterns in Ticks. Eine Note hinter dem Ende des Patterns wird abgelehnt.
- **Routing:** Song- und Master-Routing bleiben Graphen. Verbunden wird mit `connect`, `set_send` setzt Pegel und Abgriff. `get_graph` zeigt jetzt bei jeder Kante ihren Send.
- **Längen** folgen denselben Regeln wie beim Ziehen im Tab. Wie lang ein Sound ist, weiß der Editor erst nach dem Laden. `get_asset` zeigt das als `seconds`, fehlt es, verlangt der Agent eine Länge.
- **Composition:** Ein verschobenes Item nimmt seine Clips mit. Ein Clip, der dann über einem anderen läge, wird abgelehnt. Blenden gehen nur bei Items mit Ton.
**Live in Project 6:** Pattern *Melody* (C4, E4, G4, C5, ein Takt), Song *Theme* spielt es zweimal, dazu *Bass* eine Oktave tiefer. *Bass* schickt mit −6 dB vor dem FX zusätzlich in *Track 1*, `get_graph` las das genau so zurück. Danach meldete `lint_graph` ein Kabel rückwärts (beide Spuren in einer Spalte), nach `arrange_graph` 0. Composition *Intro*: Das Pattern-Item ist 120 Frames lang (1 Takt bei 120 BPM = 2 s bei 60 fps), eine Blende am Player wurde richtig abgelehnt. Danach per Undo zurückgenommen.
**Tests:**
- `agent-music` (neu, 9) und die übrigen Agent- und Relay-Tests: 109/109.
- 9 Gegenproben, alle rot, jeweils im passenden Test.
- e2e 71 (atx): 25/25. Neuer Check: Noten werden mit Namen zurückgelesen, eine Composition mit Pattern und Sprite geht in ihrem Tab auf.
- Gate (atx): `CHECK EXIT 0`, 323 Dateien, 4987 Tests. Beide atx-Läufe erst nach dem Ende der CI zu `0684e76`.
## Abschluss
Damit sind alle Etappen erledigt. Commits zu #429:
| Commit | Inhalt |
|---|---|
| `48ec722` | Der Agent sieht den offenen Editor über MCP |
| `25af064` | Der Agent liest und bearbeitet das offene Projekt |
| `b9d1602` | Graph-Nodes anordnen, für den Agenten und per Button |
| `0dd671e` | Jeder verbundene Agent zählt im Badge nur einmal |
| `732989a` | *Fit* passt wieder in den Kopf des Song-Tabs |
| `97e0d93` | Der Editor folgt den Änderungen des Agenten |
| `1943539` | Der Agent spielt das Spiel und liest seinen Zustand |
| `0d8fd6f` | 5a: Graph, Variablen, Szene, Collider, Projekt |
| `d01e2b8` | 5b: Animation, Kurven, Frames, Tiles, Tilemaps |
| `0684e76` | 5c: Pixel Art, Paletten, Vector Art |
| `10f5e3b` | 5d: Pattern, Song, Sends, Clips, Composition |
Der Katalog hat 168 Commands in 12 Bereichen. Bewusst nicht für den Agenten: Datei-Assets (kein Upload), alles über die Zwischenablage, interne Hüllen-Commands, Plugins einschalten (würde fremden Code starten) und *Generate collision* (liest die Pixel der Textur).
**Bekannte Lücke, nicht Teil dieses Issues:** Gruppen wachsen nicht mit, wenn ein neuer Node in sie gesetzt wird oder *Arrange* die Nodes neu ordnet (siehe 4738). Das Issue wird geschlossen.
Commit 19902a9, Wiki 54b0773 (MCP, Behaviors). Das Issue bleibt geschlossen.
Der Live-Test mit Pattern, Song und Composition in Project 6 hat vier Lücken gezeigt. Die Musik blieb stumm, und der Agent hat es nicht bemerkt.
Fund
jetzt
Pattern und Song-Items ohne Instrument spielen nichts
get_asset meldet das unter silent, mit Hinweis, wie man es behebt
Ein neuer Notes-Node nimmt nur C4 bis B4 an. Der Bass (transponiert um -12) und das C5 der Melodie waren stumm
silent nennt auch Noten, die das Instrument nicht spielt, im Song nach dem Transponieren, und den Bereich, den es spielt. Die Regel (soundingNotes) teilen sich Pattern-Tab und Agent
Output blieb links von den neuen Geräten stehen, ein Kabel lief rückwärts
Ist zwischen zwei Nodes kein Platz, rückt alles ab dem gespeisten Node nach rechts. Gilt auch für Arrange mit Auswahl
Gruppen wuchsen nicht mit, Kommentare konnten unter Nodes verschwinden
Neue Nodes kommen in die Gruppe ihres Partners, die Gruppe wächst mit. Arrange nimmt Gruppen und Kommentare mit (annotationFollow.ts). add_comment/fit_group weichen Nodes aus, lint_graph zählt coveredNotes
Live geprüft: Ein Log an Move landete in der Gruppe, die Gruppe wuchs von 464 auf 712. Ein Filter vor Output von Lead ergab bei lint_graph überall 0. Melody ohne Instrument zeigte silent. Nach dem Weiten der Notenbereiche (Bass C1 bis C5, Lead C3 bis C7) steht bei Theme, Intro und Melody nichts mehr unter silent.
Tests:graph-follow (neu, 12), agent-edit, agent-music (11) und die übrigen Agent-, Graph-, Pattern- und Relay-Tests grün. 10 Gegenproben, alle rot. e2e 71: 25/25. Gate: CHECK EXIT 0, 324 Dateien, 5002 Tests.
## Nachtrag: Funde aus dem Live-Test mit Musik
Commit `19902a9`, Wiki `54b0773` (*MCP*, *Behaviors*). Das Issue bleibt geschlossen.
Der Live-Test mit Pattern, Song und Composition in *Project 6* hat vier Lücken gezeigt. Die Musik blieb stumm, und der Agent hat es nicht bemerkt.
| Fund | jetzt |
|---|---|
| Pattern und Song-Items ohne Instrument spielen nichts | `get_asset` meldet das unter `silent`, mit Hinweis, wie man es behebt |
| Ein neuer *Notes*-Node nimmt nur C4 bis B4 an. Der Bass (transponiert um -12) und das C5 der Melodie waren stumm | `silent` nennt auch Noten, die das Instrument nicht spielt, im Song nach dem Transponieren, und den Bereich, den es spielt. Die Regel (`soundingNotes`) teilen sich Pattern-Tab und Agent |
| *Output* blieb links von den neuen Geräten stehen, ein Kabel lief rückwärts | Ist zwischen zwei Nodes kein Platz, rückt alles ab dem gespeisten Node nach rechts. Gilt auch für *Arrange* mit Auswahl |
| Gruppen wuchsen nicht mit, Kommentare konnten unter Nodes verschwinden | Neue Nodes kommen in die Gruppe ihres Partners, die Gruppe wächst mit. *Arrange* nimmt Gruppen und Kommentare mit (`annotationFollow.ts`). `add_comment`/`fit_group` weichen Nodes aus, `lint_graph` zählt `coveredNotes` |
**Live geprüft:** Ein *Log* an *Move* landete in der Gruppe, die Gruppe wuchs von 464 auf 712. Ein Filter vor *Output* von *Lead* ergab bei `lint_graph` überall 0. *Melody* ohne Instrument zeigte `silent`. Nach dem Weiten der Notenbereiche (Bass C1 bis C5, Lead C3 bis C7) steht bei *Theme*, *Intro* und *Melody* nichts mehr unter `silent`.
**Tests:** `graph-follow` (neu, 12), `agent-edit`, `agent-music` (11) und die übrigen Agent-, Graph-, Pattern- und Relay-Tests grün. 10 Gegenproben, alle rot. e2e 71: 25/25. Gate: `CHECK EXIT 0`, 324 Dateien, 5002 Tests.
admin
moved this to Done in Development on 2026-10-18 18:32:41 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Anlass: Ein KI-Agent (z. B. Claude Code) soll den Editor über einen MCP-Server bedienen können. Er arbeitet dabei im offenen Editor mit, sodass der User live sieht, was passiert.
Was der MCP können soll (Randnotiz des Users)
Stand heute (im Code nachgesehen)
EditorState,src/editor/state.ts:476). Es gibt 113 Command-Klassen.window.__gm(src/editor/debugHook.ts) ist die Brücke der e2e-Tests. Sie findet Widgets über ihren sichtbaren Text und liest den Zustand. Gedacht ist sie für Tests, als stabile API taugt sie nicht.src/editor/plugins/pluginApi.ts) kann bisher nur Assets auflisten, Änderungen melden und Tabs anlegen.GraphAnnotation). Eine automatische Anordnung von Nodes gibt es nicht. Wer einen Node anlegt, gibt seine Position selbst vor.connect-src 'self' data: blob:. Eine Verbindung zum eigenen Host (auchwss:) geht damit, zu anderen Hosts nicht.Grundsatz: der Agent arbeitet im offenen Editor, nicht an der Datei
Würde der MCP die Projektdatei auf dem Server direkt bearbeiten, gäbe es zwei Probleme. Er käme dem Autosave eines offenen Tabs in die Quere, und Punkt 3 wäre gar nicht machbar. Deshalb läuft alles über den offenen Tab:
Verbindung: MCP-Endpunkt auf stein2 (entschieden, Kommentar 4716)
feuerwerk-mcp: ein kleiner Node-Dienst im eigenen Container, gehärtet wiefeuerwerk-video. PHP-FPM kann keine dauerhaften Verbindungen halten, deshalb nicht in der API./mcpdorthin (auf beiden Adressen:feuerwerk.nockal.com/mcpundnockal.com/feuerwerk/mcp). Die Whitelist aus #427 bekommt genau diesen Pfad dazu.connect-src 'self') erlaubt das schon,'self'decktwss:auf demselben Host ab.Sec-WebSocket-Acceptkorrekt, echter Client bekommt die Nachricht), und SSE kommt ungepuffert an (je Event 2–3 ms). Beides auf beiden Adressen.Authentifizierung
Agent → Relay: persönlicher Agent-Token je Konto
sha256des Tokens, Dateien 0640 wie die Sitzungen.claude mcp add --transport http feuerwerk https://feuerwerk.nockal.com/mcp --header "Authorization: Bearer fwa_…"/mcp, nicht für die REST-API.Tab → Relay: die normale Sitzung
Secure-Cookie plus Origin-Prüfung, kein neuer Schlüssel.Gäste (#428): kein Agent. Ohne Konto gibt es keinen Token, und ein anonymer Zugang zum Relay wäre Mehraufwand samt Missbrauchsfläche.
Werkzeuge (Entwurf)
Nicht 113 einzelne Tools, denn so viele Tools verwirren einen Agenten. Besser sind wenige allgemeine Tools und ein Katalog, den er abfragen kann:
get_view: aktiver Tab, offenes Dokument, Auswahl (Objekt, Node, Keyframe …), Kamera und Zoom, Play-Status, offener Dialog.screenshot: das Canvas als PNG, also genau das, was der User sieht.feuerwerk://viewmit Abo. Der Agent wird dann benachrichtigt, wenn der User den Tab oder die Auswahl wechselt.list_assets,get_asset,get_scene,get_graphundcatalog(Node-Typen samt Ports, Property-Typen, Asset-Arten).run_commandmit Name und Argumenten, geprüft gegen ein Schema je Command. Mehrere Commands lassen sich zu einem Undo-Schritt bündeln, damit ein „bau mir ein Jump-Behavior“ auch mit einem einzigen Strg+Z wieder weg ist.press_keysschickt Tasten ins laufende Spiel (drücken, halten, loslassen, mit Dauer),pointerMausbewegung und Klicks in Weltkoordinaten der Spielkamera.get_runtimeliest den Zustand zur Laufzeit: Objekte mit Position, Rotation und Variablen, dazu die Konsole. So prüft der Agent selbst, ob das Gebaute tut, was es soll.Grundlage ist eine Editor-API aus Commands und Abfragen, die MCP und Plugins (#117) gemeinsam nutzen. Das Relay reicht die Tool-Aufrufe nur an den Tab durch, die Werkzeuge selbst leben im Editor.
__gmbleibt für die Tests.Kein Kabelsalat (Punkt 2)
graph/arrange.ts: Der Fluss läuft von links nach rechts (Ereignis → Bedingung → Aktion), die Anordnung ist in Schichten, und Nodes überlappen nie.lint_graphliefert die Zahl der Kantenkreuzungen, die Überlappungen und die längsten Kanten. Damit kann der Agent selbst nachbessern, und die Tests haben eine Zahl.Sicherheit
Etappen
feuerwerk-mcp, nginx-Pfad/mcp, Agent-Tokens samt Verwaltung, Tab-Verbindung mit Agent on, dazuget_view,screenshot, View-Abo.run_commandüber die Commands, mit Undo-Bündelung.arrangeundlint_graph, dazu der Knopf Arrange.press_keys,pointer,get_runtime. Dazu ein Hinweis, wenn der Startszene eine Kamera fehlt.Tests
arrange(keine Überlappung, Kreuzungen auf Beispielgraphen unter einer festen Grenze, Handplatziertes bleibt stehen), Schema-Prüfung vonrun_command, Undo-Bündelung.get_runtimeund sieht sie wandern. Ein Klick überpointerlöst ein Klick-Ereignis am getroffenen Objekt aus.get_viewmuss nach einem Tabwechsel stimmen, und ein Strg+Z nimmt den Agenten-Schritt komplett zurück.Fertig, wenn
get_viewund das View-Abo spiegeln Tab und Auswahl des Users.Entscheidungen (Kommentar 4716 und folgende)
/mcp, normale Sitzung für den Tab, kein OAuth.Danke, damit ist der Plan komplett. Den Issue-Text oben habe ich auf B umgestellt (Abschnitte Verbindung, Authentifizierung, Etappen, Tests, Fertig, wenn, Entscheidungen).
Entschieden
feuerwerk-mcpauf stein2, nginx leitet/mcpdorthin./mcp, im Kontomenü unter Agent tokens…. Er wird nur einmal angezeigt, gespeichert wird nursha256. Er gilt nicht für die REST-API, und Fehlversuche zählen in die Login-Bremse aus #427.Gemessen am 2026-10-17 (nach der Umstellung am Reverse Proxy)
Ich habe kurz einen Wegwerf-Endpunkt hinter nginx gestellt (
location = /feuerwerk/mcpauf einen Node-Container) und danach wieder entfernt. nginx.conf ist wieder byteweise wie vorher,/mcpliefert wieder 404.curl --http1.1)Sec-WebSocket-AcceptkorrektSec-WebSocket-AcceptkorrektWebSocket)Damit passt der Transport für beide Richtungen: Streamable HTTP mit SSE für den Agenten, WebSocket für den Tab.
Hinweis für Etappe 1:
X-Forwarded-Forkommt am Relay an. Das Relay darf dem Header aber nur vertrauen, wenn die Verbindung von der Brandmauer kommt, genau wie bei der Login-Bremse in #427.Etappe 1 fertig: Relay und Kontext (
48ec722, Wiki5bb0780)Gebaut
claude mcp add …-Zeile, widerrufen. Gespeichert wird nursha256(api/lib/AgentTokens.php). Der Token öffnet nur/mcp. Falsche Tokens zählen in die Login-Bremse. Passwortwechsel, Umbenennen und Löschen des Kontos beenden seine Tokens.tools/mcp/: Node ohne Pakete, auch der WebSocket-Server. Containerfeuerwerk-mcpauf172.16.0.1:8091, nginx leitet/feuerwerk/mcpdorthin. Token und Tab-Ticket prüft weiter die PHP-API, über zwei Routen, die nur mit dem Relay-Schlüssel antworten.get_view(Projekt, Tab, Dokument, Auswahl mit Namen, Kamera, Play-Status, offener Dialog),screenshot, Resourcefeuerwerk://viewmit Abo. Weil Claude Code Abos nicht verlässlich auswertet, hängt das Relay an die nächste Antwort eine Zeile, wenn sich die Ansicht geändert hat.php -S(tools/ci/serve.sh), e2e 71 fährt den ganzen Weg im Browser.Tests
get_view, Werkzeuge,socketUrlget_viewkorrekt beantwortet/mcpSechs Gegenproben (Besitzer beim Widerruf, Relay-Schlüssel, Origin, Sitzung je Konto, Namens-Rückfall, Agentenzählung): jede wird ohne ihre Prüfung rot. Am 18.10. habe ich mich außerdem selbst über Claude Code mit dem echten Tab verbunden,
get_viewundscreenshotpassten zueinander.Funde
nockal.comhatUseYarp: false. Dort kommt der Handshake durch, aber keine Nachricht vom Browser. Der Agent-Tab geht deshalb nur auffeuerwerk.nockal.com, so steht es im Wiki.titleleer. Das ziehe ich in Etappe 2 nach.Weiter mit Etappe 2: Lesen und
run_commandmit Undo-Bündelung.Etappe 2 fertig: Lesen und Ändern über
run_commandsCommit
25af0642, Wikib8f8921(Seite MCP, Abschnitt Changing the project, dazu Architecture). Gebaut und live, das Relay auf stein2 ist neu gestartet.Was der Agent jetzt kann
list_assets,get_asset(Eigenschaften mit ihren Feldern, Objekte einer Szene mit Namen),get_graph(Nodes mit ihren aktuellen Ports, Kanten, Gruppen) undcatalog(Commands mit Argumenten, Nodes eines Graphen aus derselben Palette wie im Editor, Asset-Typen, Variablenarten).run_commandsführt alle Schritte eines Aufrufs als einen Undo-Schritt aus („Agent: …“ im Edit-Verlauf). Scheitert ein Schritt, wird alles davor zurückgerollt, und die Antwort nennt Schritt und Grund, z. B.Step 8 (connect): Cannot connect number to exec."as": "walk"gibt späteren Schritten seine Id als"$walk". So legt ein Aufruf ein Behavior an und befüllt es gleich.open,select,play(play/pause/resume/stop),undo/redo.wait, das ihm dafür 2 Minuten statt 30 s gibt.tools.json, der Editor prüft jeden Aufruf dagegen (argCheck.ts).get_viewjetzt seine ersten Einträge statt eines leeren Titels.Tests
CHECK EXIT 0, 317 Dateien, 4903 Testsagent-edit/agent-viewwaitwaitignoriert.Page.navigate, weil derbeforeunload-Schutz bei ungespeichertem Projekt die Seite festhielt und den eigentlichen Fehler überdeckte. Das Modul meldet jetzt zuerst den Fehler und wartet vor dem Navigieren aufs Speichern.Offen
arrange) undlint_graphsind Etappe 3.25af0642ist zum Zeitpunkt dieses Kommentars noch nicht gelesen.Echter Agententest zu Etappe 2
Claude Code hat über den MCP in einem leeren Projekt ein Objekt gebaut, das mit den Pfeiltasten läuft. Der User hat es im Spiel ausprobiert: funktioniert.
run_commands-Aufruf mit 21 Schritten: 4× On key held → je ein Move (±200 px/s,dtvom Ereignis),objectvon einem gemeinsamen Owner. Dazu eine Kamera und das Aufräumen des Graphen.catalogund die$name-Verweise haben auf Anhieb gepasst. Kein Schritt ist gescheitert.openund die Meldung zur geänderten Ansicht funktionieren. Der offene Punkt aus Etappe 1 ist damit bestätigt.Funde
move_nodegekostet, die Node-Höhen musste der Agent raten. Das ist Etappe 3.catalognoch die Anweisungen des Relays erwähnen, dass eine Szene eine braucht. Aufgefallen ist es erst am Screenshot („No active camera“). Kommt als Hinweis in Etappe 4.Neu im Plan: Play-Tests (Wunsch des Users)
Der Agent soll Tasten und Maus im laufenden Spiel simulieren können, damit er Play-Tests selbst fahren kann. Der Issue-Text hat dafür eine eigene Etappe 4 bekommen, die bisherige Etappe 4 heißt jetzt 5:
press_keys: Tasten drücken, halten, loslassen, mit Dauer.pointer: Mausbewegung und Klicks in Weltkoordinaten der Spielkamera.get_runtime: Objekte mit Position, Rotation und Variablen, dazu die Konsole.Tests und Fertig, wenn sind im Issue-Text nachgezogen. Weiter geht es jetzt mit Etappe 3 (
arrange,lint_graph, Knopf Arrange).Etappe 3 fertig: Anordnen und
lint_graphCommits
b9d1602b(Etappe 3) und0dd671ea(Zählung im Badge), Wiki9873ee6(MCP, Behaviors).Gebaut
x/yordnet der Editor am Ende desrun_commands-Aufrufs an, im selben Undo-Schritt. Nodes, die schon da waren, bleiben stehen.src/editor/graph/arrange.ts(reine Funktion): Fluss in Spalten von links nach rechts, Owner/Get direkt vor dem ersten Node, den er speist, je Spalte die Reihenfolge mit den wenigsten Kreuzungen, Höhen nach den verbundenen Ports, keine Überlappung. Gemessen wird am gezeichnetenNodeView.lint_graph(Überlappungen, Kreuzungen, Kabel durch fremde Nodes, Rückwärts-Kanten, längste Kabel, je mit Beispiel-Ids) und Commandarrange_graph.Live am Testprojekt über MCP geprüft
arrange_graphDrei neue Nodes ohne Position landen rechts neben dem Bestand, der Bestand verrutscht nicht. Ein
undonimmt Nodes, Kanten und Anordnung zusammen zurück.Funde
lint_graphhat eine Kreuzung übersehen: Tauschen zwei Links genau spiegelbildlich ihre Zeilen, treffen sie sich exakt auf einem Stützpunkt, und gezählt wurde nur ein Durchkreuzen zwischen zwei Punkten. Behoben (segmentsMeet), der neue Test war vorher rot.objectin Zeile 2 des Moves, zwischenexecunddtder Taste.Tests
graph-arrange,agent-edit,snap-toggle: 33/33.relay.test.ts: 27/27 (drei neue zur Zählung).melektaus-atx: 18/18. Gate:CHECK EXIT 0, 318 Dateien, 4917 Tests (vor dem Lint-Fix gemessen).lint_graphmeldet 8 Kreuzungen, passend zum Screenshot.Nächstes: Wunsch des Users von heute: Der Agent soll die Tabs so öffnen und wechseln, dass man sieht, was er gerade bearbeitet. Danach Etappe 4 (Play-Tests).
Der Editor geht mit dem Agenten mit, und der CI-Fix zu Etappe 3
Commits
732989a4(CI-Fix) und97e0d931(Mitgehen und Kamera), Wiki3e7956c.CI-Fix: Suite 719 zu
0dd671ewar rotSnapToggle.setArrangeShownblendet ihn aus und legt die Kopfzeile neu aus. Der Magnet bleibt, wo er war.melektaus-atx: vorher rot (derselbe Fehler wie in CI), jetzt 59/59.5b9d084), nicht durch #429. Der damals eingebaute Wert zeigt diesmal, dass der Stream schon vor der Pause hinterherlief (skipped12950). Die Pause hat ihn also nicht aus dem Tritt gebracht. Auf atx lief der Check grün. Die Ursache bleibt offen.Mitgehen: Du siehst, woran der Agent arbeitet
run_commandszeigt der Editor, woran der letzte Schritt gearbeitet hat:Tests
agent-edit(3 neue),graph-framing(6 neue),snap-toggle(1 neuer)CHECK EXIT 0, 318 Dateien, 4931 TestsLive gebaut ist der Stand. Den CI-Lauf zu
97e0d93lese ich, bevor etwas daraufkommt.Nachtrag: CI wieder grün
Mein Kommentar 4730 nannte die Ursache des Wacklers in e2e 34 („the pause holds the stream“) noch offen. Suite 721 zu
97e0d93war dann wieder rot, nur noch mit diesem Check, jetzt mit 0 Unterläufen vor und 6745 nach der Pause.Ursache: Direkt vor dem Check erzwingt der Test eine volle Garbage Collection für die Speichermessung. Auf dem CI-Runner hielt sie die Seite sekundenlang an, und der Player lief leer, bevor die Pause geklickt wurde: 0,02 s bzw. 0,05 s Vorlauf in 719/721, statt ~2 s in grünen CI-Läufen. Das Worklet zählt einen Unterlauf erst, wenn die Samples nachkommen, deshalb tauchte er erst nach dem Fortsetzen auf. Mit #429 hat das nichts zu tun, betroffen waren auch Läufe davor (Task 712).
Fix
f296f427: Die Pause wird zuerst gemessen, an einem Stream mit mindestens 1 s Vorlauf. GC und Speichermessung kommen danach, während das Spiel noch läuft. Bewertet wird, was die Pause an Unterläufen hinzufügt.f296f42: Gate 723 und Suite 724 grün, 2119 e2e-Checks, Smokes 24/19/21. Der Check selbst lief mit 0 Unterläufen und ~2,2 s Vorlauf.Etappe 4: Play-Tests, fertig (
1943539)Der Agent kann ein gebautes Spiel jetzt selbst prüfen: Play starten, Tasten und Maus schicken, Zustand lesen. Der User muss keine Taste mehr drücken.
Neue Werkzeuge
play_inputschickt Schritte ins laufende Spiel: Taste halten (hold), antippen, gedrückt lassen oder loslassen (keep), Maus klicken, drücken, loslassen, bewegen, Mausrad, warten. Halten und Warten zählen Spielsekunden.get_runtimeliest das laufende Spiel: Objekte mit Id, Typ und Position, die eigenen Variablen der Behaviors, die Variables-Assets, Kamera, Tasten, Maus und Konsole. Benannte Objekte kommen mit allen Properties.get_viewundplaymelden, wenn die Szene keine aktive Kamera hat. Das war Fund 2 aus dem ersten Agententest (4724).Abweichung vom Plan: Statt
press_keysundpointergibt es ein Werkzeugplay_input. So kann eine Schrittfolge Tasten und Maus mischen, z. B. Shift halten und dabei klicken.Grenzen
Live am Testprojekt gefunden und behoben
hit: false, die Trefferprüfung suchte nur nach der Id.get_runtimezeigte die eingebauten Schalter eines Behaviors (enabled,runInEditor…) als Variablen.Danach live: 0,5 s →, 0,5 s ↑, 1 s ←, 0,25 s ↓ bei 200 px/s, der Player steht bei x −100, y −50, genau wie gerechnet. Der Klick über den Namen trifft.
Tests
agent-play(neu),agent-edit,agent-view,relayhit: true)CHECK EXIT 0, 319 Dateien, 4944 Testse2e 71 lief vor den beiden Fixes, die sind durch Unit-Tests, Gate und den Live-Test abgedeckt. Den CI-Lauf zu
1943539habe ich nicht abgewartet.Wiki: MCP, neuer Abschnitt Playing the game.
Offen: Etappe 5 (die übrigen Bereiche in den Katalog). #429 bleibt bis dahin offen.
Etappe 5a fertig: Graph, Variablen, Szene, Projekt (
0d8fd6f)Wiki
55a0ab0(MCP, Behaviors).Zuschnitt von Etappe 5
Der Agent kannte 23 von rund 135 Commands. Etappe 5 ist in Bereiche geteilt, je ein Commit:
Bewusst nicht für den Agenten: Datei-Assets (kein Upload), Einfügen aus der Zwischenablage, interne Hüllen-Commands und Plugins einschalten (würde fremden Code starten).
Gebaut
cataloglistet ohnequerynur Namen und Beschreibungen, mitquery(Bereich oder Command-Namen) die Argumente. Alle Schemas auf einmal wären über die 60 000-Zeichen-Grenze einer Antwort gegangen.add_portlässt einen Variables-Node auf eine Variable zeigen. Der Port übernimmt ihre Art, ein falscher Name wird mit der Liste der vorhandenen abgelehnt.add_group,add_comment) nehmen Nodes statt Koordinaten und rücken nach dem Anordnen nach, im selben Undo-Schritt.list_assetsliefert die Projekt-Einstellungen,get_assetden Inhalt platzierter Container,get_graphdie deklarierten Ports und die Rahmenfarben.lint_graphauch die Kreuzungen ansehen undarrange_graphaufrufen, wenn es mehr sind als nötig.Funde
WithStructTypes, neue Felder kamen bei Variablen dieses Typs nicht an.query: "variables"traf auchset_variables_scope. Ein Wort, das ein Bereich ist, meint jetzt nur den Bereich.Live an Project 6
speed= 300 statt der festen 200 im Move: → 0,5 s bringt den Player auf x 150,03 (mit 200 wären es 100).Tests
agent-catalog(neu, 10),agent-edit,graph-arrange(3 neu),relayspeedund Gruppe um alle 4 gezeichneten NodesCHECK EXIT 0, 320 Dateien, 4958 TestsDen CI-Lauf zu
0d8fd6fhabe ich nicht abgewartet.Offen
Etappe 5b fertig: Animation, Frames, Tiles, Tilemaps (
d01e2b8)Wiki
180cc43(Seite MCP: Bereichstabelle, Hinweise, Tests).Gebaut: 3 neue Bereiche mit 30 Commands, insgesamt jetzt 115.
animation(12)textures(8)tiles(10)get_assetnennt bei einer Animation die Ziele mit ihren animierbaren Properties. Tilemaps bis 400 Zellen liefern die Zellen selbst, größere nur die Anzahl.Beim Testen gefunden und behoben:
fillbehält jetzt die bisherige Füllung. Der Standard im Modell istrepeat, nichtstretch, wie ich zuerst beschrieben hatte.Tests:
agent-art(neu, 11) und die übrigen Agent-Tests: 64/64. 5 Gegenproben, alle rot.get_assetnennt die Ziele.CHECK EXIT 0, 321 Dateien, 4969 Tests.CI zu
0d8fd6f: Suite 728 war mit 2 Video-Checks (e2e 67, 68k) rot. Ursache war mein eigenes Gate, das aufmelektaus-atxzeitgleich mit der Suite lief. Mit dem Code hat das nichts zu tun. Eigene Läufe auf atx starte ich nicht mehr, solange dort eine Suite läuft.Offen: 5c (Pixel Art, Vector Art), 5d (Song, Pattern, Clips, Routing, Composition). Gruppen wachsen beim Neusetzen eines Nodes und bei Arrange weiterhin nicht mit.
Etappe 5c fertig: Pixel Art, Paletten, Vector Art (
0684e76)Wiki
c611f34, Seite MCP.Zwei neue Bereiche mit 29 Commands, der Katalog hat jetzt 144.
rect/ellipse, Umriss, Stil (Füllung, Deckkraft, Verlauf oder Bildfüllung, Kontur), verschieben/skalieren/drehen/spiegeln, kopieren, entfernen, kombinieren, umbenennen, Reihenfolge, in Gruppen verschieben, gruppieren, Ebenenpaint_pixelsbearbeitet eine Ebene auf einem Frame. Die Schritte laufen der Reihe nach:rows(ein kleines Bild als Zeichen, ein Leerzeichen lässt das Pixel stehen),pixels,line,rect,ellipse,fill,clear. Abgelehnt werden ein Index, den die Palette nicht hat, ein Pixel außerhalb der Leinwand und ein unbekanntes Zeichen.get_assetliefert bei Pixel Art die Palette alscolors. Bis 16 384 Pixel über alle Ebenen und Frames kommt jede Ebene als Zeilen, darüber nur die Zahl der gemalten Pixel. Farben kommen als#rrggbb.pixelActions.ts.Live in Project 6: ein 8×8-Slime und ein kopierter zweiter Frame (Blinzeln über
rect,line,pixels,fill) kamen überget_assetgenau so zurück. Ein um 45° gedrehtes Quadrat mit Kontur und eine Kreisscheibe mit radialem Verlauf, gruppiert: Die Ecken liegen bei 7,431 und 120,569 (64 ± 40·√2). Danach per Undo zurückgenommen.Tests:
agent-drawing(neu, 9) und die übrigen Agent-, Pixel- und Relay-Tests: 133/133.CHECK EXIT 0, 322 Dateien, 4978 Tests. Beide atx-Läufe erst nach dem Ende von Suite 729.Offen: 5d (Song, Pattern, Clips, Routing, Composition). Das Issue bleibt offen.
Etappe 5d fertig: Pattern, Song, Sends, Clips, Composition (
10f5e3b)Wiki
9154ac8, Seite MCP.Zwei neue Bereiche mit 24 Commands, der Katalog hat jetzt 168.
C4oderF#3.get_assetliest die Noten mit Namen zurück und nennt die Länge des Patterns in Ticks. Eine Note hinter dem Ende des Patterns wird abgelehnt.connect,set_sendsetzt Pegel und Abgriff.get_graphzeigt jetzt bei jeder Kante ihren Send.get_assetzeigt das alsseconds, fehlt es, verlangt der Agent eine Länge.Live in Project 6: Pattern Melody (C4, E4, G4, C5, ein Takt), Song Theme spielt es zweimal, dazu Bass eine Oktave tiefer. Bass schickt mit −6 dB vor dem FX zusätzlich in Track 1,
get_graphlas das genau so zurück. Danach meldetelint_graphein Kabel rückwärts (beide Spuren in einer Spalte), nacharrange_graph0. Composition Intro: Das Pattern-Item ist 120 Frames lang (1 Takt bei 120 BPM = 2 s bei 60 fps), eine Blende am Player wurde richtig abgelehnt. Danach per Undo zurückgenommen.Tests:
agent-music(neu, 9) und die übrigen Agent- und Relay-Tests: 109/109.CHECK EXIT 0, 323 Dateien, 4987 Tests. Beide atx-Läufe erst nach dem Ende der CI zu0684e76.Abschluss
Damit sind alle Etappen erledigt. Commits zu #429:
48ec72225af064b9d16020dd671e732989a97e0d9319435390d8fd6fd01e2b80684e7610f5e3bDer Katalog hat 168 Commands in 12 Bereichen. Bewusst nicht für den Agenten: Datei-Assets (kein Upload), alles über die Zwischenablage, interne Hüllen-Commands, Plugins einschalten (würde fremden Code starten) und Generate collision (liest die Pixel der Textur).
Bekannte Lücke, nicht Teil dieses Issues: Gruppen wachsen nicht mit, wenn ein neuer Node in sie gesetzt wird oder Arrange die Nodes neu ordnet (siehe 4738). Das Issue wird geschlossen.
Nachtrag: Funde aus dem Live-Test mit Musik
Commit
19902a9, Wiki54b0773(MCP, Behaviors). Das Issue bleibt geschlossen.Der Live-Test mit Pattern, Song und Composition in Project 6 hat vier Lücken gezeigt. Die Musik blieb stumm, und der Agent hat es nicht bemerkt.
get_assetmeldet das untersilent, mit Hinweis, wie man es behebtsilentnennt auch Noten, die das Instrument nicht spielt, im Song nach dem Transponieren, und den Bereich, den es spielt. Die Regel (soundingNotes) teilen sich Pattern-Tab und AgentannotationFollow.ts).add_comment/fit_groupweichen Nodes aus,lint_graphzähltcoveredNotesLive geprüft: Ein Log an Move landete in der Gruppe, die Gruppe wuchs von 464 auf 712. Ein Filter vor Output von Lead ergab bei
lint_graphüberall 0. Melody ohne Instrument zeigtesilent. Nach dem Weiten der Notenbereiche (Bass C1 bis C5, Lead C3 bis C7) steht bei Theme, Intro und Melody nichts mehr untersilent.Tests:
graph-follow(neu, 12),agent-edit,agent-music(11) und die übrigen Agent-, Graph-, Pattern- und Relay-Tests grün. 10 Gegenproben, alle rot. e2e 71: 25/25. Gate:CHECK EXIT 0, 324 Dateien, 5002 Tests.