{"id":51540545,"url":"https://github.com/sandermuller/project-boost-laravel","last_synced_at":"2026-07-09T13:01:44.616Z","repository":{"id":360299573,"uuid":"1249526698","full_name":"SanderMuller/project-boost-laravel","owner":"SanderMuller","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-03T20:56:37.000Z","size":1573,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T22:13:34.736Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SanderMuller.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-25T19:49:55.000Z","updated_at":"2026-06-03T20:56:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SanderMuller/project-boost-laravel","commit_stats":null,"previous_names":["sandermuller/project-boost-laravel"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/SanderMuller/project-boost-laravel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderMuller%2Fproject-boost-laravel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderMuller%2Fproject-boost-laravel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderMuller%2Fproject-boost-laravel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderMuller%2Fproject-boost-laravel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SanderMuller","download_url":"https://codeload.github.com/SanderMuller/project-boost-laravel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderMuller%2Fproject-boost-laravel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35299763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-09T13:01:43.733Z","updated_at":"2026-07-09T13:01:44.601Z","avatar_url":"https://github.com/SanderMuller.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# project-boost-laravel\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/sandermuller/project-boost-laravel.svg?style=flat-square)](https://packagist.org/packages/sandermuller/project-boost-laravel)\n[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/sandermuller/project-boost-laravel/run-tests.yml?branch=main\u0026label=tests\u0026style=flat-square)](https://github.com/sandermuller/project-boost-laravel/actions/workflows/run-tests.yml)\n[![Total Downloads](https://img.shields.io/packagist/dt/sandermuller/project-boost-laravel.svg?style=flat-square)](https://packagist.org/packages/sandermuller/project-boost-laravel)\n[![License](https://img.shields.io/packagist/l/sandermuller/project-boost-laravel.svg?style=flat-square)](LICENSE)\n[![Laravel Boost](https://badge.laravel.cloud/boost-badge.svg?style=flat-square)](https://github.com/laravel/boost)\n\n\u003e The Laravel-app member of the [sandermuller boost family](#which-package-fits-your-role). Sits next to [`laravel/boost`](https://github.com/laravel/boost) in the same project. Boost keeps doing what it already does: MCP server, Laravel docs API, bundled Laravel skills. This package picks up everything else — fanning the generated agent files out across nine AI coding agents instead of four, and adding the family's filtering controls (`withTags()`, `withAllowedVendors()`, `withRemoteSkills()`, `boost where`).\n\n![overview image](overview.png)\n\nYou run Laravel Boost and this package together. Neither replaces the other; the design assumes they're installed side by side.\n\n## Which package fits your role?\n\n| You're building                          | Install                                                                                           | Ships                                                                                                |\n|------------------------------------------|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|\n| A PHP application (not a package)        | [`sandermuller/project-boost-php`](https://github.com/sandermuller/project-boost-php)             | App-dev skills: dependency injection, legacy coexistence + the `foundation` guideline                |\n| **A Laravel application**                | **[`sandermuller/project-boost-laravel`](https://github.com/sandermuller/project-boost-laravel)** | **`laravel/boost` MCP coexistence + nine-agent fanout + tag filter + remote skills  ← you are here** |\n| A framework-agnostic Composer package    | [`sandermuller/package-boost-php`](https://github.com/sandermuller/package-boost-php)             | Package-author skills + `lean` / `gitattributes` commands                                            |\n| A Laravel package                        | [`sandermuller/package-boost-laravel`](https://github.com/sandermuller/package-boost-laravel)     | Laravel-package skills + `McpJsonEmitter`                                                            |\n| Your own skill bundle, or custom tooling | [`sandermuller/boost-core`](https://github.com/sandermuller/boost-core)                           | The sync engine. You supply the skills.                                                              |\n\n## What this adds on top of `laravel/boost`\n\n|                                             | `laravel/boost` alone                   | + `project-boost-laravel`                                               |\n|---------------------------------------------|-----------------------------------------|-------------------------------------------------------------------------|\n| MCP server (`boost:mcp`)                    | ✅                                       | ✅ unchanged                                                             |\n| Laravel docs API + semantic search          | ✅                                       | ✅ unchanged                                                             |\n| Bundled Laravel skills + guidelines         | ✅                                       | ✅ re-rendered through this package's pipeline                           |\n| Tag filtering                               | —                                       | ✅ `withTags()`. Ship `inertia-vue-development` only on Inertia projects |\n| Remote skill sources                        | —                                       | ✅ `withRemoteSkills()`. Pull GitHub-published `.skill` bundles          |\n| Vendor allowlist                            | auto via `composer.json`                | ✅ explicit `withAllowedVendors()` for collision control                 |\n| `boost where` origin tracing                | —                                       | ✅ host / vendor / remote / shadow attribution                           |\n| `project-boost:where` injection-set tracing | —                                       | ✅ symmetric, for the `laravel/boost` skill set this package injects     |\n| User-scope sync                             | —                                       | ✅ `boost sync --scope=user` for globally-installed CLI tools            |\n| Doctor + path-repo audit                    | —                                       | ✅ `boost doctor --check-versions`                                       |\n\nUnder the hood, `project-boost:install` calls `boost:install --mcp` so laravel/boost writes its MCP client config the same way it always does, then `project-boost:sync` takes over for the nine-agent fan-out.\n\n## Install\n\n```bash\ncomposer require --dev sandermuller/project-boost-laravel\n```\n\n`laravel/boost` and `sandermuller/boost-core` come in transitively — do **not** require `sandermuller/boost-core` separately, it resolves through this package.\n\n## Where do the skills come from?\n\nAnywhere you want. Skill sources stack:\n\n- **Your own `.ai/skills/` folder**, hand-authored next to the rest of the project. Same convention `laravel/boost` uses, and `boost-core` picks them up automatically.\n- **A Composer-installed catalog package**. Any package that ships `resources/boost/skills/` works. I publish my personal catalog at [`sandermuller/boost-skills`](https://github.com/sandermuller/boost-skills) — adopt it if your preferences align with mine, or treat it as a template for your own. Private repo, public package, monorepo subfolder; Composer resolves all of them.\n- **External, non-Composer sources** via `withRemoteSkills()`. Pull GitHub-published `.skill` bundles or single-skill repos straight from the URL.\n- **`laravel/boost`'s bundled Laravel skills** plus whatever Laravel-aware third-party packages it knows about. Picked up through the injection seam this package adds.\n\nMix and match freely. `withAllowedVendors()` gates Composer-scanned vendors (source 2) only — host skills (source 1), remote skills (source 3), and the `laravel/boost` bundle (source 4) are not gated by it. `withTags()` filters sources 2, 3, and 4. Host skills (source 1) bypass both gates: your project authored them, so the engine treats them as canonical and applies neither filter.\n\n## First run\n\n```bash\nphp artisan project-boost:install\n```\n\nWhat the wrapper does:\n\n1. Runs `php artisan boost:install --mcp`. Boost writes its MCP client config; the `--mcp` flag keeps its `GuidelineWriter` and `SkillWriter` dormant, so this package owns the agent-file fan-out from here on.\n2. Runs `php artisan project-boost:sync`. Discovers laravel/boost-bundled skills and guidelines, renders Blade templates, applies your `withTags()` filter, fans out to every agent you declared in `boost.php`.\n\nIn CI / Docker / any non-TTY shell, the wrapper detects the absence of an interactive STDIN (`stream_isatty(STDIN)` plus the `--no-interaction` flag) and skips boost's install command entirely. It calls boost's `McpWriter` directly, once per agent in `boost.php`. No prompts, no integration multiselect, no crashes.\n\n\u003e [!WARNING]\n\u003e If you run `php artisan boost:install` **without** `--mcp`, boost's `GuidelineWriter` and `SkillWriter` fire and race this package over `CLAUDE.md` and the per-agent skill directories. Always go through `project-boost:install`, or pass `--mcp` explicitly. The `suppress_upstream_writers` flag below is the guardrail for muscle-memory mistakes.\n\n## `boost.php`\n\n\u003e **Config location.** boost-core resolves its config from `.config/boost.php`\n\u003e (canonical on boost-core ≥ 0.17) or a legacy root `boost.php` — this package's\n\u003e commands honor both. laravel/boost's own `boost.json` is a separate file that\n\u003e laravel/boost owns and resolves from the project root; it intentionally stays\n\u003e there and is not moved under `.config/`.\n\nMinimal:\n\n```php\nuse SanderMuller\\BoostCore\\Config\\BoostConfig;\nuse SanderMuller\\BoostCore\\Enums\\Agent;\nuse SanderMuller\\BoostCore\\Enums\\Tag;\n\nreturn BoostConfig::configure()\n    -\u003ewithAgents([Agent::CLAUDE_CODE, Agent::CURSOR, Agent::CODEX])\n    -\u003ewithTags([Tag::Laravel, Tag::Php]);\n```\n\nSkills are tag-gated. A skill ships if every tag in its `metadata.boost-tags` is also in your `withTags()`. Untagged skills always ship. `vendor/bin/boost tags` lists every tag your installed packages declare. For a worked example of how someone organizes a tag vocabulary across a catalog, see [`sandermuller/boost-skills`'s tag registry](https://github.com/sandermuller/boost-skills#tags).\n\nCommon shapes:\n\n| Project                  | Tags                                            |\n|--------------------------|-------------------------------------------------|\n| Laravel + Livewire       | `Tag::Laravel, Tag::Php, 'livewire'`            |\n| Laravel + Inertia React  | `Tag::Laravel, Tag::Php, 'frontend', 'inertia'` |\n| Laravel API only         | `Tag::Laravel, Tag::Php`                        |\n| + Pest 4 + browser tests | add `'pest'`                                    |\n\nSee the [`boost-core` README](https://github.com/sandermuller/boost-core) for the full `BoostConfig` surface.\n\n## Commands\n\n| Command                           | Does                                                                                                                                                                                                                                                                                                                                                  |\n|-----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `project-boost:install`           | Wraps `boost:install --mcp` (boost owns MCP) and runs `project-boost:sync`. Auto-detects non-TTY for CI / Docker. Recommended entry point.                                                                                                                                                                                                            |\n| `project-boost:install --no-sync` | MCP only; skip the sync.                                                                                                                                                                                                                                                                                                                              |\n| `project-boost:sync`              | Discover, render, tag-filter, fan out to nine agents. Run after `composer install` or after editing `boost.php`.                                                                                                                                                                                                                                      |\n| `project-boost:sync --dry-run`    | Preview the full sync pipeline (laravel/boost + host + scanned vendors + remote skills) in check mode. Requires `boost.php` or `.config/boost.php`.                                                                                                                                                                                                   |\n| `project-boost:where`             | List the laravel/boost-bundled skills and guidelines this package injects, with per-skill ship / tag-filter / shadow status. The companion to `vendor/bin/boost where`, which covers the host, scanned-vendor, and remote origins.                                                                                                                    |\n| `project-boost:reconcile`         | Capture laravel/boost-seeded guidance (the `\u003claravel-boost-guidelines\u003e` block `boost:install` writes into `CLAUDE.md` / `AGENTS.md`) into `.ai/guidelines/` before a sync would overwrite it, back up each file, then sync. Run once after a first `boost:install` or when migrating. See [docs/laravel-coexistence.md](docs/laravel-coexistence.md). |\n\n## Coexistence with `laravel/boost`\n\n| Concern                                                                     | Owner                                                                                |\n|-----------------------------------------------------------------------------|--------------------------------------------------------------------------------------|\n| MCP server (`boost:mcp` artisan command, `boost:install` MCP config writes) | **`laravel/boost`**                                                                  |\n| MCP config files (`.mcp.json`, `.amp/settings.json`, agent-specific)        | **`laravel/boost`**                                                                  |\n| Laravel docs API + semantic search                                          | **`laravel/boost`**                                                                  |\n| `CLAUDE.md` / `AGENTS.md` / `GEMINI.md` content                             | **this package** (via `boost-core`)                                                  |\n| `.{agent}/skills/\u003cname\u003e/SKILL.md` files                                     | **this package** (via `boost-core`)                                                  |\n| Skill content discovery + Blade rendering                                   | **this package** (`LaravelBoostAssetReader` + `BladeRenderer`)                       |\n| Versioned-variant resolution (e.g. `pest/3` vs `pest/4`)                    | **this package**. `Laravel\\Roster\\Roster::scan()` matches the host's installed major |\n| Tag filtering + collision resolution                                        | **`boost-core`**                                                                     |\n| Remote skill fetching (`withRemoteSkills`)                                  | **`boost-core`**                                                                     |\n\n**First-install takeover.** `boost:install` seeds its guidelines directly into your agent files inside a `\u003claravel-boost-guidelines\u003e` marker. If you have hand-edited those files, run `php artisan project-boost:reconcile` once before syncing — it captures your edits into `.ai/guidelines/` and backs the files up, so the (markerless, wholesale) sync never drops them. The full sequence and the data-loss mechanics are in [docs/laravel-coexistence.md](docs/laravel-coexistence.md).\n\nThings to avoid:\n\n- **A bare `vendor/bin/boost sync` on a wrapper project.** It bypasses this package's laravel/boost injection, assembles a smaller guidance set, and wholesale-overwrites your files with it. Always use `php artisan project-boost:sync`.\n- `php artisan boost:install` without `--mcp`. The interactive default re-engages boost's writers and races this package.\n- `php artisan boost:update`. Boost's bundled-asset refresh. Harmless but pointless; `project-boost:sync` re-renders on every run anyway.\n\n## Auto-sync on `composer install`\n\nIn Laravel projects using this package, wire `@php artisan project-boost:sync` into composer's post-install / post-update hooks:\n\n```jsonc\n{\n  \"scripts\": {\n    \"post-install-cmd\": [\"@php artisan project-boost:sync\"],\n    \"post-update-cmd\": [\"@php artisan project-boost:sync\"]\n  }\n}\n```\n\nThe `@php artisan project-boost:sync` hook routes through this package's wrapper, which walks `vendor/laravel/boost/.ai/`, pre-renders Blade templates with proper container context, and injects laravel/boost-bundled skills (`pest-testing`, `livewire-development`, `filament-development`, `inertia-development`, `eloquent-models`, and the rest) into the sync call. Without this hook, those bundled skills don't reach your agent directories — host skills + scanned vendors + remote skills still sync, but the laravel/boost set silently doesn't.\n\n### Why not `BoostAutoSync::run`?\n\n`boost-core` ships a `SanderMuller\\BoostCore\\Scripts\\BoostAutoSync::run` composer-script helper that invokes `vendor/bin/boost sync` (bare CLI). In Laravel projects using this package, that helper is the wrong hook: bare CLI bypasses this wrapper's injection pipeline entirely, so the laravel/boost-bundled skill set never reaches your agent directories. Operators who wire `BoostAutoSync::run` into their composer scripts typically don't notice — the bare-CLI sync still reports success, just against a smaller skill set than the wrapper would have surfaced. Use `@php artisan project-boost:sync` instead.\n\nA stray bare-CLI sync no longer *deletes* the wrapper's already-emitted skill files — the `BoostWrapper` contract (see [Architecture](#architecture)) declares them so the cleanup pass leaves them in place. But bare CLI still won't *(re)emit* the laravel/boost set, so `@php artisan project-boost:sync` remains the correct hook.\n\n(For non-Laravel projects consuming `boost-core` directly without a wrapper, `BoostAutoSync::run` IS the correct hook. The guidance above is Laravel-app-specific.)\n\n## Defensive flag: `suppress_upstream_writers`\n\nSet `PROJECT_BOOST_SUPPRESS_UPSTREAM=true` in `.env` to enable a `CommandStarting` listener that intercepts ad-hoc `php artisan boost:install` calls and injects `--mcp` before they run. Any truthy value works (`=true`, `=1`, `=yes`). Off by default — `project-boost:install` already does the right thing in both TTY and non-TTY modes, so the flag is belt-and-suspenders for teams worried about muscle-memory mistakes.\n\nNote: this does not suppress boost's integrations writers (cloud / sail / nightwatch). `--mcp` short-circuits feature selection only; the integrations multiselect still runs in TTY mode, and selecting one triggers its writer.\n\n## Remote skills\n\nDeclared in `boost.php` via `withRemoteSkills([RemoteSkillSource::githubBundle(...), RemoteSkillSource::githubPath(...)])`. The mechanism, cache behavior, `BOOST_GITHUB_TOKEN`, and `BOOST_REMOTE_STRICT` all live in [boost-core's README](https://github.com/sandermuller/boost-core#remote-skill-sources) — same surface in this package.\n\n## Architecture\n\n`LaravelBoostAssetReader` and `LaravelBoostGuidelineReader` walk `vendor/laravel/boost/.ai/`, render any `.blade.php` files through the package's `BladeRenderer` (which uses `laravel/boost`'s own `RendersBladeGuidelines` trait so `$assist` binds correctly), and hand the resulting `Skill[]` and `Guideline[]` to boost-core via `BoostSync::sync(injectedVendorSkills, injectedVendorGuidelines)`. From there it's boost-core's normal pipeline — tag filter, collision resolution, per-agent fan-out. See [boost-core's README](https://github.com/sandermuller/boost-core) for the engine internals.\n\nGuidelines are install-gated. `LaravelBoostGuidelineReader` emits only the core guidelines plus guidelines for packages the host actually installed, mirroring `laravel/boost`'s own `GuidelineComposer` detection (PHPUnit-vs-Pest priority, Sail opt-in, direct-only MCP / Livewire). An app never receives guidelines for packages it doesn't use — a Livewire + Filament + PHPUnit app won't get Inertia, Pest, or Sail guidance. Version-major sub-fragments are version-scoped too, on two axes: package dirs by exact installed major (a Laravel 12 app gets `laravel/12`, not `laravel/11` — they're alternative complete sets), and `php/8.x` cumulative-downward to your declared `require.php` floor (`php/8.4` features are usable on 8.5, so a project supporting `^8.3` keeps `≤8.3` and won't be told to use 8.5-only syntax it can't rely on).\n\nA `BoostWrapper` class implements boost-core's `BoostWrapperContract` (introduced in 0.11.0), declaring the per-agent skill-emit paths this package injects. A bare `vendor/bin/boost sync` (no wrapper injection) then preserves those files instead of flagging them stale-to-delete. Requires `boost-core ^1.0`.\n\nThis package's own semver-protected surface — the CLI commands, config keys, and behaviour it guarantees — is documented in [`PUBLIC_API.md`](PUBLIC_API.md). It exposes no `@api` PHP classes: it's an artisan/CLI-driven wrapper, so its public contract is the commands and config, not a class API.\n\n## Troubleshooting\n\n**`No boost config found (expected boost.php or .config/boost.php)`** — create one (see `boost.php` above; `.config/boost.php` is the canonical location on boost-core ≥ 0.17) or run `vendor/bin/boost install`.\n\n**`Errors during sync: ... listed more than once`** — `boost.php` declared a `withRemoteSkills` source whose skill name overlaps another source, or the laravel/boost asset reader produced two versioned variants of the same skill that didn't dedupe. The second case is a bug; please report.\n\n**`Errors during sync: ... also published by a scanned vendor`** — a package you allowlisted via `withAllowedVendors` publishes a skill colliding with one this package injects from laravel/boost. Either rename the vendor's skill or exclude it: `-\u003ewithExcludedSkills(['vendor/pkg:skill-name'])`.\n\n**Blade-templated skill output contains literal `@php` or `{{ ... }}`** — `BladeRenderer` didn't fire. Confirm `laravel/boost` is installed (`composer show laravel/boost`), and run the sync through **`php artisan project-boost:sync`**: that path auto-registers the renderer against a bootstrapped framework, so your `.ai/skills/\u003cname\u003e/SKILL.blade.php` and `.ai/guidelines/*.blade.php` render. Bare `vendor/bin/boost sync` can't render Blade — it never boots Laravel, so the renderer has no application context and fails fast with an actionable error. Use the artisan command for Blade-templated content.\n\n**`unchanged` for every file on a second sync** — that's expected. boost-core's `FileWriter` is content-aware.\n\n## Testing\n\n```bash\ncomposer test\n```\n\nPest suite. Unit tests for discovery, version resolution, and the suppress-upstream listener, plus Testbench-backed feature tests for `project-boost:install`'s TTY-vs-non-TTY branching.\n\n`.github/workflows/ci-smoke.yml` runs the end-to-end consumer install path on every push and PR. It spins up a fresh `laravel/laravel` app, installs this package from the checkout, runs `project-boost:install --no-sync --no-interaction` (asserts `.mcp.json` lands with the `laravel-boost` server entry), then `project-boost:sync` (asserts no Blade directives leak into rendered output).\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n## Credits\n\n- [Sander Muller](https://github.com/sandermuller)\n- [`laravel/boost`](https://github.com/laravel/boost) for the MCP server, the bundled Laravel skills, and the per-agent `McpWriter` this package reuses.\n- [`sandermuller/boost-core`](https://github.com/sandermuller/boost-core) for the sync engine this package extends.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandermuller%2Fproject-boost-laravel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsandermuller%2Fproject-boost-laravel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandermuller%2Fproject-boost-laravel/lists"}