PluginInspection
Mirar los plugins antes de tocarlos: si el grafo resuelve y en qué orden, qué pasaría al encender uno, si un manifiesto está íntegro, qué tiene actualización, y regenerar el archivo de bloqueo. ── POR QUÉ VIVE AQUÍ Y NO EN UN HOST ─────────────────────────────────────────────────────────── Porque todo lo que necesita ya vivía aquí: {@see MetadataGraphResolver} decide si el grafo ordena, {@see PluginManifest} si un manifiesto vale, {@see LockFileManager} escribe el bloqueo. Lo único que ponía el host era la lista de plugins activos —y este paquete la sabe armar desde su registry y la lista declarada, que es la misma que ya usa {@see PluginOperations}. Estas cinco nacieron en un host, donde funcionaban. El problema era el SIGUIENTE host: para poder preguntar si su grafo resuelve tendría que reescribirlas, y esa copia es la que después diverge. Un `composer create-project` las tiene sin escribir una línea. ── NINGUNA ADJUDICA POR SU CUENTA ────────────────────────────────────────────────────────────── Llama y reporta. Un inspector que volviera a decidir sería una segunda autoridad diciendo lo mismo —peor, y más tarde— sobre lo que el resolver y el manifiesto ya decidieron.
PluginInspection::__construct()
public function __construct(Milpa\Plugin\Contracts\PluginRegistryInterface $registry, array $declared = [], ?string $root = null, ?Milpa\Interfaces\Plugin\PluginInstallerInterface $installer = null, ?Milpa\Plugin\Contracts\ActivationSafetyInterface $safety = null, Milpa\Services\CapabilityMatcher $matcher = new CapabilityMatcher(), ?Milpa\Plugin\Contracts\StateBaselineInterface $baseline = null):Parameters
| Name | Type | Description |
|---|---|---|
| $registry | Milpa\Plugin\Contracts\PluginRegistryInterface | |
| $declared | list<class-string> | las clases que el host declara en código |
| $root | (string | null) | la raíz de la app; sin ella no se pueden leer manifiestos ni escribir `milpa.lock`, y las operaciones que lo necesitan no se ofrecen |
| $installer | ?Milpa\Interfaces\Plugin\PluginInstallerInterface | |
| $safety | ?Milpa\Plugin\Contracts\ActivationSafetyInterface | |
| $matcher | Milpa\Services\CapabilityMatcher | |
| $baseline | ?Milpa\Plugin\Contracts\StateBaselineInterface |
PluginInspection::deps()
public function deps(array $input): array¿El grafo de plugins activos resuelve, y en qué orden arrancarían? El orden ES el dato, no presentación: es la secuencia en que el runtime los va a arrancar, y quien provee algo tiene que ir antes que quien lo requiere.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |
PluginInspection::architecture()
public function architecture(array $input): arrayEl grafo de esta app como DATO: qué capacidades hay, quién provee cada una, quién la pide, cuál falta, y qué se rompería si apagas cada plugin (P17.2). ── POR QUÉ NO ALCANZABA CON `deps` ───────────────────────────────────────────────────────── `deps` contesta en qué ORDEN arrancan, que es una pregunta de arranque. Las que se hacen cuando alguien —o algo— quiere OPERAR el sistema son otras: «¿quién usa `database`?», «¿qué se cae si apago esto?», «¿qué capacidad quedó sin dueño?». Todas se derivan del mismo grafo y ninguna se podía contestar sin leer plugin por plugin y cruzar a mano. El índice INVERSO es la mitad que faltaba. Un agente que sólo ve «cada plugin declara esto» tiene que reconstruir «quién depende de qué» en su cabeza, en cada vuelta y sin poder verificarlo. Cruzarlo aquí cuesta un bucle y se calcula una vez. ── EL IMPACTO SE PREGUNTA, NO SE INTENTA ─────────────────────────────────────────────────── `blockingReasonWithout()` existía y sólo se alcanzaba al NEGAR un `plugins.disable` — o sea que la única forma de saber qué se rompía era intentar romperlo. Preguntar antes de causar es la misma distinción que separa `simulate` de `enable`.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |
PluginInspection::simulate()
public function simulate(array $input): array¿Qué pasaría si se encendiera este plugin? Resuelve el grafo con el candidato adentro SIN encender nada: es la forma de preguntar antes de causar, y la que una superficie de agente debería usar antes de `plugins.enable`.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |
PluginInspection::verify()
public function verify(array $input): array¿El manifiesto existe, es válido, y coincide con lo que el atributo declara? Las tres preguntas se reportan por separado: colapsarlas en un `ok` obligaría a correr algo más para saber cuál de las tres falló. Que NO haya manifiesto tampoco es una falla —un plugin puede vivir sólo con su atributo—, así que se dice y ya.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |
PluginInspection::outdated()
public function outdated(array $input): arrayQué plugins remotos tienen una versión más nueva disponible. ── UNA LIMITACIÓN QUE SE HEREDA, DICHA ───────────────────────────────────────────────────── El instalador SALTA en silencio una fuente que no contestó. Así que «ninguno desfasado» puede significar «ninguno» o «no pude preguntar», y desde aquí no se distinguen: se reporta `checked` para que el conteo al menos lo insinúe. El arreglo pertenece al instalador.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |
PluginInspection::lock()
public function lock(array $input): arrayRegenera `milpa.lock` desde lo que el registry dice que está instalado.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |
PluginInspection::active()
public function active(): arrayLos plugins que ARRANCAN, con lo que cada uno declara. Instalado y habilitado son dos condiciones y no la misma: uno instalado pero apagado existe en disco y no arranca, así que incluirlo diría que sus capacidades están disponibles cuando no.
PluginInspection::metadata()
public function metadata(string $clase): arrayLo que un plugin DECLARA en su atributo.
Parameters
| Name | Type | Description |
|---|---|---|
| $clase | class-string |
Throws
\RuntimeException si la clase no declara `#[PluginMetadata]`
PluginInspection::classOf()
public function classOf(string $nombre): ?stringLa clase de un plugin por su nombre corto, entre lo declarado y lo instalado. A diferencia de un host, este paquete NO escanea disco: no sabe cómo cada app acomoda sus plugins. Busca entre las clases que el host declaró y, si no, prueba la convención `Milpa\Plugins\<Nombre>\<Nombre>` que usa el instalador al desempacar.
Parameters
| Name | Type | Description |
|---|---|---|
| $nombre | string |
PluginInspection::hasRoot()
public function hasRoot(): boolSi esta instancia puede leer manifiestos y escribir el archivo de bloqueo.