Reads, validates, and classifies a plugin's priv/mob_plugin.exs manifest.
The manifest is data, not code (see MOB_PLUGINS.md): a plain Elixir map
describing what a plugin contributes. This module is the single place that
turns that map into a validated, classified description — tier, hot-push
status, activation — that mix mob.plugins reports and the compile-time
merge will later consume.
A tier-0 plugin has no manifest at all; load/1 returns {:ok, nil} for
that case, and tier(nil) is 0.
Summary
Functions
Whether the plugin's contributions can be hot-pushed without a native rebuild.
Loads the manifest for a plugin checked out at plugin_dir.
Classifies the plugin tier (0–4) from which capability sections are present.
Validates a manifest map against the spec's required top-level fields.
Functions
@spec hot_pushable(map() | nil) :: true | false | :partial
Whether the plugin's contributions can be hot-pushed without a native rebuild.
Computed from populated sections, not from tier: true for pure-Elixir
plugins, false for native-only ones (NIFs / components), and :partial
when a plugin mixes native code with hot-pushable Elixir (screens, lifecycle).
Loads the manifest for a plugin checked out at plugin_dir.
Returns {:ok, nil} when there is no priv/mob_plugin.exs (a tier-0
plugin), {:ok, map} when one is present and evaluates to a map, or
{:error, reason} when the file is unreadable or doesn't yield a map.
Does not validate field contents — call validate/1 for that.
@spec tier(map() | nil) :: 0..4
Classifies the plugin tier (0–4) from which capability sections are present.
Highest matching section wins. nil (no manifest) is tier 0. A manifest
with required fields but no capability sections is the tier-1 floor (the
"minimum viable manifest").
Validates a manifest map against the spec's required top-level fields.
Returns {:ok, manifest} or {:error, reasons} with a list of every
problem found (validation never stops at the first error). nil (no
manifest) is valid — a tier-0 plugin has nothing to validate.