feat: lit-divi-insert prüft Schleifen-Inhalte im Kontext des Ziels; neue Schleife plus Inhalt in einem Aufruf fail closed (X3)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-19 20:51:42 +02:00
co-authored by Claude Sonnet 5.5
parent 2f484b77ae
commit 249bc7b932
4 changed files with 254 additions and 4 deletions
@@ -6,6 +6,10 @@ namespace LIT\MCP\Integrations\Divi\Pages;
use LIT\MCP\Abilities\Ability;
use LIT\MCP\Abilities\ToolResult;
use LIT\MCP\Integrations\Divi\BlockTree\Block;
use LIT\MCP\Integrations\Divi\BlockTree\NodeIndex;
use LIT\MCP\Integrations\Divi\Compose\LoopContext;
use LIT\MCP\Integrations\Divi\Compose\LoopScope;
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
use LIT\MCP\Integrations\Divi\Release\FeatureSets;
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
@@ -114,4 +118,22 @@ abstract class DiviWriteAbility implements Ability, RequiresDiviFeatures
{
return null;
}
/**
* Ruling X3: the loop scope at $block – its nearest loop-enabled ancestor-or-self (LoopContext, X1); none at
* the top level. $newAttrs (node ID => attrs) replaces the stored attrs of nodes this call changes. The index
* is the tree loaded for this call, never a client value. Opaque blocks are never entered by NodeIndex, so one
* can only be $block itself – and every tool refuses to write into or onto it.
*
* @param array<string, array<string, mixed>> $newAttrs
*/
protected static function loopAt(NodeIndex $index, ?Block $block, array $newAttrs = []): LoopScope
{
$chain = [];
for ($node = $block; $node !== null; $node = $index->parentBlock($node)) {
array_unshift($chain, $newAttrs[(string) $index->idOf($node)] ?? $node->attrs());
}
return LoopContext::fromChain($chain);
}
}