jeffersongoncalves / laravel-package-cli
Scaffold new open-source Laravel packages with git already configured, built with Laravel Zero. Designed to be driven non-interactively (by an AI agent or a script) via arguments and flags.
Package info
github.com/jeffersongoncalves/laravel-package-cli
Type:project
pkg:composer/jeffersongoncalves/laravel-package-cli
Requires
- php: ^8.3
- jeffersongoncalves/laravel-zero-package-scaffold: ^1.0
Requires (Dev)
- jeffersongoncalves/laravel-zero-self-update: ^1.1
- laravel-zero/framework: ^13.0
- laravel/pint: ^1.25
- mockery/mockery: ^1.6
- pestphp/pest: ^3.8|^4.7
- phpstan/phpstan: ^2.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Laravel Package CLI
Scaffold new open-source Laravel packages with git already configured, built with Laravel Zero. Fully non-interactive — every input is an argument or a flag, so it's meant to be driven by an AI agent (e.g. Claude Code's laravel-package-creator skill) as much as by a human.
What it does
laravel-package create vendor/package "Description" generates the mechanical, repeatable part of a new Spatie-style Laravel package:
- Directory skeleton (
src/,config/,database/migrations/,resources/lang/{en,pt_BR}/,tests/,art/,.github/workflows/) composer.jsonwithspatie/laravel-package-tools, Pest, Larastan, Pint wired up- Service Provider (
PackageServiceProvider) and Facade stubs phpstan.neon.dist,phpunit.xml.dist,.editorconfig,.gitattributes,.gitignore,LICENSE.md,CHANGELOG.md,README.md- CI workflows:
tests.yml,pint.yml,phpstan.yml,update-changelog.yml git init, first commit onmain
It deliberately does not write the package's actual logic (Service Provider bindings, config values, README body, tests, banner) — that's judgment work left to whoever (human or agent) is building the package on top of this scaffold.
Requirements
- PHP 8.2+
- Git
Installation
composer global require jeffersongoncalves/laravel-package-cli
Or clone and build locally:
git clone https://github.com/jeffersongoncalves/laravel-package-cli.git
cd laravel-package-cli
composer install
php laravel-package app:build laravel-package
Usage
laravel-package create vendor/package [description] [options]
Arguments
| Argument | Required | Description |
|---|---|---|
vendor-package |
yes | vendor/package slug, e.g. jeffersongoncalves/laravel-cep. Split on / to derive vendor, package, namespace (Vendor\Package), Service Provider name, Facade name, and config/<package>.php filename. |
description |
no | Short one-line package description. Used in composer.json and the generated README.md. Defaults to empty string when omitted. |
Options
| Option | Description |
|---|---|
--path=DIR |
Target directory to scaffold into. Default: ./<package> under the current working directory. |
--namespace=NS |
PSR-4 root namespace override, e.g. "JeffersonGoncalves\PostHog". Its last segment also drives the Service Provider, Facade and README title. Defaults to <VendorRoot>\<StudlyName> (see below) — pass it whenever the name's casing isn't a plain studly of the slug (posthog → Posthog, never PostHog). |
--keywords=LIST |
Comma-separated composer.json keywords. Default: laravel,<package>. |
--require=LIST |
Extra runtime dependencies, comma-separated name:constraint. When any illuminate/* entry is given, the default illuminate/contracts is dropped so it isn't dragged in alongside. |
--author="Name" |
Author name for composer.json and LICENSE.md. Default: git config user.name, falling back to Jefferson Gonçalves if unset. |
--email=EMAIL |
Author email for composer.json. Default: git config user.email. |
--no-git |
Skip git init and the first commit — scaffold files only. |
--dry-run |
Print the planned file list (write vs. skip-if-exists) without writing anything or touching git. |
Every argument/option is designed for scripted, non-interactive invocation — no prompts are ever shown.
Examples
Basic package, everything defaulted (author/email from git config, written to ./laravel-cep):
laravel-package create jeffersongoncalves/laravel-cep "Brazilian CEP (postal code) lookup for Laravel"
No description (left blank in composer.json/README):
laravel-package create jeffersongoncalves/laravel-cep
Custom target directory:
laravel-package create jeffersongoncalves/laravel-cep "Brazilian CEP lookup for Laravel" --path=/d/PROJETOS/jeffersongoncalves/laravel-cep
Explicit author/email (overrides git config, e.g. CI or a different identity):
laravel-package create jeffersongoncalves/laravel-cep "Brazilian CEP lookup for Laravel" \ --author="Jefferson Gonçalves" \ --email=jeffersongoncalves@gmail.com
Namespace
The laravel- prefix is dropped, mirroring spatie/laravel-package-tools' shortName() — which is also what names the published config file.
| Package | Namespace | Classes | Config |
|---|---|---|---|
jeffersongoncalves/laravel-cep |
JeffersonGoncalves\Cep |
CepServiceProvider, Facades\Cep |
config/cep.php |
acme/laravel-widget |
Acme\Widget |
WidgetServiceProvider, Facades\Widget |
config/widget.php |
Both halves are studly-cased, which cannot see camel-case boundaries inside a single lowercase word (jeffersongoncalves → Jeffersongoncalves, posthog → Posthog). Teach it once in ~/.package/vendornamespace.json, shared with filament-plugin-cli:
{
"jeffersongoncalves": "JeffersonGoncalves",
"posthog": "PostHog"
}
With those two entries, jeffersongoncalves/laravel-posthog derives JeffersonGoncalves\PostHog (and PostHogServiceProvider, Facades\PostHog, config/posthog.php) with no flags at all. Lookups are per whole slug and case-insensitive; unlisted slugs fall back to studly. See laravel-zero-package-scaffold for the file's full contract.
--namespace remains for one-offs you don't want in the shared file.
Explicit namespace casing, keywords and dependencies (nothing the slug can reveal):
laravel-package create jeffersongoncalves/laravel-posthog "PHP/Laravel client for the PostHog API" \ --namespace="JeffersonGoncalves\PostHog" \ --keywords="laravel,posthog,analytics,feature-flags" \ --require="illuminate/http:^12.0|^13.0,illuminate/support:^12.0|^13.0"
Scaffold files only, no git repo (e.g. dropping into an already-initialized repo):
laravel-package create jeffersongoncalves/laravel-cep "Brazilian CEP lookup for Laravel" --no-git
Preview what would be created without writing anything:
laravel-package create jeffersongoncalves/laravel-cep "Brazilian CEP lookup for Laravel" --dry-run
Full invocation, all options combined:
laravel-package create jeffersongoncalves/laravel-cep "Brazilian CEP lookup for Laravel" \ --path=/d/PROJETOS/jeffersongoncalves/laravel-cep \ --namespace="JeffersonGoncalves\Cep" \ --keywords="laravel,cep,correios" \ --require="illuminate/http:^12.0|^13.0" \ --author="Jefferson Gonçalves" \ --email=jeffersongoncalves@gmail.com \ --no-git \ --dry-run
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Security
If you discover any security related issues, please see SECURITY.
Credits
License
The MIT License (MIT). Please see License File for more information.
