sandermuller / package-boost
AI-assisted development tooling for Laravel package developers
Requires
- php: ^8.2
- illuminate/console: ^11.0||^12.0||^13.0
- illuminate/support: ^11.0||^12.0||^13.0
Requires (Dev)
- driftingly/rector-laravel: ^2.2
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- orchestra/testbench: ^9.0||^10.0||^11.0
- pestphp/pest: ^3.0||^4.0
- pestphp/pest-plugin-arch: ^3.0||^4.0
- pestphp/pest-plugin-laravel: ^3.0||^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- rector/rector: ^2.0
- rector/type-perfect: ^2.1
- spaze/phpstan-disallowed-calls: ^4.6
- symplify/phpstan-extensions: ^12.0
- tomasvotruba/cognitive-complexity: ^1.0
- tomasvotruba/type-coverage: ^2.1
README
AI tooling for Laravel package developers. Bridges the gap between Laravel Boost (designed for applications) and package development with Orchestra Testbench.
What It Does
- Syncs
.ai/skills/to.claude/skills/and.github/skills/so Claude Code, GitHub Copilot, and Codex can use them - Syncs
.ai/guidelines/intoCLAUDE.md,AGENTS.md, and.github/copilot-instructions.md - Generates
.mcp.jsonpointing tovendor/bin/testbench boost:mcpwhen Boost is installed - Ships a
package-developmentskill that teaches AI agents how to work with Testbench
Installation
composer require sandermuller/package-boost --dev
Add the service provider to your testbench.yaml:
providers: - SanderMuller\PackageBoost\PackageBoostServiceProvider
Usage
1. Create your skills and guidelines
.ai/
├── guidelines/
│ └── my-conventions.md
└── skills/
└── my-skill/
└── SKILL.md
2. Sync to agent directories
vendor/bin/testbench package-boost:sync
3. Commit the generated files
The sync copies your .ai/ files to the directories each AI tool expects. Commit both the source (.ai/) and the generated files (.claude/, .github/, CLAUDE.md, AGENTS.md).
Selective sync
vendor/bin/testbench package-boost:sync --skills vendor/bin/testbench package-boost:sync --guidelines vendor/bin/testbench package-boost:sync --mcp
CI drift check
vendor/bin/testbench package-boost:sync --check
Reports planned actions without writing. Exits non-zero if any skill, guideline, or MCP target differs from its source. Use in CI to catch "forgot to sync" commits.
JSON output
vendor/bin/testbench package-boost:sync --check --format=json
Emits a structured JSON document on stdout — parseable by jq or programmatic consumers:
{
"schema": 1,
"check": true,
"drift": false,
"skills": { "new": [], "updated": [], "removed": [], "unchanged": 6 },
"guidelines": { "new": [], "updated": [], "removed": [], "unchanged": 3 },
"mcp": { "action": "unchanged", "target": ".mcp.json" }
}
Shape contract:
skillsandguidelinescarry{ new, updated, removed, unchanged }. Each non-unchanged array holds per-target entries with fields:target(string) — always present, relative to the package root.hint(string, optional) — advisory prose. For skills:"symlink → <relative target>"onupdatedactions. For guidelines:"+N lines"/"-N lines"/"content updated"onupdated/newactions. No hint onremovedorunchanged. Not a command-to-run; the fix for any drift ispackage-boost:syncwithout--check.line_delta(int, optional, guidelines only) — integer line difference of the target file between its current state and what the sync would write. Only the<package-boost-guidelines>block is rewritten, soline_deltais effectively the synced-region delta (file content outside the block is never touched).
mcpcarries{ action, target }— always a single object, never an array.actionis"new","updated", or"unchanged".skippedcategories report structurally:skills/guidelineswhen no sources are found:{ "skipped": "no-sources" }.mcpwhen Laravel Boost isn't installed:{ "action": "skipped", "reason": "laravel-boost-not-installed" }.
- Arrays are stable-sorted by
targetfor deterministic diffs across runs.
Example GitHub Actions step that fails the job and lists drifted targets:
- name: Check package-boost sync run: | report=$(vendor/bin/testbench package-boost:sync --check --format=json || true) drift=$(echo "$report" | jq -r '.drift') if [ "$drift" = "true" ]; then echo "::error::package-boost sync drift detected" echo "$report" | jq -r ' (.skills.new, .skills.updated, .skills.removed)[]?.target, (.guidelines.new, .guidelines.updated, .guidelines.removed)[]?.target, if .mcp.action == "new" or .mcp.action == "updated" then .mcp.target else empty end ' | sort -u | sed "s|^| - |" exit 1 fi
Pass --show-unchanged to turn the unchanged field from an int count into a full array of { target } entries.
Verbose output
vendor/bin/testbench package-boost:sync --show-unchanged
By default, the sync output lists only targets that changed and folds unchanged ones into the total: ... summary. Pass --show-unchanged to print a line per unchanged target as well.
Composer script
{
"scripts": {
"sync-ai": "vendor/bin/testbench package-boost:sync"
}
}
Composer auto-sync hook
Register package-boost:sync as a post-autoload-dump hook so
composer install / update / dump-autoload catch "forgot to
sync" mistakes automatically. Complements the --check CI gate: CI
catches stale generated files on the server, the hook catches them
on the contributor's machine.
Strict variant (recommended) — matches the CI contract. If
anything has drifted, the install fails and the contributor re-runs
package-boost:sync by hand:
{
"scripts": {
"post-autoload-dump": [
"@php vendor/bin/testbench package-boost:sync --check"
]
}
}
Auto-fix variant — friendlier but mutates the working tree when
drift exists, which leaves uncommitted changes behind after a fresh
composer install on a dirty branch:
{
"scripts": {
"post-autoload-dump": [
"@php vendor/bin/testbench package-boost:sync"
]
}
}
Boost-less packages — if the host doesn't depend on
laravel/boost, narrow the hook to skip MCP (otherwise it emits a
"Laravel Boost is not installed" warn on every composer run):
{
"scripts": {
"post-autoload-dump": [
"@php vendor/bin/testbench package-boost:sync --check --skills --guidelines"
]
}
}
The hook runs via /bin/sh on posix and cmd.exe on Windows;
single-command-per-array-entry form works on both. Chained shell
operators (&&, ||) are not portable across composer's shell
layers — use separate array entries if you need multiple steps.
With Laravel Boost
When laravel/boost is also installed as a dev dependency, you get:
- MCP server —
package-boost:sync --mcpgenerates the correct.mcp.jsonconfig - Doc search — Boost's
search-docstool works out of the box via Testbench - Shipped
package-developmentskill — ships viaresources/boost/skills/and is bundled into.claude/skills/and.github/skills/bypackage-boost:sync, so downstream agents always get it regardless of Boost version. - Package-tuned foundation — ships
resources/boost/guidelines/foundation.mdwith package-dev framing (Testbench harness, semver, public API discipline).package-boost:syncbundles it into the<package-boost-guidelines>block ahead of any user-authored.ai/guidelines/content, separated by a horizontal rule. - App-only guidelines stripped — defaults exclude
foundation(Boost's app-tuned version), Inertia, Livewire, Filament, Volt, Folio, Pennant, Wayfinder, Nightwatch, Pulse, Herd, Sail, Tailwind, Vite, deployments, andlaravel/style|api|localization
Customising excluded guidelines
Publish the config and edit config/package-boost.php:
vendor/bin/testbench vendor:publish --tag=package-boost-config
The excluded_boost_guidelines array is merged into boost.guidelines.exclude at boot. Keys match Boost's GuidelineComposer keys exactly (e.g. livewire/core, filament/v4, herd).
Vendor-contributed skills and guidelines
Installed Composer packages that ship
resources/boost/skills/<name>/SKILL.md or
resources/boost/guidelines/*.md are picked up automatically and
merged into the sync. Load order:
- Package-boost's shipped defaults
- Vendor packages (alphabetical by
vendor/name) - Host
.ai/
For skills, later entries override earlier ones on name
collisions — host .ai/skills/<name> always wins over a vendor
contribution of the same name. For guidelines, each source
contributes its own block and they concatenate in load order,
separated by ---.
Disable discovery entirely or skip specific packages via
config/package-boost.php:
'discover_vendor_packages' => true, 'excluded_vendor_packages' => [ 'sandermuller/package-boost', ],
How It Differs from Laravel Boost
| Laravel Boost | Package Boost | |
|---|---|---|
| For | Laravel applications | Laravel packages |
| Runs via | php artisan |
vendor/bin/testbench |
| Discovers skills | From app + vendor packages | From .ai/ + vendor/*/resources/boost/ |
| Generates guidelines | Composes from installed packages | Copies .ai/ + merges vendor contributions |
| MCP server | Built-in | Delegates to Boost when installed |
Changelog
See CHANGELOG.md for a per-release history. Entries are auto-generated from GitHub Releases.
License
MIT