Package Checklist
Use Extension examples when you need concrete snippets for admin bridges, settings, frontend hooks, Tailwind assets, and cache invalidation.
Use this checklist when creating or reviewing a Capell package.
Required
Section titled “Required”composer.jsonhas the package name, PSR-4 namespace, and Laravel provider discovery.capell.jsonuses manifest v3 and hasmanifest-version,name,slug,displayName,kind,capellApiVersion,version,surfaces,dependencies, andproviders.- Every PHP file has
declare(strict_types=1);. - User-facing strings are translated.
- Domain logic lives in Actions.
- Boundary state uses Data objects.
- Providers are split by runtime context when the package touches multiple surfaces.
- Package metadata comes from
capell.json; provider-sideCapellCore::registerPackage()is only for trusted first-party bootstrap or compatibility paths. - Admin pages/resources/widgets register through
AdminBridge/AdminBridgeRegistrar, or directCapellAdmin::contributeToAdminSurface(...)for small one-off surfaces. - Settings classes and settings schemas are registered through
SettingsSchemaRegistry. - Frontend renderers register stable component keys through
FrontendComponentRegistryInterface; saved content does not depend on package Blade namespaces. - Migrations and settings migrations are idempotent.
- Tests cover provider registration, Actions, and any Filament page access.
Before Release
Section titled “Before Release”- Run package-focused Pest tests.
- Run the sibling repo test suite.
- Run
composer lint. - Run
composer analyze. - Confirm package docs and README match the installed commands.
- Confirm sibling package integrations use the right manifest relationship:
dependencies.requiresfor hard requirements,dependencies.supportsfor support packages that are auto-added when applicable, andvisibility: supportfor packages that should not appear as standalone catalogue choices. - Confirm
class_exists()is not used as the only availability check for optional Capell packages. - Confirm frontend requests do not boot admin-only providers.
Optional Capell Packages
Section titled “Optional Capell Packages”Composer availability and Capell extension availability are different states. A package class can autoload while the extension is not installed, disabled, or missing its tables. class_exists() only proves Composer can load the class; it does not prove capell:extension-install and migrations have completed.
Do not gate Capell package queries, models, Blade components, Filament fields, listeners, or Actions with class_exists() alone:
if (class_exists(Navigation::class)) { Navigation::query()->first();}Use CapellCore::isPackageInstalled() before touching package runtime behavior:
if (CapellCore::isPackageInstalled('capell-app/navigation') && class_exists(Navigation::class)) { Navigation::query()->first();}For optional database-backed integrations, make the installed-state check the first gate. Add a schema check when code can run during install, upgrade, diagnostics, or another partial-migration state:
if ( CapellCore::isPackageInstalled('capell-app/navigation') && Schema::hasTable('navigations') && class_exists(Navigation::class)) { Navigation::query()->first();}class_exists() is still fine for non-Capell PHP/library capabilities, dynamic configured classes, autoload priming before cache deserialization, and defensive validation after the Capell package has already been proven installed.