- Hints (PostPresenter::DIVI_NOTE, outline, catalog) and server instructions (tree_rev rule)
name the Divi write tools; guides divi-shortform and divi-placeholders, additions to
divi-structure, divi-attrs, overview (tool groups, 'nur lesen'), workflows, content-types.
- D7 wording and the S7 exception in readme, guides and spec 1.3/5.2; readme 0.3.0.
- ToolNamingTest: every referenced guide topic exists; overview lists exactly the topics.
- tests/Integration/divi-write-smoke.sh: all write tools via OAuth, editor without
unfiltered_html with benign probes (S6), Divi's own save filters on the new fixture
synthetic-divi-filters.html (S7); admin-render.php accepts the new wrap class.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
New input divi (1-30 sections, short form like lit-divi-insert) builds a Divi 5
layout in one divi/placeholder. The whole description is checked before the
insert (Divi's map for "no entry yet"); the draft is inserted with its normal
WordPress fields only, then DiviContentComposer composes again bound to the new
entry and stores it via DiviSaver::saveNew (same kses window as save(), strict
DiviFlags). A refusal or failure deletes the draft. Result adds tree_rev and the
outline.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
TextReplacer replaces only in plain-text segments (S8 split), outside
script/style bodies, inserts the replacement cleaned per field kind and
refuses any result whose tags, entities or references differ from the
original plus the inserted text. Unchanged strings are never cleaned.
Per page all or nothing with the tree_rev lock; Throwables are reported
per page (S10).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
DiviSaver/DiviWriter/DiviComposition/DiviChange, WpValueSanitizer (S4),
WpMediaResolver, DiviFlags (S11), DynamicContentMap from Divi's live
registry (S22), S31 wiring, S35 control strip at apply() entry.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
TreeEditor (position/insert/move/remove/duplicate on the BlockTree) and
Warnings (post-write quality checks), plus S18's outline breadth limit
on the 2a Outline/DiviOutlineAbility.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
- lit/divi-node-get now also returns the post-level rev (Rev::ofPost, same
optimistic lock lit-content-update needs) next to tree_rev, and reports a
node's type as the short name ("button"), matching lit-divi-outline instead
of the namespaced "divi/button". description() notes that $variable(...)$
values shown are re-validated when written, never taken over unchecked.
- lit/divi-outline validates its optional `id` input against the same
path-ID pattern lit-divi-node-get uses (a malformed id is now a validation
error, not a "not found"), and its outputSchema's per-node `required` list
now includes info/presets/children, which are always present.
- NodeSummary::label() (the admin label shown in outlines and node-get)
whitespace-normalizes and bounds its result via Text::shorten(), like every
other summary string, instead of returning a raw, unbounded value.
- docs/superpowers/notes/.../etappe-2a-abnahme.md corrected: only a global
module is "nur lesbar" - a specialty section is a normal, editable
divi/section block; the outline just marks it "[specialty]".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>