docs: Theme Builder guide, instructions, readme and spec for 0.5.0

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-27 22:05:33 +02:00
co-authored by Claude Opus 5.5
parent 4e959833b9
commit 3db96a3f5b
14 changed files with 364 additions and 45 deletions
+32 -15
View File
@@ -33,8 +33,25 @@ Die Divi-Bibliothek speichert Layouts, Abschnitte, Zeilen und Module zur Wiederv
- `lit/library-save`: einen Abschnitt, eine Zeile oder ein Modul als neuen Eintrag speichern (`post_id`,
`tree_rev`, Pfad-ID `id`, `title`, `scope: "normal"` oder `"global"`, vorhandene `categories`/`tags`). Der
Knoten auf der Seite bleibt eine eigenständige Kopie – um ihn zu verknüpfen, ihn durch eine Instanz
ersetzen (siehe Ablauf unten). Ein Knoten, der selbst ein globales Modul ist oder eines enthält, lässt sich
nicht als globaler Eintrag speichern.
ersetzen (siehe Ablauf unten). Ein Knoten, der selbst ein globales Modul ist oder auf einen Eintrag verweist
(auch als Divi-4-Shortcode mit `global_module` in einem Text), lässt sich nicht als globaler Eintrag speichern.
- `lit/library-find-similar`: Knoten finden, die wie ein Knoten (`post_id` und `id`) oder ein Eintrag
(`library_id`) aufgebaut sind. `match: "identical"` = gleicher Inhalt einschließlich aller Texte (nur
Admin-Labels ausgenommen), `"structure"` = gleicher Aufbau (Modultypen, Spalten, Presets) mit anderen Inhalten.
Durchsucht werden Einträge der Divi-Inhaltstypen (optional nur `post_type`), nie Bibliothekseinträge oder
Theme-Builder-Layouts; nur Einträge, die das Konto bearbeiten darf. Höchstens 200 Einträge je Aufruf
(`limit`), weiter mit `next_cursor`; bei sehr vielen Treffern endet ein Aufruf früher und sagt das in `note`.
Jeder Treffer nennt `tree_rev`.
- `lit/library-make-global`: einen Knoten einer Seite oder eines Beitrags in ein globales Modul umwandeln
(`post_id`, `tree_rev`, `id`, `title`, optional `categories`/`tags`): neuer globaler Eintrag mit genau diesem
Inhalt, der Knoten wird durch die Instanz ersetzt – alles oder nichts. Weitere, inhaltsgleiche Vorkommen
ersetzen: `library_id` und `targets` (je `post_id`, `tree_rev`, `ids` der Treffer `"identical"`; höchstens 20
Seiten). Alle Ziele werden vorher geprüft; ohne `confirm` ist das ein Probelauf (`confirm_required` mit
`affected`), dann `confirm: true`. Jede Seite bekommt eine Revision (`pages`). Nur Seiten und Beiträge
(Inhaltstypen `page` und `post`), die das Konto bearbeiten darf – keine Bibliothekseinträge und keine
Theme-Builder-Layouts, auch nicht als Quelle. Knoten, die auf einen Eintrag verweisen, werden kein globales
Modul. Schlägt eine Seite fehl, bleiben die vorher ersetzten Seiten ersetzt (je mit Revision), die übrigen
unverändert; der Fehler nennt alle drei Gruppen (`changed_posts`, `failed_post`, `unchanged_posts`).
- `lit/divi-node-copy`: einen Knoten von einem Eintrag an eine Position eines anderen kopieren
(`source_post_id`, `source_id`, `source_tree_rev` aus `lit-divi-outline` der Quelle – Pflicht, weil
Pfad-IDs nur für diesen Stand gelten; Ziel mit `post_id`, `tree_rev`, Position). Quelle und Ziel dürfen
@@ -84,6 +101,9 @@ wird leer; ein globaler Eintrag enthält keine globalen Module. Nur aktive Eintr
`lit-page-render-summary` zeigt globale Module nicht (über die Schnittstelle rendert Divi sie nicht) und nennt
sie in `notes`; ihren Inhalt mit `lit-divi-outline` und der ID lesen.
Fügt eine Divi-Änderung einen Abschnitt ein, der wie ein Abschnitt der Bibliothek aufgebaut ist, nennt
`warnings` den Eintrag – dann `lit-library-insert` erwägen.
## Rechte
- WordPress: die Bibliothek nutzen = Beiträge bearbeiten dürfen; einen Eintrag lesen oder ändern = diesen
@@ -96,10 +116,8 @@ sie in `notes`; ihren Inhalt mit `lit-divi-outline` und der ID lesen.
Hinweis.
- Einstellungen → LIT MCP → Tools: Gruppe „Divi-Bibliothek“ auf „nur lesen“ sperrt jeden Schreibzugriff auf
Bibliothekseinträge, auch über die Divi-Werkzeuge; deaktiviert gilt jeder Eintrag als nicht vorhanden.
Grenze: Die Einträge selbst sind dann nicht lesbar und nicht änderbar, aber `lit-divi-outline`,
`lit-divi-node-get` und `lit-page-render-summary` einer Seite nennen die ID eines dort verwendeten globalen
Moduls weiterhin (auch ohne das Recht „Divi-Bibliothek“). Diese ID mit den Divi-Werkzeugen zu öffnen,
antwortet `not_found`; dann nicht weiter versuchen.
Ohne das Recht „Divi-Bibliothek“ oder mit deaktivierter Gruppe nennen `lit-divi-outline`, `lit-divi-node-get`
und `lit-page-render-summary` globale Module nur als solche, ohne ihre ID.
`lit-library-insert` und `lit/divi-node-copy` sind außerdem gesperrt, wenn `lit-divi-insert` gesperrt ist;
`lit/divi-node-copy` mit einem Bibliothekseintrag als Quelle auch, wenn `lit-library-insert` gesperrt ist.
- Ohne das Recht `unfiltered_html` überträgt LIT MCP beim Kopieren, Einfügen und Speichern (`lit/divi-node-copy`,
@@ -113,13 +131,12 @@ sie in `notes`; ihren Inhalt mit `lit-divi-outline` und der ID lesen.
## Ablauf: globale Module vorschlagen
1. Die Seiten lesen (`lit-divi-outline`) und wiederkehrende Abschnitte suchen (gleiche Admin-Labels oder
Texte, z. B. Kontakt, Öffnungszeiten, Call-to-Action).
2. Dem Nutzer vorschlagen, welche davon globale Module werden sollen, und erklären: eine Änderung wirkt
danach auf allen Seiten.
3. Nach Zustimmung den Abschnitt einer Seite mit `lit/library-save` und `scope: "global"` speichern.
4. Auf jeder Seite (auch der ersten) die Instanz mit `lit-library-insert` direkt vor dem bisherigen Abschnitt
einfügen und den bisherigen Abschnitt nach Rückfrage mit `lit-divi-delete` entfernen.
1. Wiederkehrende Abschnitte suchen: `lit/library-find-similar` mit einem typischen Abschnitt (`post_id`, `id`)
– z. B. Kontakt, Öffnungszeiten, Call-to-Action.
2. Dem Nutzer die Treffer zeigen und erklären: eine Änderung wirkt danach auf allen Seiten mit dem Modul.
Treffer mit `match: "structure"` unterscheiden sich im Inhalt – vorher klären, welche Fassung gilt, und die
übrigen angleichen (`lit-divi-update`) oder weglassen.
3. Nach Zustimmung `lit/library-make-global` mit dem gewählten Abschnitt.
4. Die inhaltsgleichen Vorkommen mit `lit/library-make-global` (`library_id`, `targets` mit der `tree_rev` aus
`lit/library-find-similar`) ersetzen: Probelauf zeigen, dann `confirm: true`.
5. Den Nutzer bitten, das Ergebnis im Divi-Builder anzusehen.
Unterscheiden sich die Abschnitte in Details, vorher mit dem Nutzer klären, welche Fassung gilt.
+6 -2
View File
@@ -33,12 +33,16 @@ beginnt (geschützte Meta-Daten), sind nicht erlaubt.
In Link-Feldern (`url`, `button_url` …) für interne Links immer `{{link:<ID>}}` verwenden statt fester
Adressen wie `/?page_id=…`. Der Eintrag muss existieren und für das Konto lesbar sein; Einträge im Papierkorb,
automatische Entwürfe und Medien (Anhänge – dafür die Adresse aus der Mediathek) lehnt das Werkzeug ab,
ebenso `{{link:…}}` außerhalb von Link-Feldern. Solange das Ziel ein Entwurf oder privat ist, zeigt Divi
automatische Entwürfe, Einträge der Divi-Bibliothek und Medien (Anhänge – dafür die Adresse aus der Mediathek)
lehnt das Werkzeug ab – wie eine unbekannte ID –, ebenso `{{link:…}}` außerhalb von Link-Feldern. Solange das Ziel ein Entwurf oder privat ist, zeigt Divi
Besuchern nur die Adresse `?page_id=<ID>` (kein Titel); nach dem Veröffentlichen die normale Adresse. Sonst
nimmt ein Link-Feld jeden dynamischen Inhalt an; sinnvoll sind nur Werte, die eine Adresse ergeben
(`{{post:url}}`, ein Feld mit einer URL, eine Link-Variable).
Dieselben Regeln gelten für die Vollform `post_link_url_<Typ>` mit `post_id`: das Ziel muss lesbar sein, darf
nicht im Papierkorb liegen, kein Anhang und kein Bibliothekseintrag sein und muss genau den Typ im Namen haben
(`post_link_url_page` nur für Seiten). `{{link:<ID>}}` wählt den passenden Namen selbst.
Welche dynamischen Quellen und Felder es für einen Inhaltstyp gibt, liefert `lit/divi-dynamic-sources`
(über `mcp-adapter-execute-ability`): Divis Quellen mit Platzhalter und die Felder, die sich als
`{{field:…}}` eignen. Gelistet werden nur textartige Felder; Beziehungs- und Dateifelder (Divi zeigt sie nur
+10 -6
View File
@@ -23,9 +23,9 @@ Direkt sichtbar: `lit-guide`, `lit-site-status`, `lit-content-types`, `lit-conte
`lit-divi-outline`, `lit-divi-node-get`, `lit-divi-catalog`, `lit-divi-design-system`, `lit-divi-insert`,
`lit-divi-update`, `lit-divi-move`, `lit-divi-delete`, `lit-library-insert`.
Die Tools sind nach Integration gruppiert (Grundlagen, WordPress, Medien, Divi, Divi-Bibliothek). Jede Gruppe hat unter
Einstellungen → LIT MCP → Tools eine eigene Einstellung (direkt/indirekt/deaktiviert), die ihre Tools übernehmen
(„wie Gruppe“). Eine Einstellung am einzelnen Tool geht vor; die Gruppe zeigt dann „gemischt“. „nur lesen“
Die Tools sind nach Integration gruppiert (Grundlagen, WordPress, Medien, Divi, Divi-Bibliothek,
Divi Theme Builder). Jede Gruppe hat unter Einstellungen → LIT MCP → Tools eine eigene Einstellung
(direkt/indirekt/deaktiviert), die ihre Tools übernehmen („wie Gruppe“). Eine Einstellung am einzelnen Tool geht vor; die Gruppe zeigt dann „gemischt“. „nur lesen“
schaltet alle schreibenden Tools der Gruppe ab – auch solche mit eigener Einstellung. `lit-guide` bleibt immer
direkt; `lit-media-preview`/`lit-media-download` bleiben bei Gruppe „indirekt“ direkt. Ab mehr als 25 direkten
Tools warnt die Seite (Kontextkosten im Assistenten). Änderungen gelten ab der nächsten Verbindung.
@@ -37,13 +37,17 @@ Status (`lit/post-unpublish`, `lit/post-schedule`, `lit/post-trash`), Kopien (`l
(`lit/menu-list`, `lit/menu-get`, `lit/menu-create`, `lit/menu-set-items`, `lit/menu-assign-location`),
Einstellungen (`lit/wp-settings-get`, `lit/wp-settings-update`), Medien (`lit/media-get`, `lit/media-upload`,
`lit/media-update`, `lit/media-delete`), Divi (`lit/divi-duplicate-node`, `lit/divi-replace-text`,
`lit/divi-node-copy`, `lit/divi-dynamic-sources`), Divi-Bibliothek (`lit/library-list`, `lit/library-save`).
`lit/divi-node-copy`, `lit/divi-dynamic-sources`), Divi-Bibliothek (`lit/library-list`, `lit/library-save`,
`lit/library-find-similar`, `lit/library-make-global`), Divi Theme Builder (`lit/tb-list`,
`lit/tb-create-template`, `lit/tb-assign`, `lit/tb-activate`).
Die `lit-divi-…`-Werkzeuge gibt es nur, wenn der Divi-5-Builder aktiv ist. Sie arbeiten auch auf Einträgen
der Divi-Bibliothek (ID als `post_id`); globale Module: `lit-guide` topic `divi-library`.
der Divi-Bibliothek und auf Layouts des Theme Builders (ID als `post_id`); globale Module: `lit-guide` topic
`divi-library`, Vorlagen: `lit-guide` topic `theme-builder`.
Weitere Themen: `lit-guide` mit `topic` = `content-types`, `workflows`, `media`, `divi-structure`,
`divi-shortform`, `divi-attrs`, `divi-placeholders`, `divi-design-system` oder `divi-library`.
`divi-shortform`, `divi-attrs`, `divi-placeholders`, `divi-design-system`, `divi-library` oder
`theme-builder`.
Für den Einstieg liefert `lit-guide` mit dem Thema „all“ alle Themen in einem Aufruf.
+117
View File
@@ -0,0 +1,117 @@
# Divi Theme Builder
Der Theme Builder legt fest, wie Kopfzeile, Inhalt und Fußzeile für bestimmte Seiten aussehen – z. B. für alle
Einträge eines eigenen Inhaltstyps. Eine **Vorlage** hat Bedingungen („gilt für alle Personen“) und bis zu drei
**Layouts** (Kopfzeile, Inhalt, Fußzeile). Die **Standardvorlage** gilt überall, wo keine andere greift; ihre
Kopf- und Fußzeile heißen „global“, weil andere Vorlagen sie mitbenutzen.
## Grundregel: nichts wird ohne Freigabe sichtbar
- Neue Vorlagen legt LIT MCP immer **deaktiviert** an – Besucher sehen nichts davon.
- Aktivieren und Deaktivieren gibt es nur mit `lit/tb-activate`, und immer so: Probelauf (Bedingungen, Layouts,
andere aktive Vorlagen mit denselben oder verwandten Bedingungen unter `overlaps`/`possible_overlaps`) →
Nutzer fragen → dieselbe Anfrage mit `confirm: true`.
- Auch alles andere, was Besucher sofort sähen, ist zuerst ein Probelauf (`confirm_required`) und braucht
`confirm: true`: Bedingungen einer aktiven Vorlage ändern (`lit/tb-assign`) und ein Layout ändern, das eine
aktive Vorlage zeigt (die `lit-divi-…`-Werkzeuge; die Antwort nennt die Vorlagen unter `templates`). Vor dem
Speichern eines sichtbaren Layouts entsteht eine Revision; sind Revisionen abgeschaltet, eine
Sicherungskopie im Papierkorb (`backup_id`).
- `lit/divi-replace-text` ändert sichtbare Layouts nicht; solche Änderungen mit `lit-divi-update` und
`confirm: true` vornehmen.
- Die Standardvorlage ändert LIT MCP nicht (nur im Theme Builder).
## Werkzeuge (über `mcp-adapter-execute-ability`)
- `lit/tb-list`: alle Vorlagen mit `enabled`, `live` (für Besucher wirksam), Bedingungen (`use_on`,
`exclude_from` und Beschriftungen), Layouts (`id`, Titel, `shared_with` = andere Vorlagen mit demselben
Layout) und `template_rev`. `template_id`: nur diese Vorlage. `conditions: true` liefert alle Bedingungen,
die Divi anbietet; eine ID, die auf „:“ endet, braucht ein Objekt am Ende, z. B.
`singular:post_type:page:id:42`. `detached` zeigt Vorlagen, die ein Speichern im Theme Builder entfernt hat
(siehe unten); `draft_pending` zeigt ungespeicherte Änderungen im Theme Builder.
- `lit/tb-create-template`: `title`, je Bereich (`header`, `body`, `footer`) `source`:
`"new"` (neues Layout; optional `nodes` wie bei `lit-divi-insert` und `title`), `"global"` (Kopf-/Fußzeile
der Standardvorlage mitbenutzen; nicht für `body`), `"default"` (nichts Eigenes, Standard bei fehlender
Angabe) oder `"hidden"` (Bereich ausblenden). Optional `use_on`/`exclude_from`. Alles oder nichts: schlägt
ein Schritt fehl, entfernt LIT MCP alles wieder. Antwort: `template_id`, `template_rev`, `enabled: false`,
`layouts`.
- `lit/tb-assign`: Bedingungen ersetzen (`template_id`, `template_rev`, `use_on`). Fehlt `exclude_from`,
bleiben die bisherigen Ausnahmen; `[]` entfernt sie. Der Probelauf einer aktiven Vorlage zeigt vorher/nachher
(`before`, `after`) und Überschneidungen. Die Antwort nennt die bisherigen Bedingungen unter `previous`.
- `lit/tb-activate`: `enabled: true` oder `false` (`template_id`, `template_rev`). Deaktivieren ist der
schnelle Weg zurück. Zum Aktivieren müssen alle Layouts der Vorlage noch aktiv sein.
- Layouts bearbeiten: `lit-divi-outline`, `lit-divi-node-get`, `lit-divi-insert`, `lit-divi-update`,
`lit-divi-move`, `lit-divi-delete` … mit der Layout-ID als `post_id` (aus `lit/tb-list`). Benutzt eine
andere Vorlage dasselbe Layout (`shared_with`), wirkt die Änderung auch dort. Das Modul „Beitragsinhalt“
(`post-content`) gibt es nur im Inhalt-Layout, nicht in Kopf- oder Fußzeile.
## Bedingungen
Erlaubt sind nur die Bedingungen, die Divi selbst anbietet (`lit/tb-list` mit `conditions: true`), höchstens 50
je Liste. Ein Objekt am Ende (Seite, Beitrag, Begriff, Person) muss existieren und für das Konto lesbar bzw.
zuweisbar sein; sonst lautet die Antwort wie bei einer unbekannten ID. Bedingungen für Autoren
(`archive:user:id:…`) verlangen das Recht, Benutzer aufzulisten (`list_users`) – strenger als Divi.
## Felder im Inhalt-Layout (Dynamic Content)
Im Inhalt-Layout zeigen Platzhalter die Daten des jeweiligen Eintrags: `{{post:title}}`, `{{post:excerpt}}`,
`{{post:date}}` und Felder als `{{field:<Schlüssel>}}`. Welche Felder ein Inhaltstyp hat und welche Divi als Text
zeigt, liefert `lit/divi-dynamic-sources` mit `post_type`. Nur textartige Felder eignen sich: Bei Auswahlfeldern
zeigt Divi den gespeicherten Wert, nicht die Beschriftung; Beziehungs- und Dateifelder zeigen nur IDs, Pods mit
Tabellen-Speicherung gar nichts.
LIT MCP prüft die Felder eines geänderten Inhalt-Layouts gegen die Inhaltstypen aus den Bedingungen
(`singular:post_type:<typ>:…`) der Vorlagen, die das Layout benutzen, und warnt (`warnings`) – gespeichert wird
trotzdem. Das gilt für die Kurzform `{{field:…}}` und für Felder, die im Divi-Builder über „Benutzerdefiniertes
Feld“ gewählt wurden. Bei einem sichtbaren Layout stehen die Warnungen schon im Probelauf. Ohne solche Bedingung
bleiben die Felder ungeprüft (die Antwort sagt das). Kopf- und Fußzeile werden nicht geprüft.
## Wenn der Theme Builder gerade offen ist
- Hat der Theme Builder ungespeicherte Änderungen (Entwurf, `draft_pending`), lehnen `lit/tb-create-template`,
`lit/tb-assign` und das Aktivieren ab: erst dort speichern oder verwerfen.
- Deaktivieren (`lit/tb-activate` mit `enabled: false`) geht immer – auch dann, und auch bei einer aktiven
Vorlage im Papierkorb. Die Antwort warnt: Speichert jemand ein offenes Theme-Builder-Fenster, kann Divi
seinen eigenen Stand wiederherstellen; danach mit `lit/tb-list` prüfen.
- Speichert jemand in einem Theme-Builder-Fenster, das vor dem Anlegen einer Vorlage geöffnet wurde, entfernt
Divi die neue Vorlage wieder aus der Liste und löscht sie 7 Tage später. `lit/tb-list` zeigt sie dann unter
`detached` (mit `marked_unused`). Nur auf ausdrücklichen Wunsch: `lit/tb-assign` mit `reattach: true` ordnet
sie wieder zu – immer deaktiviert, und nur, wenn ihre Layouts noch aktiv sind.
## Rechte
- WordPress: „Beiträge anderer bearbeiten“ (`edit_others_posts`) und „Design bearbeiten“
(`edit_theme_options`); je Vorlage und Layout das Recht, sie zu bearbeiten; zum Anlegen zusätzlich
„veröffentlichen“ (Divi legt Vorlagen und Layouts sofort aktiv an).
- Divi → Rollen-Editor: „Theme Builder“ – standardmäßig nur für Administratoren.
- Fehlt eines davon, gibt es für dieses Konto keine Vorlagen und Layouts (`not_found` wie bei einer unbekannten
ID bzw. `forbidden`). Vorlagen, die das Konto nicht bearbeiten darf, erscheinen nirgends; aktive davon nur als
Anzahl (`hidden_live` in `lit/tb-list`, `hidden_overlaps` im Probelauf).
- Einstellungen → LIT MCP → Tools: Gruppe „Divi Theme Builder“ auf „nur lesen“ sperrt jedes Schreiben, auch über
die `lit-divi-…`-Werkzeuge; deaktiviert gibt es keine Vorlagen und Layouts.
## Globale Module im Theme Builder
`lit/library-make-global` wandelt keine Knoten in Theme-Builder-Layouts um. Stattdessen den Abschnitt mit
`lit/library-save` (`scope: "global"`) speichern und mit `lit-library-insert` (`mode: "global"`) einfügen
(`lit-guide` topic `divi-library`).
## Rückgängig machen
Vorlagen haben keine Revisionen: `lit/tb-assign` nennt die bisherigen Bedingungen (`previous`), `lit/tb-activate`
schaltet zurück; jede Änderung steht im Protokoll. Layouts erhalten wie Divi-Seiten eine Revision. Neu angelegte
Vorlagen im Divi Theme Builder löschen.
## Ablauf: Vorlage für einen Inhaltstyp (custom-post-type-vorlage)
1. Inhaltstyp und Felder klären: `lit-content-types`, dann `lit/divi-dynamic-sources` mit `post_type`.
2. `lit/tb-list` lesen: gibt es schon eine Vorlage für den Typ? Gibt es eine globale Kopf-/Fußzeile?
3. Mit dem Nutzer den Aufbau abstimmen (welche Felder, welche Reihenfolge, Kopf-/Fußzeile global oder eigen).
4. `lit/tb-create-template` mit `use_on: ["singular:post_type:<typ>:all"]`, `header`/`footer` meist
`{"source": "global"}`, `body` mit `source: "new"` und `nodes` (Überschrift `{{post:title}}`, Texte mit
`{{field:…}}`, das Modul `post-content`, wenn der Eintrag eigenen Inhalt hat). Warnungen zu Feldern beachten.
5. Das Inhalt-Layout bei Bedarf mit `lit-divi-outline`/`lit-divi-update` verfeinern (Layout-ID als `post_id`;
solange die Vorlage deaktiviert ist, ohne Probelauf).
6. Den Nutzer bitten, die Vorlage im Theme Builder anzusehen (Vorschau eines Eintrags ist erst nach dem
Aktivieren möglich).
7. Erst auf ausdrücklichen Wunsch: `lit/tb-activate` mit `enabled: true` – Probelauf zeigen, dann
`confirm: true`.
+9 -2
View File
@@ -26,8 +26,9 @@
Vorhandene Abschnitte aus der Divi-Bibliothek zuerst suchen (`lit/library-list`) und mit `lit-library-insert`
einfügen, statt sie neu zu bauen. Einen gelungenen Abschnitt für später speichern: `lit/library-save`.
Abschnitte zwischen Seiten kopieren: `lit/divi-node-copy`. Globale Module ändern und neue vorschlagen:
`lit-guide` topic `divi-library`.
Abschnitte zwischen Seiten kopieren: `lit/divi-node-copy`. Wiederkehrende Abschnitte finden und zu globalen
Modulen machen: `lit/library-find-similar`, `lit/library-make-global`. Globale Module ändern und neue
vorschlagen: `lit-guide` topic `divi-library`.
## Text auf vielen Seiten ersetzen
@@ -68,3 +69,9 @@ geändert, sondern in `skipped_nodes` genannt – sie im Bibliothekseintrag änd
1. `lit-content-types` mit `post_type` → Pflichtfelder, Auswahlwerte, Beziehungsziele.
2. `lit-content-create` mit allen Pflichtfeldern in `fields`.
3. Beziehungen über IDs (vorher mit `lit-content-query` suchen).
## Vorlage für einen Inhaltstyp (Theme Builder)
Wie Einträge eines Inhaltstyps (z. B. Personen) auf der Website aussehen, legt eine Theme-Builder-Vorlage fest.
Ablauf und Regeln: `lit-guide` topic `theme-builder`. Neue Vorlagen sind deaktiviert; aktiviert wird nur auf
ausdrücklichen Wunsch mit `lit/tb-activate`.
@@ -220,3 +220,46 @@ Quellen der Web-Recherche: [Divi AI Agent – Ankündigung](https://www.elegantt
Divi-Katalog beim Standard von 128M nicht mehr in den Speicher passt.
- Server-Instructions: Zeile „Divi-Bibliothek: …“ nur bei aktiver, beschreibbarer Gruppe; MCP-Prompts gibt es
noch nicht, der Ablauf „globale Module vorschlagen“ steht im Guide `divi-library` (E14).
## 7. Umsetzung Etappe 3b (Plan 2026-09-27-etappe-3b-theme-builder.md)
Rulings Q1–Q25: `.superpowers/sdd/2026-09-27-etappe-3b-theme-builder/progress.md`.
- E7 präzisiert: Layouts und neue Vorlagen über `et_theme_builder_insert_layout`/`et_theme_builder_store_template`
mit Rechteprüfung davor und `wp_die`-Sperre währenddessen; Zuordnung zur Live-Liste, Bedingungen und
`_et_enabled` als Nachbildung von Divis Meta-Schreibweise (store_template würde bei bestehenden Vorlagen auch
Standard-Kennzeichen, Titel und Onboarding-Meta neu schreiben). Nach dem Anlegen Rücklesen; Abweichung =
alles zurücknehmen, auch Posts, die Divi vor einem Fehler schon eingefügt hatte (Q19).
- E8/Antwort F1 umgesetzt als eigenes Tool `lit/tb-activate` (statt `enabled` in `lit/tb-assign`); neue Vorlagen
sind immer deaktiviert. Jede andere Änderung, die Besucher sofort sähen (Bedingungen aktiver Vorlagen, Layouts
aktiver Vorlagen), ist zuerst ein Probelauf und braucht `confirm`; Layouts mit der Sicherung aus
`VisibleEdits` (Q2, Q9). Aktiv = zugeordnet und `_et_enabled`, unabhängig vom Post-Status (Q8).
- Der Ausschalter (`lit/tb-activate` mit `enabled: false`) geht immer: auch bei TB-Entwurf, dann mit Warnung
(Q20), und bei einer aktiven Vorlage im Papierkorb (Q16).
- TB-Editor: Ablehnung bei TB-Entwurf; neue Vorlagen hängen sofort an der Live-Liste; `lit/tb-list` zeigt vom
Theme Builder entfernte Vorlagen (`detached`), `lit/tb-assign` mit `reattach` ordnet sie deaktiviert wieder zu
(nur mit aktiven Layouts, Q8/B10). Befunde 10–12: `tests/Fixtures/divi/stage3b/README.md`.
- E3 für den Theme Builder: `edit_others_posts`, `edit_theme_options` (Q15) und Divis Rollen-Recht
„Theme Builder“, je Vorlage/Layout `edit_post`, zum Anlegen die Veröffentlichen-Rechte. Nicht bearbeitbare
Vorlagen antworten wie fehlende (Q18); aktive davon nur als Anzahl in Liste und Probeläufen
von `lit/tb-assign`/`lit/tb-activate` (Q21; für die Probeläufe der Layout-Änderungen folgt Q22 in der
Schlussrunde).
- Bedingungen nur aus Divis Katalog; Objekte lesbar (Begriffe: `assign_term`); strenger als Divi:
Autoren-Bedingungen (`archive:user:id:`) nur mit `list_users` (Q10).
- E9: eigene Gruppe „Divi Theme Builder“ (`divi-theme-builder`); alle neuen Tools indirekt, 22 direkte Tools.
- E10/E11 umgesetzt mit `Fingerprint` (Struktur/Inhalt). „Inhaltsgleich“ heißt gleiche Bytes einschließlich
Textteilen zwischen Blöcken und Inhalt von Core-Blöcken, nur Admin-Labels ausgenommen (Q25); ersetzt wird nur
auf Seiten und Beiträgen (`page`, `post`), die das Konto bearbeiten darf – Theme-Builder-Layouts auch nicht als
Quelle (Q24). Globale Einträge enthalten keinen Verweis auf einen Eintrag in irgendeiner Schreibweise (Q7).
D10-Semantik beim Speichern mehrerer Seiten: Abbruch bei der ersten gescheiterten Seite, Fehler nennt
geänderte, gescheiterte und unveränderte Seiten.
- E12: Feldprüfung im Inhalt-Layout als Warnung gegen die Inhaltstypen der Vorlagen-Bedingungen, beide
Feldformen (Q11).
- P13 (vollständiges Ausblenden der Bibliotheks-IDs, auch im Suchen-und-Ersetzen) und P10 (Zielregeln der
Vollform `post_link_url_*`, Bibliothekseinträge und Typen ohne Divi-Linkoption wie fehlende IDs, Q14)
umgesetzt.
- Restrisiken: P25 (ungewöhnliche Schreibweisen globaler Verweise), dazu Divis erneutes Auswerten von Blöcken in
Shortcode-Modulen und WooCommerce-Textmodulen (dokumentiert im Guide `divi-library`); das Präfilter-Orakel von
`lit/divi-replace-text` (Q13) und die Race-Bedingungen zwischen Prüfen und Schreiben bleiben für Etappe U.
- Server-Instructions: Zeile „Divi Theme Builder: …“ nur bei aktiver, beschreibbarer Gruppe; der Ablauf
„custom-post-type-vorlage“ steht im Guide `theme-builder`.
@@ -114,7 +114,7 @@ Ob dieser Aufbau stabil funktioniert, entscheidet Etappe 0 (§12).
- **Direkte Tools (~20):** mit vollem Schema sofort sichtbar; nur direkte Tools können Bilder (`ImageContent`) zurückgeben. Standard-Set:
`lit/guide`, `lit/content-types`, `lit/content-query`, `lit/content-get`, `lit/content-create`, `lit/content-update`, `lit/post-publish`, `lit/media-search`, `lit/media-preview`, `lit/media-upload-from-url`, `lit/divi-outline`, `lit/divi-node-get`, `lit/divi-insert`, `lit/divi-update`, `lit/divi-move`, `lit/divi-delete`, `lit/divi-design-system`, `lit/divi-catalog`, `lit/library-insert`, `lit/page-render-summary`.
- **Stand nach Etappe 2 (Entscheidung D2, 2026-09-26):** 21 direkte Tools – das Standard-Set oben ohne `lit/library-insert` (kommt mit Etappe 3), dazu `lit/site-status` (leeres Eingabeschema, Anker der Verbindungstests) und `lit/media-download` (eingebettete Ressource, funktioniert nur direkt). `lit/divi-duplicate-node` und `lit/divi-replace-text` sind indirekt. Mit Etappe 3 sind es 22; das Budget wird dort erneut geprüft (Kosten entstehen vor allem durch große Eingabeschemas, nicht durch die Zahl). **Stand nach Etappe 3a:** 22 direkte Tools (dazu `lit/library-insert`); indirekt neu `lit/library-list`, `lit/library-save`, `lit/divi-node-copy`, `lit/divi-dynamic-sources`. Neue Tool-Gruppe „Divi-Bibliothek“ (`lit/library-*`); `lit/divi-node-copy` und `lit/divi-dynamic-sources` gehören zur Gruppe „Divi“.
- **Stand nach Etappe 2 (Entscheidung D2, 2026-09-26):** 21 direkte Tools – das Standard-Set oben ohne `lit/library-insert` (kommt mit Etappe 3), dazu `lit/site-status` (leeres Eingabeschema, Anker der Verbindungstests) und `lit/media-download` (eingebettete Ressource, funktioniert nur direkt). `lit/divi-duplicate-node` und `lit/divi-replace-text` sind indirekt. Mit Etappe 3 sind es 22; das Budget wird dort erneut geprüft (Kosten entstehen vor allem durch große Eingabeschemas, nicht durch die Zahl). **Stand nach Etappe 3a:** 22 direkte Tools (dazu `lit/library-insert`); indirekt neu `lit/library-list`, `lit/library-save`, `lit/divi-node-copy`, `lit/divi-dynamic-sources`. Neue Tool-Gruppe „Divi-Bibliothek“ (`lit/library-*`); `lit/divi-node-copy` und `lit/divi-dynamic-sources` gehören zur Gruppe „Divi“. **Stand nach Etappe 3b:** weiterhin 22 direkte Tools; indirekt neu `lit/tb-list`, `lit/tb-create-template`, `lit/tb-assign`, `lit/tb-activate` (neue Tool-Gruppe „Divi Theme Builder“; „nur lesen“ sperrt auch Schreibzugriffe der Divi-Werkzeuge auf Theme-Builder-Layouts, deaktiviert gelten Vorlagen und Layouts als nicht vorhanden) sowie `lit/library-find-similar`, `lit/library-make-global` (Gruppe „Divi-Bibliothek“).
- **Alle übrigen Abilities:** über die Meta-Tools des Adapters (`discover-abilities`, `get-ability-info`, `execute-ability`).
- In den Einstellungen änderbar, welche Abilities direkt, indirekt oder deaktiviert sind.
- Ability-Namen: `lit/<bereich>-<aktion>`. Der Adapter bildet daraus Tool-Namen (`lit-<bereich>-<aktion>`).
@@ -159,7 +159,7 @@ tests/Unit, tests/Integration, tests/Fixtures
1. **Verbinden:** mcp-oauth-Autorisierung (jeder eingeloggte Benutzer).
2. **Nutzen:** Capability `lit_mcp_use` (nur freigegebene Rollen) – geprüft über Adapter-Filter und in jeder Ability.
3. **Handeln:** konkrete Prüfung pro Ability, z. B. `edit_post` für die Ziel-ID, `publish_post` fürs Veröffentlichen, `upload_files`, `edit_theme_options` für Divi-Designsystem und Menüs, `manage_options` für WP-Einstellungen, `edit_others_posts` für Theme Builder (Divi-Anforderung).
3. **Handeln:** konkrete Prüfung pro Ability, z. B. `edit_post` für die Ziel-ID, `publish_post` fürs Veröffentlichen, `upload_files`, `edit_theme_options` für Divi-Designsystem und Menüs, `manage_options` für WP-Einstellungen, `edit_others_posts`, `edit_theme_options` und Divis Rollen-Recht „Theme Builder“ für den Theme Builder (Divi-Anforderung und Gate von Divis Theme-Builder-Seite; Etappe 3b), dazu `edit_post` je Vorlage/Layout; Vorlagen ohne `edit_post` antworten wie fehlende IDs, aktive davon erscheinen nur als Anzahl.
## 5. Divi-Kern
@@ -229,7 +229,7 @@ Jede Schreib-Rückmeldung enthält Warnungen zu:
- leeren Modulen,
- Sprüngen in der Überschriftenhierarchie,
- Verwendung des Code-Moduls,
- ähnlichen, bereits existierenden Abschnitten (Hinweis auf `lit/library-find-similar`) – ab Etappe 3 zusammen mit `lit/library-find-similar` (D6).
- ähnlichen, bereits existierenden Abschnitten (Hinweis auf `lit-library-insert` und `lit/library-find-similar`) – verglichen wird nur ein neu eingefügter Abschnitt mit den Abschnitten der Divi-Bibliothek (Struktur-Fingerabdruck, höchstens 200 Einträge, je Anfrage einmal gelesen), nur mit Bibliothekszugang (Gruppe nicht deaktiviert, Recht „Divi-Bibliothek“; P13) und nicht bei `lit/library-insert` selbst (Etappe 3b, E11).
Kurzform setzt Admin-Labels automatisch (`<Abschnitt> – <Modul>`), sofern nicht angegeben.
@@ -238,7 +238,7 @@ Kurzform setzt Admin-Labels automatisch (`<Abschnitt> – <Modul>`), sofern nich
1. Rechte prüfen (`edit_post`), `tree_rev` prüfen.
2. Änderung auf dem BlockTree ausführen, validieren (alles oder nichts).
3. Serialisieren, `wp_slash()`, `wp_update_post()` – Status unverändert, vorher Wiederherstellungspunkt (Revision). Für Benutzer ohne `unfiltered_html` wird kses für genau diesen Aufruf abgeschaltet: `filter_block_content()` würde sonst jeden unveränderten Block neu serialisieren (Byte-Identität, globale Module; in DDEV nachgewiesen). Das ist nur vertretbar, weil keine client-gelieferte Zeichenkette ungeprüft in `post_content` gelangt (D7): Klartext-Werte werden je Feldtyp bereinigt (Text: `sanitize_text_field`; Rich-Text: `wp_kses_post`, abhängig von `unfiltered_html`; URLs: `esc_url_raw`, geroutet über die Attribut-Metadaten des Katalogs, ersatzweise über den Schlüsselnamen). Werte mit `$variable(...)$` – ob aus Platzhaltern erzeugt oder unverändert aus `lit/divi-node-get` zurückgegeben – werden geparst, streng geprüft (zulässiger Typ, existierende gcid-/gvid-/Dynamic-Content-Quellennamen, whitelisted Settings-Schlüssel, String-Settings bereinigt) und vom Plugin neu serialisiert; alles andere wird mit `validation_failed` abgelehnt. Ob Divi das Dynamic-Content-`before`/`after` bei der Ausgabe selbst escaped, wird in Etappe 2b im Divi-Quellcode verifiziert; die Bereinigung gilt unabhängig davon (Verteidigung in der Tiefe, R2).
4. Post-Meta `_et_pb_use_divi_5=on`, `_et_pb_use_builder=on` setzen.
4. Post-Meta `_et_pb_use_divi_5=on`, `_et_pb_use_builder=on` setzen (Seiten und Theme-Builder-Layouts; Bibliothekseinträge nicht).
5. `ET_Core_PageResource::remove_static_resources($post_id, 'all', true)`; bei globalen Library-Elementen und Theme-Builder-Änderungen `('all', 'all', true)` sowie `et_theme_builder_clear_wp_cache('all')`.
6. Protokolleintrag, `ToolResult` zurückgeben.
@@ -262,11 +262,12 @@ Kurzform setzt Admin-Labels automatisch (`<Abschnitt> – <Modul>`), sofern nich
| `lit/library-save` | schreiben | Knoten als Library-Eintrag speichern (normal oder global; global braucht Divis „Globale Bibliothekselemente bearbeiten“, P7); Knoten auf der Seite bleibt unverändert; StoredNodeGuard (E6) |
| `lit/library-insert` | schreiben | Library-Eintrag als Kopie oder globale Instanz im Format des Visual Builders (`localAttrs`-Schnappschuss, `globalParent`) einfügen; direkt |
| `lit/divi-node-copy` | schreiben | Knoten von Eintrag A nach Eintrag B kopieren (Seiten und Bibliothekseinträge; byte-gleich, `source_tree_rev` Pflicht, S7/S26-Prüfung E6) |
| `lit/library-make-global` | schreiben | Knoten in globales Modul umwandeln; optional gleichartige Vorkommen ersetzen |
| `lit/library-find-similar` | lesen | ähnliche Abschnitte seitenübergreifend (Struktur-Fingerabdruck: Modultypen, Aufbau, Presets) |
| `lit/tb-list` | lesen | Vorlagen, Bedingungen, Layouts |
| `lit/tb-create-template` | schreiben | Vorlage mit Header/Body/Footer-Layouts anlegen (`et_theme_builder_insert_layout`, `et_theme_builder_store_template`, Meta `_et_template`) |
| `lit/tb-assign` | schreiben | Bedingungen (`_et_use_on`/`_et_exclude_from`, z. B. `singular:post_type:person:all`) setzen |
| `lit/library-make-global` | schreiben | Knoten in globales Modul umwandeln (alles oder nichts); optional gleichartige Vorkommen ersetzen: gleichartig = inhaltsgleich einschließlich aller Texte (Inhalts-Fingerabdruck und normalisierte Bytes), `library_id` + `targets`, Probelauf + `confirm`, P8a, Revision je Seite; Seite N scheitert → vorherige bleiben ersetzt, Fehler nennt geänderte/gescheiterte/unveränderte Seiten (E10). Nur Inhaltstypen `page` und `post` – keine Bibliothekseinträge, keine Theme-Builder-Layouts, auch nicht als Quelle; Knoten mit Verweis auf einen Eintrag (jede Schreibweise) werden kein globales Modul |
| `lit/library-find-similar` | lesen | ähnliche Abschnitte seitenübergreifend (Struktur-Fingerabdruck: Modultypen, Aufbau, Presets) und Inhalts-Fingerabdruck (`identical`); höchstens 200 Einträge je Aufruf, `cursor`, nur bearbeitbare Einträge, nie Bibliothekseinträge oder Theme-Builder-Layouts (E11) |
| `lit/tb-list` | lesen | Vorlagen, Bedingungen (Divis Beschriftungen, Objekte nur als ID), Layouts (`shared_with`), `template_rev`; `detached` = von einem veralteten Theme-Builder-Fenster entfernte Vorlagen; optional Divis Bedingungskatalog; nicht bearbeitbare Vorlagen fehlen, aktive nur als Anzahl |
| `lit/tb-create-template` | schreiben | Vorlage mit Header/Body/Footer-Layouts anlegen (`et_theme_builder_insert_layout`, `et_theme_builder_store_template`, Meta `_et_template`); immer deaktiviert (Antwort F1); je Bereich neu, global (Standardvorlage), leer oder ausgeblendet; alles oder nichts; abgelehnt, solange der Theme Builder einen Entwurf hat |
| `lit/tb-assign` | schreiben | Bedingungen (`_et_use_on`/`_et_exclude_from`, z. B. `singular:post_type:person:all`) setzen – nur Divis eigene, Objekte lesbar, Autoren nur mit `list_users`; aktive Vorlage nur nach Probelauf und `confirm`; `reattach` für vom Theme Builder entfernte Vorlagen (bleiben deaktiviert) |
| `lit/tb-activate` | schreiben | Vorlage aktivieren/deaktivieren – einzige Stelle, die eine Vorlage sichtbar macht; immer Probelauf, dann `confirm` (Antwort F1, Etappe 3b); Deaktivieren geht immer, auch bei Theme-Builder-Entwurf (mit Warnung) und im Papierkorb |
## 6. WordPress-Basis
@@ -403,6 +404,7 @@ Dynamisch pro Seite erzeugt (Server-Beschreibung → `instructions`), ca. 15 Zei
- Kernregeln: vor dem Schreiben `lit/divi-outline` und `lit/divi-design-system` lesen; Variablen/Presets vor festen Werten; native Module vor Code-Modul; Status nie ändern ohne ausdrücklichen Wunsch; immer `rev` (bei Divi-Änderungen `tree_rev`) mitgeben,
- Verweis auf `lit/guide`.
- Etappe 3a: Zeile „Divi-Bibliothek: …“ (globale Module im Bibliothekseintrag ändern, Probelauf und `confirm: true`, Guide `divi-library`), nur wenn die Gruppe „Divi-Bibliothek“ aktiv und beschreibbar ist.
- Etappe 3b: Zeile „Divi Theme Builder: …“ (neue Vorlagen deaktiviert, Aktivieren nur mit `lit/tb-activate`, Guide `theme-builder`), nur bei aktiver, beschreibbarer Gruppe „Divi Theme Builder“.
### 9.2 `lit/guide(topic)`
@@ -412,7 +414,7 @@ Themen: `overview`, `divi-structure`, `divi-shortform`, `divi-attrs`, `divi-plac
### 9.3 MCP-Prompts
`corporate-design-uebernehmen`, `neue-website-aufsetzen`, `seite-pruefen`, `globale-module-vorschlagen`, `custom-post-type-vorlage`.
(Stand Etappe 3a: noch keine MCP-Prompts im Plugin; `globale-module-vorschlagen` steht als Ablauf im Guide `divi-library`.)
(Stand Etappe 3b: noch keine MCP-Prompts im Plugin; `globale-module-vorschlagen` steht als Ablauf im Guide `divi-library`, `custom-post-type-vorlage` im Guide `theme-builder`.)
## 10. Sicherheit
@@ -466,7 +468,7 @@ Referenz: https://modelcontextprotocol.io/specification
| **0 – Anbindung testen** | Plugin-Gerüst, Composer, mcp-oauth + Adapter, Rollen-Gate, App-Password-Scope-Filter, eigener Server mit direkten Tools, `lit/guide` (overview), ein Test-Tool; claude.ai-Connector über `ddev share`/Staging; MCP Inspector; Test: The Events Calendar-Eintrag generisch anlegen | Entscheidung: mcp-oauth bleibt oder Wechsel zu mcp-connect; Events-Erweiterungspunkt nötig ja/nein |
| **1 – WordPress-Basis** | Schema-Erkennung inkl. Pods, Content-Tools, Status/Kopie/Austausch, Revisionen, Medien, Menüs, WP-Einstellungen, `ToolResult`, Protokoll, Einstellungsseite | Seiten/Beiträge/Pods-Einträge pflegen, Medien verwalten, Websites mit Struktur und Menü aufsetzen |
| **2 – Divi-Seiten** | BlockTree, Katalog, Kurz-/Vollform, Platzhalter, Outline/Insert/Update/Move/Delete/Duplicate/Replace, Warnungen, `page-render-summary`, Divi-Guides (umgesetzt in 2a: lesen, 2b: schreiben) | Divi-Seiten mit dem KI-Assistenten bauen und pflegen |
| **3 – Library & Theme Builder** | Library-Tools, Node-Copy, Make-Global, Find-Similar, Theme-Builder-Tools, Dynamic Content | CPT-Vorlagen bauen, globale Module einführen |
| **3 – Library & Theme Builder** | Library-Tools, Node-Copy, Make-Global, Find-Similar, Theme-Builder-Tools, Dynamic Content | CPT-Vorlagen bauen, globale Module einführen (3a Bibliothek, 3b Theme Builder und Konsolidierung) |
| **4 – Designsystem** | Farben, Variablen, Presets, Theme-Optionen inkl. SEO, Snapshots, Prompts | Corporate Design in einem Rutsch übernehmen |
| **U – Auslieferung & Updates** (nach Etappe 1) | **OFFEN – bewusst noch nicht spezifiziert.** Bekannt: Build mit `composer install --no-dev` (~3,3 MB vendor), Updates nur anzeigen (manueller Klick), `plugin-update-checker`; Hosting (Gitea / GitHub / eigene Subdomain mit `update.json`) und Signaturprüfung werden später entschieden | – |
@@ -491,6 +493,8 @@ Kann-Kriterien nach Etappe 4 oder bei freier Kapazität.
| `.well-known`/POST auf `/wp-json/` durch Hoster/WAF blockiert | Site-Health-Test, Fehlersuche-Doku |
| Design-Qualität neuer Abschnitte ohne Vorlagen | Library-first-Arbeitsweise, Designsystem-Platzhalter, Guides, Warnungen |
| Parallele Bearbeitung im Builder | `tree_rev`-Sperre |
| Veraltetes Theme-Builder-Fenster speichert und entfernt neue Vorlagen | Ablehnung bei Theme-Builder-Entwurf, `detached` in `lit/tb-list`, `reattach` (deaktiviert); Warnung in jeder Anlege-Antwort (Etappe 3b) |
| Ungewöhnliche Schreibweisen globaler Verweise (P25), z. B. ein maskierter `divi/global-layout`-Block in einem Modulwert, den Divi in Shortcode-Modulen und WooCommerce-Textmodulen erneut auswertet | bekanntes Restrisiko, dokumentiert im Guide `divi-library`; braucht Bearbeitungsrechte auf der verweisenden Seite; `UsageMatcher` erkennt die übrigen Schreibweisen fail-closed |
| Datenformate Designsystem nur aus Code abgeleitet (lokal keine Daten) | vor Etappe 4 echte Daten im Builder anlegen und als Fixtures sichern |
## 15. Offene Punkte (in Etappen zu klären)
+40 -4
View File
@@ -4,7 +4,7 @@ Tags: mcp, ai, divi, pods, oauth
Requires at least: 6.9
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.4.0
Stable tag: 0.5.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -14,8 +14,9 @@ MCP-Server für WordPress, Divi 5 und Pods – mit OAuth für KI-Assistenten.
WP-LIT-MCP stellt einen MCP-Server bereit, über den ein KI-Assistent (ein MCP-fähiger Client mit OAuth) diese
Website pflegt: Inhalte aller Inhaltstypen inkl. Pods-Feldern, Status, Kopien, Revisionen, Menüs, freigegebene
WordPress-Einstellungen, die Mediathek sowie Divi-Seiten und die Divi-Bibliothek (auch globale Module). Jede Änderung läuft mit den Rechten des verbundenen
WordPress-Benutzers und wird protokolliert.
WordPress-Einstellungen, die Mediathek sowie Divi-Seiten, die Divi-Bibliothek (auch globale Module) und den
Divi Theme Builder. Jede Änderung läuft mit den Rechten des verbundenen WordPress-Benutzers und wird
protokolliert.
Einstellungen: Einstellungen → LIT MCP (Verbindung, Zugriff, Tools, Protokoll, Limits).
@@ -75,8 +76,23 @@ Einstellungen: Einstellungen → LIT MCP (Verbindung, Zugriff, Tools, Protokoll,
privaten oder geplanten Eintrag, der das Modul zeigt, nicht bearbeiten darf.
* Divis Rollen-Editor gilt zusätzlich zu den WordPress-Rechten: ohne „Divi-Bibliothek“, „In der Bibliothek
speichern“, „Aus der Bibliothek hinzufügen“ bzw. „Globale Bibliothekselemente bearbeiten“ lehnt LIT MCP ab.
* Divi Theme Builder: neue Vorlagen legt LIT MCP deaktiviert an (über Divis eigene Funktionen, mit Layouts für
Kopfzeile, Inhalt und Fußzeile); sichtbar werden sie nur über lit/tb-activate nach Probelauf und confirm.
Änderungen an Bedingungen aktiver Vorlagen und an Layouts, die Besucher sehen, verlangen ebenfalls Probelauf
und confirm (Layouts vorher mit Revision bzw. Sicherungskopie). Deaktivieren geht immer. Der Theme Builder
verlangt „Beiträge anderer bearbeiten“, „Design bearbeiten“ (edit_theme_options) und das Divi-Recht
„Theme Builder“; Vorlagen, die der Benutzer nicht bearbeiten darf, nennt LIT MCP nicht (aktive nur als
Anzahl). Solange der Theme Builder ungespeicherte Änderungen hat, ändert LIT MCP keine Vorlagen (außer
Deaktivieren). Speichert ein Theme-Builder-Fenster, das vor dem Anlegen geöffnet wurde, entfernt Divi die neue
Vorlage wieder; lit/tb-list zeigt sie dann unter detached.
* lit/library-make-global legt globale Einträge an und ersetzt inhaltsgleiche Vorkommen auf Seiten und
Beiträgen erst nach Probelauf und confirm, jede Seite mit eigener Revision; Theme-Builder-Layouts und
Bibliothekseinträge ändert es nicht.
* Ohne Zugang zur Divi-Bibliothek (Recht „Divi-Bibliothek“ oder Tools-Gruppe deaktiviert) nennt LIT MCP keine
Bibliotheks-IDs, auch nicht bei globalen Modulen auf Seiten.
* Interne Links über {{link:<ID>}} nutzen Divis eigenen dynamischen Inhalt „<Typ> Link“: die Adresse wird beim
Anzeigen ermittelt. Für Entwürfe und private Ziele zeigt Divi Besuchern nur ?page_id=<ID> (ohne Titel).
Dieselben Zielregeln gelten für die Vollform post_link_url_<Typ>; Bibliothekseinträge sind kein Linkziel.
* lit-site-status prüft, ob die von LIT MCP genutzten Divi-Funktionen vorhanden sind, und nennt nach einem
Divi-Update fehlende unter problems.
* Pods-Felder: Die Feldrechte von Pods gelten auch über LIT MCP. „Verborgen“ und für den Benutzer gesperrte
@@ -109,7 +125,11 @@ Es gibt keine allgemeine "Rückgängig"-Funktion; was sich wie zurücksetzen lä
lit/revision-restore. Beim seitenübergreifenden Ersetzen erhält jede geänderte Seite eine eigene Revision.
* Bibliothekseinträge: jede Änderung legt vorher eine Revision an (revision_id), bei abgeschalteten Revisionen
eine Sicherungskopie im Papierkorb (backup_id); zurück über WordPress (Eintrag der Divi-Bibliothek
bearbeiten → Revisionen). Neu angelegte Einträge (lit/library-save) in der Divi-Bibliothek löschen.
bearbeiten → Revisionen). Neu angelegte Einträge (lit/library-save, lit/library-make-global) in der
Divi-Bibliothek löschen; durch Instanzen ersetzte Knoten über die Revision der jeweiligen Seite zurückholen.
* Theme Builder: Vorlagen haben keine Revisionen. lit/tb-assign nennt die bisherigen Bedingungen (previous) und
schreibt sie ins Protokoll; lit/tb-activate schaltet zurück. Layouts erhalten wie Divi-Seiten eine Revision.
Neu angelegte Vorlagen und Layouts im Divi Theme Builder löschen.
* Original durch eine Kopie ersetzen (lit/post-replace-with-copy): vorher legt das Werkzeug eine Revision
und eine vollständige Sicherung des bisherigen Originals im Papierkorb an (backup_id in der Antwort) –
von dort in WordPress wiederherstellbar.
@@ -169,6 +189,22 @@ Bibliothekseintrags.
== Changelog ==
= 0.5.0 =
* Divi Theme Builder: Vorlagen, Bedingungen und Layouts auflisten (lit/tb-list), Vorlagen mit Kopfzeile,
Inhalt und Fußzeile anlegen – immer deaktiviert (lit/tb-create-template) –, Bedingungen setzen
(lit/tb-assign, auch vom Theme Builder entfernte Vorlagen wieder zuordnen), ausdrücklich aktivieren oder
deaktivieren (lit/tb-activate).
* Die Divi-Werkzeuge bearbeiten Theme-Builder-Layouts; sichtbare Layouts erst nach Probelauf und confirm.
Felder im Inhalt-Layout ({{field:…}} und im Divi-Builder gewählte Felder) werden gegen den Inhaltstyp der
Vorlage geprüft (nur Warnungen).
* Ähnliche Abschnitte finden (lit/library-find-similar); Knoten in globale Module umwandeln und
inhaltsgleiche Vorkommen ersetzen (lit/library-make-global); Divi-Änderungen weisen auf gleich aufgebaute
Abschnitte der Bibliothek hin.
* Tools-Gruppe „Divi Theme Builder“; lit-site-status prüft die genutzten Theme-Builder-Funktionen.
* Sicherheit: Bibliotheks-IDs bleiben ohne Bibliothekszugang verborgen; interne Links in der Vollform
(post_link_url_*) folgen denselben Zielregeln wie {{link:ID}}; globale Einträge enthalten keine Verweise auf
andere Einträge, in keiner Schreibweise.
= 0.4.0 =
* Divi-Bibliothek: Einträge auflisten und lesen (lit/library-list), Knoten als normalen oder globalen Eintrag
speichern (lit/library-save), als Kopie oder globale Instanz einfügen (lit-library-insert, direkt).
+13 -1
View File
@@ -19,6 +19,9 @@ final class InstructionsBuilder
/** Tool group of the Divi Library (LibraryAccess::GROUP); its rule needs a writable group. */
private const LIBRARY_GROUP = 'divi-library';
/** Tool group of the Divi Theme Builder (ThemeBuilderAccess::GROUP); its rule needs a writable group. */
private const THEME_BUILDER_GROUP = 'divi-theme-builder';
/** @var (callable(): list<string>)|null */
private $postTypeNames;
@@ -75,6 +78,15 @@ final class InstructionsBuilder
]
: [];
$themeBuilder = str_contains(', ' . $active . ',', ', ' . self::THEME_BUILDER_GROUP . ',')
&& $this->policy->groupWritable(self::THEME_BUILDER_GROUP)
? [
'- Divi Theme Builder: neue Vorlagen entstehen deaktiviert; aktivieren nur auf ausdrücklichen '
. 'Wunsch mit lit/tb-activate (Probelauf, dann confirm: true); '
. 'Ablauf: lit-guide topic "theme-builder".',
]
: [];
return implode("\n", array_merge($lines, [
'Regeln:',
'- Vor dem ersten Arbeitsschritt lit-guide (ohne Topic) aufrufen; Details je Thema über lit-guide '
@@ -86,6 +98,6 @@ final class InstructionsBuilder
'- Beim Bearbeiten immer den rev-Wert aus dem letzten Lesevorgang mitgeben (Pflicht).',
'- Löschen und Ersetzen erst nach Rückfrage beim Nutzer (confirm: true).',
'- Fehler enthalten einen hint – ihm folgen, statt blind zu wiederholen.',
], $divi, $library));
], $divi, $library, $themeBuilder));
}
}
+3 -2
View File
@@ -20,8 +20,9 @@ final class DiviSchema
],
'confirm' => [
'type' => 'boolean',
'description' => 'Bei globalen Bibliothekseinträgen (und beim Löschen): true erst, nachdem der Nutzer '
. 'den Probelauf (confirm_required mit den betroffenen Seiten) bestätigt hat.',
'description' => 'Bei globalen Bibliothekseinträgen, bei Theme-Builder-Layouts aktiver Vorlagen (und '
. 'beim Löschen): true erst, nachdem der Nutzer den Probelauf (confirm_required mit den '
. 'betroffenen Seiten bzw. Vorlagen) bestätigt hat.',
],
];
}
+1 -1
View File
@@ -45,7 +45,7 @@ defined('ABSPATH') || exit;
*/
final class Plugin
{
public const VERSION = '0.4.0';
public const VERSION = '0.5.0';
private static string $pluginFile = '';
private static ?SettingsPage $settingsPage = null;
@@ -104,6 +104,58 @@ final class InstructionsBuilderTest extends TestCase
}
}
private function themeBuilder(): Integration
{
$group = Mockery::mock(Integration::class);
$group->allows('id')->andReturn('divi-theme-builder');
$group->allows('isAvailable')->andReturn(true);
$activate = $this->ability('lit/tb-activate', false);
$activate->allows('annotations')->andReturn(['readonly' => false]);
$group->allows('abilities')->andReturn([$activate]);
return $group;
}
public function testAddsTheThemeBuilderRuleOnlyWhenItsGroupCanWrite(): void
{
$core = $this->coreWith($this->ability('lit/guide', true));
$registry = new IntegrationRegistry($core, $this->themeBuilder());
$with = (new InstructionsBuilder($registry))->build();
$without = (new InstructionsBuilder(new IntegrationRegistry($core)))->build();
self::assertStringContainsString('Divi Theme Builder: neue Vorlagen entstehen deaktiviert', $with);
self::assertStringContainsString('lit/tb-activate', $with);
self::assertStringContainsString('confirm: true', $with);
self::assertStringContainsString('topic "theme-builder"', $with);
self::assertStringNotContainsString('Divi Theme Builder:', $without);
self::assertLessThan(2000, strlen($with));
foreach ([['@readonly:divi-theme-builder' => true], ['@group:divi-theme-builder' => 'disabled']] as $settings) {
$policy = (new ExposurePolicy($settings))->withGroups($registry->groupMap());
$text = (new InstructionsBuilder($registry, null, $policy))->build();
self::assertStringNotContainsString('Divi Theme Builder:', $text, (string) json_encode($settings));
}
}
public function testAllRulesTogetherStayShort(): void
{
$divi = Mockery::mock(Integration::class);
$divi->allows('id')->andReturn('divi');
$divi->allows('isAvailable')->andReturn(true);
$divi->allows('abilities')->andReturn([$this->ability('lit/divi-outline', true)]);
$core = $this->coreWith($this->ability('lit/guide', true));
$registry = new IntegrationRegistry($core, $divi, $this->library(), $this->themeBuilder());
$text = (new InstructionsBuilder($registry, static fn (): array => ['page', 'post']))->build();
self::assertStringContainsString('Divi-Bibliothek:', $text);
self::assertStringContainsString('Divi Theme Builder:', $text);
self::assertLessThan(2000, strlen($text));
}
public function testListsPostTypesWhenAProviderIsGiven(): void
{
$core = $this->coreWith($this->ability('lit/guide', true));
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Pages;
use LIT\MCP\Integrations\Divi\Pages\DiviSchema;
use LIT\MCP\Tests\Unit\TestCase;
final class DiviSchemaTest extends TestCase
{
/** Ruling Q17 M2: confirm also applies to layouts of active Theme Builder templates. */
public function testTheConfirmDescriptionNamesEveryCaseThatNeedsADryRun(): void
{
$description = (string) DiviSchema::write()['confirm']['description'];
self::assertStringContainsString('globalen Bibliothekseinträgen', $description);
self::assertStringContainsString('Theme-Builder-Layouts aktiver Vorlagen', $description);
self::assertStringContainsString('Löschen', $description);
self::assertStringContainsString('confirm_required', $description);
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
/**
* Plugin Name: WP-LIT-MCP
* Description: MCP-Server für WordPress, Divi 5 und Pods – mit OAuth für KI-Assistenten.
* Version: 0.4.0
* Version: 0.5.0
* Requires at least: 6.9
* Requires PHP: 8.1
* Tested up to: 7.1