anomaly/addons-module
Addon management module for the Anomaly CMS built on Laravel. Browse, install, enable, disable, and organize modules, plugins, and themes from the admin panel, with support for addon discovery and lifecycle operations.
anomaly/addons-module is not a standalone Laravel package — it is a PyroCMS / Streams Platform module. It provides the addon inventory and management surface (modules, plugins, extensions, themes, field types) inside the control panel, plus the repository/collection plumbing behind it. If you are not on the Anomaly/Streams stack, there is nothing here for you.
Minimum steps:
anomaly/streams-platform) or PyroCMS installed — this module assumes its AddonServiceProvider, AddonManager, and control-panel middleware are present.composer require anomaly/addons-moduleconfig/app.php entry is needed. Verify it shows up in the admin addon listing after a cache clear./admin/addons (or the equivalent control-panel route your install registers) and confirm the tabbed listing renders.Where to look first:
src/AddonsModuleServiceProvider.php — the $provides / $type properties tell you exactly how the platform classifies and boots the module.src/Addon/ — repository, collection, and the command/presenter classes used by the listing.resources/ — the control-panel views and language files for the listing tables.First real use case: an audit pass. Open /admin/addons, confirm the version strings of every installed addon, and check which are enabled vs. merely present. That listing is the fastest way to answer "what is actually running in this Pyro build?" — which is the primary day-to-day value of this package.
Programmatic access to the collection. The listing is backed by the platform AddonManager, so anything the UI shows, you can pull in your own code:
use Anomaly\Streams\Platform\Addon\AddonManager;
$addons = app(AddonManager::class)->all(); // AddonCollection of everything
$modules = $addons->modules(); // filtered by type
$plugins = $addons->plugins();
$themes = $addons->themes();
Per-addon metadata is on the addon object itself — getName(), getTitle(), getDescription(), getVersion(), getType(), getSlug(), getNamespace(), getPath(), plus the enabled/installed flags. That is the contract most integrations actually need.
Deployment / CI gate. A small artisan command that iterates AddonManager::all(), asserts required modules are present and enabled, and non-zero-exits otherwise catches the classic "composer install succeeded but the addon was never registered" failure before a release.
Conditional bootstrapping. Rather than hardcoding slugs, ask the manager whether an addon exists before wiring optional behaviour:
if (app(AddonManager::class)->get('anomaly/foo-module')?->isEnabled()) {
// register the extra provider / route group
}
Custom admin screens. If you are building an internal panel that needs the same data, reuse the module's repository and table builder instead of re-scanning addons/ yourself. The table builders are already wired to the control-panel UI conventions (filters, columns, actions), so you get consistent presentation for free.
Reporting. A scheduled job that dumps name/version/type to a metrics table or Slack digest is a low-effort way to track drift between environments. The data is cheap to collect and hard to get otherwise.
composer require.$type, $provides) and its Composer manifest, not from the directory name alone. A mismatch between namespace/PSR-4 and the manifest produces an addon that lists with wrong metadata or fails to appear entirely.src/ end-to-end is faster than looking for docs — and if you need anything beyond the listing, writing your own thin wrapper over AddonManager is usually safer than extending this module.How can I help you explore Laravel packages today?