Feature 066 — Block Tree Mutation & Nested Editing
Six new abilities plus one enhancement to update-post-block giving clients complete read/write control over the Gutenberg block tree inside a WordPress post, including nested blocks. All new abilities live under the existing acrossai-abilities-manager-content category and follow the same { success, <payload>, message } response shape as every other content ability.
New abilities
| Slug | Type | Purpose |
|---|---|---|
acrossai/get-post-blocks | read | Return a post's parsed block tree with each block annotated with its canonical integer-array path (e.g. [0, 2, 1] = 2nd grandchild of the 3rd child of the 1st top-level block) |
acrossai/add-block | write | Insert a new block at a parent_path + sibling index. Appends when the requested index exceeds the current sibling count |
acrossai/remove-block | write | Remove the block at a canonical path; returns the removed payload for undo / logging |
acrossai/duplicate-block | write | Deep-clone the block at a path (including all inner blocks) and insert the clone as the next sibling |
acrossai/move-block | write | Atomically move a block from from_path to to_parent_path + to_index. Refuses moves whose destination lies inside the source's own subtree (would create a cycle) |
acrossai/insert-pattern | write | Resolve a saved block pattern by slug across database, active theme, and installed plugins, then insert its constituent blocks at parent_path + index. Ambiguous slugs return multiple_locations so callers can disambiguate via source / theme_type / plugin_slug |
Enhanced
acrossai/update-post-block— accepts an optionalpathinput for nested addressing at any depth. Existing consumers usingblock_indexorblock_name+occurrencesee zero behaviour change — the path branch is a strict addition.
Shared infrastructure
includes/Abilities/Utilities/Block_Tree.php— centralises tree-path primitives (walk, get / insert / remove / replace / move, block-name and attribute-schema validation). Extracts what were previously private inline guards inUpdate_Post_Block::executeso all seven abilities share one authoritative implementation.
Security parity
Every write inherits the update-post-block capability model — manage_options + edit_posts globally, edit_post per-post, and the post-type whitelist blocking revision / nav_menu_item / custom_css / customize_changeset / oembed_cache / user_request. get-post-blocks uses read_post per-post instead of edit_post. Attribute-schema validation is soft-fail (warn but allow) when the block type is not registered so custom / third-party blocks remain authorable.
Quality
- 577 PHPUnit tests, 1365 assertions, 0 failures (82 new assertions across 8 new test files)
- PHPCS (WPCS strict): 0 errors
- PHPStan (level 8): 0 errors
- All 8 CI checks pass on PR #115