feat: lit-site-status, Admin-Tab und Admin-Hinweis zeigen Divi-Fähigkeiten mit Zustand, Quelle, Problemen und betroffenen Werkzeugen
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
b92545a8fe
commit
2aef6e1154
@@ -6,31 +6,47 @@ namespace LIT\MCP\Integrations\Divi;
|
||||
|
||||
use LIT\MCP\Integrations\Core\EnvironmentComponent;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviEnvironment;
|
||||
use LIT\MCP\Integrations\Divi\Release\FeatureOverview;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseGate;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Divi in lit-site-status: version, the internals that are missing (DiviCompatibility) and the release status
|
||||
* (spec §5.5); inactive without problems and release when Divi is not the template.
|
||||
* Divi in lit-site-status: version, missing internals (DiviCompatibility), the release status and – per feature –
|
||||
* state, source, problems and the tools it affects (E3). The features come from the matrix the release gate
|
||||
* already holds (cached, D7), so a site-status call never recomputes the mirror fingerprints.
|
||||
*/
|
||||
final class DiviEnvironmentComponent implements EnvironmentComponent
|
||||
{
|
||||
public function __construct(private ?DiviCompatibility $compatibility = null)
|
||||
private FeatureOverview $overview;
|
||||
|
||||
public function __construct(private ?DiviCompatibility $compatibility = null, ?FeatureOverview $overview = null)
|
||||
{
|
||||
$this->overview = $overview ?? FeatureOverview::withoutTools();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{id: string, active: bool, version: ?string, problems: list<string>, release: ?array<string, mixed>,
|
||||
* features: list<array{id: string, label: string, state: string, source: ?string, problems: list<string>,
|
||||
* tools: list<string>}>}
|
||||
*/
|
||||
public function describe(): array
|
||||
{
|
||||
$version = DiviEnvironment::version();
|
||||
$active = $version !== null;
|
||||
if ($version === null) {
|
||||
return ['id' => 'divi', 'active' => false, 'version' => null, 'problems' => [], 'release' => null,
|
||||
'features' => []];
|
||||
}
|
||||
|
||||
$status = ReleaseGate::status();
|
||||
|
||||
return [
|
||||
'id' => 'divi',
|
||||
'active' => $active,
|
||||
'active' => true,
|
||||
'version' => $version,
|
||||
'problems' => $active ? ($this->compatibility ?? new DiviCompatibility())->problems() : [],
|
||||
'release' => $active ? ReleaseGate::status()->toArray() : null,
|
||||
'problems' => ($this->compatibility ?? new DiviCompatibility())->problems(),
|
||||
'release' => $status->toArray(),
|
||||
'features' => $this->overview->rows($status->matrix),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace LIT\MCP\Integrations\Divi;
|
||||
|
||||
use Closure;
|
||||
use LIT\MCP\Abilities\Ability;
|
||||
use LIT\MCP\Abilities\ToolAvailability;
|
||||
use LIT\MCP\Admin\DiviTab;
|
||||
use LIT\MCP\Admin\SettingsPage;
|
||||
@@ -55,6 +56,7 @@ use LIT\MCP\Integrations\Divi\Pages\DynamicContentMap;
|
||||
use LIT\MCP\Integrations\Divi\Release\CompatibilityCheck;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviCheckRoute;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseResolver;
|
||||
use LIT\MCP\Integrations\Divi\Release\FeatureOverview;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviCatalogAbility;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
|
||||
@@ -95,11 +97,14 @@ final class DiviIntegration implements Integration, Bootable
|
||||
* "Divi Theme Builder" gate their entries in the Divi tools (ruling P9, E9), lit/divi-insert gates
|
||||
* lit/divi-node-copy, lit-library-insert and content-create's divi input (audit M2), lit/library-insert
|
||||
* gates lit/divi-node-copy from a library entry (audit L5). null = no Tools tab: everything allowed.
|
||||
* @param (Closure(): list<Ability>)|null $allAbilities The abilities of every integration (Plugin passes
|
||||
* IntegrationRegistry::abilities()); the tools a Divi feature affects are found among them (E3).
|
||||
*/
|
||||
public function __construct(
|
||||
private ContentSchema $schema,
|
||||
private ChangeLog $log,
|
||||
private ?ToolAvailability $tools = null
|
||||
private ?ToolAvailability $tools = null,
|
||||
private ?Closure $allAbilities = null
|
||||
) {
|
||||
$this->modules = new DiviModules();
|
||||
$this->design = new DesignSystemReader();
|
||||
@@ -177,10 +182,16 @@ final class DiviIntegration implements Integration, Bootable
|
||||
return [new DiviLogoUsage()];
|
||||
}
|
||||
|
||||
/** Port for lit-site-status: Divi's version, missing internals and release status. */
|
||||
/** Which tools each Divi feature affects – for lit-site-status and the Divi tab (E3). */
|
||||
public function featureOverview(): FeatureOverview
|
||||
{
|
||||
return new FeatureOverview($this->allAbilities ?? static fn (): array => []);
|
||||
}
|
||||
|
||||
/** Port for lit-site-status: Divi's version, missing internals, release status and features. */
|
||||
public function environmentComponent(): EnvironmentComponent
|
||||
{
|
||||
return new DiviEnvironmentComponent();
|
||||
return new DiviEnvironmentComponent(overview: $this->featureOverview());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,7 +221,10 @@ final class DiviIntegration implements Integration, Bootable
|
||||
(new DiviCheckRoute($check))->register();
|
||||
DiviCheckCommand::register($check);
|
||||
|
||||
add_filter(SettingsPage::TABS_FILTER, fn (array $tabs): array => [...$tabs, new DiviTab(log: $this->log)]);
|
||||
add_filter(
|
||||
SettingsPage::TABS_FILTER,
|
||||
fn (array $tabs): array => [...$tabs, new DiviTab(log: $this->log, overview: $this->featureOverview())]
|
||||
);
|
||||
}
|
||||
|
||||
public function abilities(): array
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Release;
|
||||
|
||||
use Closure;
|
||||
use LIT\MCP\Abilities\Ability;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* The per-feature view shared by lit-site-status and the admin tab (E3): each row of the compatibility matrix plus
|
||||
* the tools that need the feature. Reads the matrix the release gate already holds (cached, D7) – nothing is
|
||||
* checked again here.
|
||||
*/
|
||||
final class FeatureOverview
|
||||
{
|
||||
/** @param Closure(): list<Ability> $abilities All registered abilities (IntegrationRegistry::abilities()). */
|
||||
public function __construct(private Closure $abilities)
|
||||
{
|
||||
}
|
||||
|
||||
/** An overview that knows no tools (tests, and a Divi tab built without a registry). */
|
||||
public static function withoutTools(): self
|
||||
{
|
||||
return new self(static fn (): array => []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tools whose diviFeatures([]) contain the feature, named as the MCP client sees them: direct tools
|
||||
* lit-<name>, indirect ones lit/<name>. A tool that needs a feature only for certain input (content-create
|
||||
* with divi) is not listed – its refusal names the feature.
|
||||
*
|
||||
* @return array<string, list<string>> Feature ID => tool names.
|
||||
*/
|
||||
public function toolsByFeature(): array
|
||||
{
|
||||
$map = [];
|
||||
foreach (($this->abilities)() as $ability) {
|
||||
if (! $ability instanceof RequiresDiviFeatures) {
|
||||
continue;
|
||||
}
|
||||
foreach ($ability->diviFeatures([]) as $feature) {
|
||||
$map[$feature->value][] = $ability->isDirect()
|
||||
? str_replace('/', '-', $ability->name())
|
||||
: $ability->name();
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{id: string, label: string, state: string, source: ?string, problems: list<string>,
|
||||
* tools: list<string>}>
|
||||
*/
|
||||
public function rows(CompatibilityMatrix $matrix): array
|
||||
{
|
||||
$tools = $this->toolsByFeature();
|
||||
|
||||
return array_map(
|
||||
static fn (array $row): array => $row + ['tools' => $tools[$row['id']] ?? []],
|
||||
$matrix->toArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user