Package Authoring
Capell treats package authoring as a platform surface, not a side effect of Laravel auto-discovery. A package should declare what it owns in capell.json, route runtime work through provider buckets, and keep public output safe for anonymous users and cached HTML.
Scaffold First
Section titled “Scaffold First”Use the existing capell:make-extension command to create new packages:
php artisan capell:make-extensionphp artisan capell:make-extension vendor/example --profile=minimal --path=packages --name="Example"php artisan capell:make-extension vendor/example-tools --profile=full --path=packages --premiumInteractive mode asks for the package name, scaffold profile, target directory, and display name when they are missing. Non-interactive scripts must pass package, --profile, and --path.
Profiles
Section titled “Profiles”minimal creates the smallest useful package:
- Composer metadata and PSR-4 autoloading.
- Manifest v3 with all provider buckets present and only the runtime bucket populated.
- A runtime provider extending
AbstractPackageServiceProvider. - Translations, README, and a manifest/public-cache safety test.
full creates live, harmless examples:
- Metadata, install, runtime, admin, and frontend providers.
- A package-owned console command.
- Settings registration with translated labels.
- A safe frontend render hook backed by an Action and Data object.
- Frontend asset registration.
- Tests for manifest validity, provider bucket shape, and unsafe public-output regressions.
Safety Rules
Section titled “Safety Rules”Public package output must not expose admin or editor details. Render hooks and Blade views should receive hydrated public state from Actions or view models, not query models directly. Cached HTML must remain safe to serve to anonymous visitors, signed-in users, admins, crawlers, and static exports.
Use the generated tests as the baseline, then add package-specific tests for settings, commands, admin surfaces, routes, migrations, and frontend rendering before release.
Lifecycle Actions
Section titled “Lifecycle Actions”Install, setup, and after-install work that can run from the web UI or Marketplace must be implemented as Actions, not nested Artisan commands. Add lifecycle classes that implement Capell\Core\Contracts\PackageLifecycleAction and declare them in capell.json:
{ "actions": { "install": "Vendor\\Example\\Actions\\InstallExamplePackageAction", "setup": "Vendor\\Example\\Actions\\SetupExamplePackageAction", "afterInstall": "Vendor\\Example\\Actions\\AfterInstallExamplePackageAction" }}Console commands may remain as thin CLI adapters for developers, but they should delegate to the same Action. Web-triggered lifecycle work will prefer these Actions and will not fall back to legacy commands.
Install In An App
Section titled “Install In An App”Require published packages normally:
composer require vendor/examplephp artisan optimize:clearphp artisan capell:package-cache:clearFor local development, point the app at a sibling package repository:
{ "repositories": [ { "type": "path", "url": "../capell-packages-4/packages/*", "options": { "symlink": true } } ]}Then require the package by Composer name:
composer require vendor/example:@devUse the wildcard path repository when one app should load several local packages. For one package only, this is enough:
composer config repositories.vendor-example path ../capell-packages-4/packages/examplecomposer require vendor/example:@devShare On Marketplace
Section titled “Share On Marketplace”Before sharing a package, tag a release, run package tests, and audit the manifest:
php artisan capell:extension-audit ../capell-packages-4/packages/exampleMarketplace-ready packages should have aligned composer.json and capell.json names, clear marketplace metadata, screenshots where useful, support notes in the README, and a normal Composer install path through Packagist, private Composer, VCS, or another configured repository.