AttributeLoader
Reads the ecosystem's second real metadata source — the `#[PluginMetadata]` attribute a plugin's main class carries — into a {@see VersionManifest}. The attribute's `provides`/`requires`/`suggests` are bare interface FQCN lists (it carries no version information), so they synthesize into exactly the same unversioned records the legacy manifest loader produces (`contractVersion 0.0.0` / `constraint *`), and its `type` — the only surface declaration available at the attribute level — rides through as `metadata['pluginType']`. The manifest is marked `metadata['shape'] = 'attribute'`. Following the metadataOf pattern of {@see \Milpa\Services\CapabilityGraphChecker}, a `PluginMetadata` record may also be handed in directly (via {@see fromMetadata()}) when it was already extracted and no reflection is needed.
AttributeLoader::fromClass()
public function fromClass(string $class): Milpa\Resolver\Manifest\VersionManifestReflect the `#[PluginMetadata]` off `$class` and build its manifest.
Parameters
| Name | Type | Description |
|---|---|---|
| $class | (class-string | string) |
Throws
InvalidManifestException When the class cannot be loaded or carries no `#[PluginMetadata]`.
AttributeLoader::fromMetadata()
public function fromMetadata(Milpa\Attributes\PluginMetadata $metadata): Milpa\Resolver\Manifest\VersionManifestBuild a manifest from an already-resolved `#[PluginMetadata]` record.
Parameters
| Name | Type | Description |
|---|---|---|
| $metadata | Milpa\Attributes\PluginMetadata |
Throws
InvalidManifestException When the metadata's name/version do not form a valid manifest.