chore: release 0.6.0 with Divi release gate, smoke test and acceptance notes

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 03:19:31 +02:00
co-authored by Claude Opus 5.5
parent 4b619d12e9
commit 35ea47d832
6 changed files with 151 additions and 3 deletions
+8
View File
@@ -62,3 +62,11 @@ Für den Einstieg liefert `lit-guide` mit dem Thema „all“ alle Themen in ein
- Fehler: JSON mit `code` (z. B. `validation_failed`, `rev_mismatch`, `write_failed`, `partial_write`),
`message`, `hint` (und ggf. `fields`). Dem `hint` folgen.
- `confirm_required`: Nutzer fragen, dann mit `confirm: true` wiederholen.
## Divi-Version nicht freigegeben
Antwortet ein schreibendes Divi-Werkzeug mit `divi_untested`, ist die installierte Divi-Version für LIT MCP noch nicht
geprüft; bei `divi_incompatible` hat Divi Stellen geändert, die LIT MCP nutzt. In beiden Fällen wurde nichts
geändert. Lesende Divi-Werkzeuge funktionieren weiter und melden den Zustand in `warnings`; `lit-site-status` zeigt
ihn unter `components` → `divi` → `release`. Den Nutzer bitten, unter Einstellungen → LIT MCP → Divi die Prüfung
auszuführen und die Version freizugeben (`divi_untested`) bzw. LIT MCP zu aktualisieren (`divi_incompatible`).
@@ -0,0 +1,15 @@
# Divi-Absicherung – manuelle Abnahme
Stand 2026-09-30, Branch `divi-absicherung`, Version 0.6.0.
1. Einstellungen → LIT MCP → Divi: Zustand „freigegeben – im Plugin als getestet hinterlegt“, Divi 5.2.1.
2. „Prüfung starten“: nach einigen Sekunden Hinweis „Divi-Prüfung abgeschlossen“, fünf ✓; unter Seiten keine
„[LIT MCP Prüfung]“-Seite, auch nicht im Papierkorb.
3. Ungetestete Version simulieren (nur lokal, nicht committen): in `src/Integrations/Divi/Release/DiviReleases.php`
`TESTED = []` setzen. Reiter zeigt „ungetestet“; ein MCP-Client bekommt beim Schreiben `divi_untested` mit dem
Hinweistext, beim Lesen den Hinweis in `warnings`.
4. „Prüfung starten“, dann „Divi 5.2.1 freigeben“: Zustand „freigegeben – auf dieser Website freigegeben am … von …“;
`lit-site-status` zeigt `release.source = database`; Protokoll zeigt den Eintrag `lit/divi-release`.
5. „Freigabe zurückziehen“: wieder „ungetestet“, Schreiben gesperrt, Protokoll-Eintrag. Danach `TESTED` zurücksetzen
(`git diff` leer).
6. Optional: eine vom Plugin geschriebene Seite im Visual Builder öffnen und speichern.
+12 -1
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.5.0
Stable tag: 0.6.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -190,8 +190,19 @@ Die Änderung wirkt auf allen Seiten mit diesem Modul. LIT MCP speichert erst na
betroffenen Seiten nennt, und einer ausdrücklichen Bestätigung (confirm); vorher entsteht eine Revision des
Bibliothekseintrags.
== Divi-Freigabe ==
LIT MCP schreibt nur mit Divi-Versionen, die für diese Plugin-Version geprüft sind. Nach einem Divi-Update lesen die Divi-Werkzeuge weiter; schreibende Divi-Werkzeuge antworten mit „divi_untested“, bis ein Administrator unter Einstellungen → LIT MCP → Divi die Prüfung startet und die Version freigibt. Die Prüfung legt eine Entwurfsseite an, schreibt und rendert sie und löscht sie danach endgültig. Hat Divi Stellen geändert, die LIT MCP nachbildet, ist die Version „inkompatibel“ (divi_incompatible) – dann hilft nur ein Update von LIT MCP. Für Entwickler: `wp --user=<admin> lit-mcp divi-check [--diff] [--update-reference]`.
== Changelog ==
= 0.6.0 =
* Divi-Absicherung: Divi-Zugriffe gebündelt in Adaptern mit Manifest; Fingerabdrücke der nachgebildeten Divi-Funktionen.
* Ungetestete oder veränderte Divi-Versionen sperren alle schreibenden Divi-Wege (divi_untested / divi_incompatible); lesende Divi-Werkzeuge melden es in warnings.
* Neuer Reiter „Divi“: Prüfung mit Wegwerfseite, Freigabe nach grüner Prüfung, Freigabe zurückziehen.
* lit-site-status zeigt den Freigabe-Zustand (release).
* WP-CLI: wp lit-mcp divi-check mit --diff und --update-reference.
= 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
+1 -1
View File
@@ -51,7 +51,7 @@ defined('ABSPATH') || exit;
*/
final class Plugin
{
public const VERSION = '0.5.0';
public const VERSION = '0.6.0';
private static string $pluginFile = '';
private static ?SettingsPage $settingsPage = null;
+114
View File
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
# End-to-end checks of the Divi release gate (spec 2026-09-29-divi-absicherung).
# Runs INSIDE the DDEV web container (Divi 5.2.1 must be the active theme):
# cd /home/janniclas/Projekte/WordPress && timeout 900 ddev exec bash wp-content/plugins/WP-LIT-MCP/tests/Integration/divi-release-smoke.sh
# Leaves nothing behind: pages, the check report, the check lock, the state transient and the application password
# are removed again.
set -euo pipefail
cd /var/www/html
# shellcheck source=lib.sh
source wp-content/plugins/WP-LIT-MCP/tests/Integration/lib.sh
ADMIN_LOGIN=$(wp user list --role=administrator --field=user_login | head -1)
CREATED_POSTS=()
BASE=http://localhost
cleanup() {
for id in "${CREATED_POSTS[@]}"; do
wp post delete "$id" --force >/dev/null 2>&1 || true
done
wp option delete lit_mcp_divi_check_report lit_mcp_divi_check_lock >/dev/null 2>&1 || true
wp transient delete lit_mcp_divi_state >/dev/null 2>&1 || true
cleanup_app_passwords_for "$ADMIN_LOGIN"
}
trap 'rc=$?; cleanup; guard_exit "$rc" || exit $?' EXIT
check_pages() { wp post list --post_type=page --post_status=any --meta_key=_lit_mcp_check_page --format=count; }
[ "$(wp eval 'echo get_template();')" = "Divi" ] || fail "Divi must be the active theme"
# 1. Code, registrations and fingerprints match Divi 5.2.1
[ "$(wp eval 'echo wp_json_encode((new LIT\MCP\Integrations\Divi\DiviCompatibility())->problems());')" = "[]" ] \
|| fail "Divi compatibility problems under WP-CLI"
pass "manifests and fingerprints match the installed Divi"
connect "$ADMIN_LOGIN"
STATUS=$(tool lit-site-status '{}')
echo "$STATUS" | jq -e '.components[] | select(.id == "divi") | .problems == [] and .release.state == "released" and .release.source == "code"' >/dev/null \
|| fail "site status must show Divi released from code: $STATUS"
pass "lit-site-status: Divi 5.2.1 released (code), no problems in an MCP request"
# 2. Admin check through the REST route (application password instead of the cookie nonce).
# X-Forwarded-Proto: https is required here: without it the request to http://localhost with the
# site's own Host header never reaches the route (a 404 before any auth check even runs), the same
# header mcp-smoke.sh and tb-smoke.sh already send for their own curl calls against this DDEV site.
APP_PASSWORD=$(wp user application-password create "$ADMIN_LOGIN" lit-mcp-integration-test --porcelain)
HEADERS=$(curl -s -o /dev/null -D - -X POST -H "Host: $HOST" -H 'X-Forwarded-Proto: https' -u "$ADMIN_LOGIN:$APP_PASSWORD" "$BASE/wp-json/lit-mcp/v1/divi-check")
echo "$HEADERS" | grep -qi '^HTTP/[0-9.]* 303' || fail "check route must answer 303: $HEADERS"
echo "$HEADERS" | grep -qi '^location:.*tab=divi.*lit_mcp_notice=divi_checked' || fail "redirect to the tab: $HEADERS"
REPORT=$(wp option get lit_mcp_divi_check_report --format=json)
echo "$REPORT" | jq -e '[.steps[] | (.problems == [] and .skipped == false)] | all and length == 5' >/dev/null \
|| fail "every check step must be green: $REPORT"
[ "$(check_pages)" = "0" ] || fail "the throwaway page must be gone"
[ "$(wp option get lit_mcp_divi_check_lock 2>/dev/null || true)" = "" ] || fail "the check lock must be released"
pass "admin check (REST): five green steps, throwaway page deleted, lock released"
UNAUTH=$(curl -s -o /dev/null -w '%{http_code}' -X POST -H "Host: $HOST" -H 'X-Forwarded-Proto: https' "$BASE/wp-json/lit-mcp/v1/divi-check")
[ "$UNAUTH" = "401" ] || [ "$UNAUTH" = "403" ] || fail "anonymous check must be refused, got $UNAUTH"
pass "check route refuses anonymous requests"
# 3. Incompatible Divi (simulated: a failed fingerprint in the state cache) locks every write path
wp eval '
$key = LIT\MCP\Integrations\Divi\Release\ReleaseResolver::stateKey((string) LIT\MCP\Integrations\Divi\Release\DiviEnvironment::version());
set_transient(LIT\MCP\Integrations\Divi\Release\ReleaseResolver::CACHE, ["key" => $key, "problems" => ["Smoke: Nachbau geändert"]], 600);'
PAGE_ID=$(wp --user="$ADMIN_LOGIN" post create --post_type=page --post_status=draft --post_title="LIT Freigabe Smoke" --porcelain)
CREATED_POSTS+=("$PAGE_ID")
wp post meta update "$PAGE_ID" _et_pb_use_builder on >/dev/null
wp post meta update "$PAGE_ID" _et_pb_use_divi_5 on >/dev/null
BEFORE=$(wp post get "$PAGE_ID" --field=post_content)
OUTLINE=$(tool lit-divi-outline "{\"post_id\":$PAGE_ID}")
echo "$OUTLINE" | jq -e '.warnings | any(test("inkompatibel"))' >/dev/null || fail "read tool must carry the notice: $OUTLINE"
pass "reading Divi tool runs and warns"
INSERT=$(tool lit-divi-insert "{\"post_id\":$PAGE_ID,\"tree_rev\":$(echo "$OUTLINE" | jq '.tree_rev'),\"nodes\":[{\"type\":\"section\",\"modules\":[{\"type\":\"text\",\"content\":\"<p>x</p>\"}]}]}")
echo "$INSERT" | jq -e '.__error | fromjson | .code == "divi_incompatible"' >/dev/null || fail "write must be refused: $INSERT"
[ "$(wp post get "$PAGE_ID" --field=post_content)" = "$BEFORE" ] || fail "nothing may be written"
pass "writing Divi tool refused with divi_incompatible, page unchanged"
CREATE=$(tool lit-content-create '{"post_type":"page","title":"LIT Freigabe Smoke Neu","divi":[{"type":"section","modules":[{"type":"text","content":"<p>x</p>"}]}]}')
echo "$CREATE" | jq -e '.__error | fromjson | .code == "divi_incompatible"' >/dev/null || fail "content-create with divi must be refused: $CREATE"
[ "$(wp post list --post_type=page --post_status=any --title='LIT Freigabe Smoke Neu' --format=count)" = "0" ] \
|| fail "no draft may remain"
pass "lit-content-create with divi refused before a draft exists"
STATUS=$(tool lit-site-status '{}')
echo "$STATUS" | jq -e '.components[] | select(.id == "divi") | .release.state == "incompatible"' >/dev/null \
|| fail "site status must show incompatible: $STATUS"
# wp db query --skip-column-names misreports this as a write query (it treats "insert" anywhere in the SQL,
# even inside a quoted value like 'lit/divi-insert', as an INSERT and prints "Rows affected" instead of the
# result) - wp eval with $wpdb->get_var() runs the same COUNT() reliably.
REFUSED_LOGGED=$(wp eval '
global $wpdb;
echo (int) $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}lit_mcp_log WHERE result = %s AND ability = %s",
"refused",
"lit/divi-insert"
));')
[ "$REFUSED_LOGGED" -ge 1 ] || fail "the refusal must be in the change log"
pass "site status incompatible, refusal logged"
# 4. Back to released: writes work again
wp transient delete lit_mcp_divi_state >/dev/null
OUTLINE=$(tool lit-divi-outline "{\"post_id\":$PAGE_ID}")
INSERT=$(tool lit-divi-insert "{\"post_id\":$PAGE_ID,\"tree_rev\":$(echo "$OUTLINE" | jq '.tree_rev'),\"nodes\":[{\"type\":\"section\",\"modules\":[{\"type\":\"text\",\"content\":\"<p>x</p>\"}]}]}")
echo "$INSERT" | jq -e '.ok == true' >/dev/null || fail "write must work when released: $INSERT"
pass "released again: writing works"
# 5. WP-CLI
wp --user="$ADMIN_LOGIN" lit-mcp divi-check >/dev/null || fail "wp lit-mcp divi-check must succeed"
[ "$(check_pages)" = "0" ] || fail "the CLI check must delete its page"
pass "wp lit-mcp divi-check is green and leaves no page"
finish
+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.5.0
* Version: 0.6.0
* Requires at least: 6.9
* Requires PHP: 8.1
* Tested up to: 7.1