Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Package Boost Laravel Package

sandermuller/package-boost

Deprecated: sandermuller/package-boost is split into successors. Use package-boost-php for framework-agnostic Composer packages, package-boost-laravel for Laravel packages, or project-boost for PHP apps. Legacy 0.15.x remains for existing installs.

View on GitHub
Deep Wiki
Context7
0.15.0

Highlights

  • package-boost:doctor --fix. Runs package-boost:sync --prune --prune-orphans and package-boost:lean under the hood, then rebuilds the report from the post-fix state. Exit code is driven solely by the post-fix DoctorReport::hasIssues() — sync's prune refusal warns but exits 0, so doctor's rebuilt report is the single authoritative status source.
  • JSON fix outcome contract. With --fix --format=json, the payload gains an additive top-level fix object recording each category's attempted (what doctor saw pre-fix) and resolved (what actually changed). Refusals — for example sync declining to prune a Copilot file with user content — surface as { attempted: true, resolved: false }, distinguishable from a noop ({ attempted: false, resolved: false }). schema stays 1 (additive change).
  • Frontmatter blocking aligned with sync. DoctorReport::hasIssues() previously failed on any SKILL.md frontmatter issue, including third-party vendor packages the operator can't patch. It now mirrors SyncCommand::hasHostFrontmatterIssues: only issues under host .ai/skills/ or under package-boost's own bundled resources/boost/skills/ flip exit code. Third-party vendor issues remain rendered (as warnings) but exit-zero.
  • Legacy Copilot detection corrected. Doctor previously flagged any .github/copilot-instructions.md via bare file existence — including hand-authored Copilot files without the <package-boost-guidelines> tag, where sync --prune is a no-op. The flag now requires the tag, matching SyncCommand::warnAboutLegacyCopilotInstructions. Hand-authored Copilot files are no longer flagged.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.14.0...0.15.0

0.14.0

Three new commands round out the package-boost toolbelt: a one-shot doctor diagnostic, a managed-block .gitattributes writer (lean), and a frontmatter-aware skill/guideline scaffolder (new). sync gains --prune-orphans and a host-only SKILL.md frontmatter linter in --check. Internal classes move under Console\Internal\ so the public command surface is finally clearly demarcated.

Highlights

  • New package-boost:doctor command. Aggregates the checks that were previously scattered across sync --check, install, and the legacy / orphan warnings into a single report: configured + effective agents, sync drift counts, SKILL.md frontmatter issues, deselected-agent orphans, vendor skill collisions, MCP / Boost detection, the legacy Copilot file, and the .gitattributes managed block. Exits non-zero on any finding. --format=json emits a stable shape (schema: 1) parseable by jq.
  • New package-boost:lean command. Idempotently writes a managed # >>> package-boost (managed) >>> / # <<< package-boost (managed) <<< block into .gitattributes covering AI-era export-ignore paths (.ai/, .claude/, .cursor/, .agents/, .junie/, .kiro/, AGENTS.md, CLAUDE.md, GEMINI.md, …) so composer archive / Packagist --prefer-dist tarballs stay lean. User-authored entries outside the marker block are preserved verbatim. --check fails CI on drift. The shipped lean-dist skill teaches the validation side (stolt/lean-package-validator); this command handles the write side.
  • New package-boost:new command. Scaffolds .ai/skills/<name>/SKILL.md or .ai/guidelines/<name>.md with frontmatter pre-filled. Rejects collisions unless --force is passed, and validates the name against the same kebab-case shape (^[a-z][a-z0-9-]*$) the frontmatter linter enforces — a freshly scaffolded skill always passes package-boost:doctor without further edits.
  • sync --prune-orphans. Deletes generated artefacts for agents that fell out of package-boost.agents: skill dirs are removed wholesale (sync writes them in their entirety), guideline files have just the <package-boost-guidelines> block stripped (the file is deleted only when nothing but whitespace remains, so user-authored content outside the block is preserved), and .mcp.json has the laravel-boost entry removed when claude_code is deselected. Replaces the prior warn-only behaviour, which still ships as the default.
  • SKILL.md frontmatter linter in sync --check. Host-authored .ai/skills/<name>/SKILL.md files now fail --check when missing required frontmatter (name, description) or when name / directory disagree. Shipped and vendor skills surface the same issues as warnings only; CI catches host issues before they ship.
  • .gitattributes managed block in this repo. Now self-hosting package-boost:lean — the same managed block ships in this repository's .gitattributes. stolt/lean-package-validator is installed as a dev dep for archive validation.
  • Internal namespace move. BoostDetector, DeselectedAgentArtifacts, LegacyCopilotInstructions, SyncAction, SyncFormatter, SyncPlan, SyncReporter, SyncSources, SyncWriter, plus new DoctorReport, PackageRoot, SkillFrontmatter, and SyncPlanner, all move under SanderMuller\PackageBoost\Console\Internal\. They were already [@internal](https://github.com/internal) final readonly; the namespace move makes the boundary visible at a glance. Anything outside Console\Internal\ is the public surface.
  • Skill-dir consumption note in README. Calls out that today only Claude Code natively reads its skill dir as auto-activatable skills; the other eight agents primarily consume the per-agent guideline file. Skill dirs are written for forward compatibility so the same .ai/skills/ source becomes useful to each tool the moment it ships skill support — no re-author or re-sync required.

Removed

  • boost:update deprecated alias. Hidden, deprecated alias of package-boost:sync since 0.8.0. Anyone still invoking boost:update should switch to package-boost:sync; the previous release already emitted a deprecation warning on every invocation.

Upgrading

composer update sandermuller/package-boost
vendor/bin/testbench package-boost:sync
vendor/bin/testbench package-boost:lean
vendor/bin/testbench package-boost:doctor


Re-syncing rewrites the <package-boost-guidelines> block and skill dirs in every selected agent's directory. package-boost:lean writes the managed .gitattributes block (idempotent — safe to re-run). package-boost:doctor is a read-only diagnostic; run it to surface any remaining drift in one shot.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.13.0...0.14.0

0.13.0

Package-boost now treats every Composer package as in-scope, not just Laravel packages. The shipped foundation guideline no longer asserts "This codebase is a Laravel package" unconditionally — generated CLAUDE.md / AGENTS.md content is correct for framework-agnostic adopters from the first sync.

Highlights

  • Foundation rewritten with a marked Laravel section. Universally-true rules (no app/, semver discipline, tests-as-spec, public API discipline) are unconditional. Testbench / php artisan / laravel/boost guidance lives under ## If your package targets Laravel. After re-syncing, framework-agnostic packages stop seeing Laravel claims in their generated guideline files; Laravel-targeted packages keep all the Laravel guidance — it just lives below the new H2.
  • New ### Framework-agnostic packages README subsection. Walks through the verified Testbench-as-dev-dep recipe (composer require orchestra/testbench --dev, minimal testbench.yaml with laravel: '[@testbench](https://github.com/testbench)', run sync). Notes that .mcp.json generation is skipped automatically when laravel/boost isn't installed. Calls out the package-boost:install workbench-helpers requirement so framework-agnostic adopters don't hit a silent break after sync.
  • Console\BoostDetector (final readonly, [@internal](https://github.com/internal)). Extracts the Laravel-Boost-presence check used by MCP sync. The container-binding seam (package-boost.boost-detector) is honoured only while runningUnitTests() is true, so a stray service provider in a downstream app can't flip MCP sync on or off — production behaviour stays anchored to the package graph (class_exists(BoostServiceProvider::class, false)).
  • package-boost:install error message rewritten. When the workbench config path can't be resolved, the command now lists three concrete recovery paths (install Testbench + re-run via vendor/bin/testbench, skip install entirely and use the zero-config "all agents" default, or hand-edit workbench/config/package-boost.php) instead of a single bare "requires Orchestra Testbench" line.
  • Two new tests pinning the contract. A structural Pest test splits the synced block on the ## If your package targets Laravel marker and scans the framework-agnostic preamble for nine claim-shape patterns (is a laravel, targets laravel package, assume a laravel, …) — phrasing variants of the original bug class are rejected regardless of exact wording. A second test exercises the genuine laravel-boost-not-installed MCP-skip branch through the new detector seam, dodging the suite-wide stub provider that had been masking it.

Upgrading

composer update sandermuller/package-boost
vendor/bin/testbench package-boost:sync



Re-syncing rewrites the <package-boost-guidelines> block in every selected agent's guideline file with the new framework-neutral foundation. No code changes required — the upgrade is generated-output only.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.12.0...0.13.0

0.12.0

Highlights

  • New skill-authoring skill — teaches the four things models routinely get wrong on a new SKILL.md: namespacing to avoid silent collisions, frontmatter that actually triggers auto-activation, the .ai/skills/ vs resources/boost/skills/ source-dir choice, and the package-boost:sync regeneration step. Documents all three real collision modes (host masks vendor, vendor masks vendor, vendor masks package-boost default) so authors can reason about precedence without reading the sync code.
  • Vendor-vendor precedence pinned by test. Added a regression test that fixes the alphabetically-later vendor as the winner of a same-name collision, matching SyncSources behaviour. Prevents the shipped collision table from drifting from the code.
  • Internal ai-guidelines skill trimmed. Skill-authoring mechanics now defer to the new shipped skill; the trimmed version keeps only repo-specific dogfooding guidance and corrects the prior "commit generated files together" instruction (this repo gitignores them per release-automation).
  • README shipped-skill list reconciled. The Ships a … skill bullet list had silently fallen 3 entries behind resources/boost/skills/ci-matrix-troubleshooting, cross-version-laravel-support, and now skill-authoring — all added.

Upgrading

composer update sandermuller/package-boost
vendor/bin/testbench package-boost:sync




The first sync after upgrading writes the new skill-authoring skill to every selected agent's skill dir. Existing skills are unaffected.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.11.0...0.12.0

0.11.0

Package Boost v0.11.0

Three new vendor-shipped skills propagate to consumer Laravel packages via package-boost:sync, teaching maintainers how to write good README files, GitHub release bodies, and UPGRADING.md guides.

Highlights

  • New readme skill — teaches the two README shapes (stub vs comprehensive), required sections per shape, voice, and a canonical staleness-audit pattern. Distilled from a survey of 11 well-maintained Laravel packages.
  • New release-notes skill — defaults to GitHub's auto-generated format and overrides only when major/breaking. Includes a "Bookwork to cut" list (no Internals sections, no Why-now narrative, no empty Compatibility blocks, no Test-hygiene reports).
  • New upgrading skill — per-major sections in reverse-chronological order, version-comment-labelled before/after code, stable H2 anchors that release-notes' breaking-change bullets link to. Recognises four real filename conventions (UPGRADING.md, docs/upgrading.md, etc.) without prescribing one.
  • Connected contract across the three. README links to UPGRADING.md, release-notes' ## Breaking changes bullets each end with [UPGRADING.md#anchor], and the host-internal pre-release skill validates the contract via a new 5d matrix row that fires on breaking releases only.
  • Generic body + Laravel-specific reference. Each skill body is generic; references/laravel-package.md carries ecosystem conventions and is loaded advisorily when composer.json shows laravel/framework / illuminate/* / Filament / Livewire / Nova deps.

Upgrading

composer update sandermuller/package-boost
vendor/bin/testbench package-boost:sync





The first sync after upgrading writes the three new skills (and their references/ subdirs) to every selected agent's skill dir. Existing skills are unaffected.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.10.1...0.11.0

0.10.1

Bug fix

package-boost:install was writing the literal four characters ${indent} to the start of the rewritten 'agents' => ..., line, producing invalid PHP in workbench/config/package-boost.php:

${indent}'agents' => ['claude_code', 'copilot'],






The preg_replace replacement string used ${indent} as a named- group backreference, but PHP only honours positional backreferences ($1, ${1}) in preg_replace replacements — named ones are emitted verbatim. Switched to $1 against the (now-unnamed) first capture group; existing comments, indentation, and unrelated config keys still survive the rewrite.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.10.0...0.10.1

0.10.0

What's new

Multi-agent sync

Three guideline files (CLAUDE.md, AGENTS.md, GEMINI.md) and six unique skill dirs:

Agent Guidelines Skills dir
Claude Code CLAUDE.md .claude/skills
Cursor AGENTS.md .cursor/skills
GitHub Copilot AGENTS.md .github/skills
Codex CLI AGENTS.md .agents/skills
Gemini CLI GEMINI.md .agents/skills
Junie AGENTS.md .junie/skills
Kiro AGENTS.md .kiro/skills
OpenCode AGENTS.md .agents/skills
Amp AGENTS.md .agents/skills

.agents/skills is shared across Codex, Gemini, OpenCode, and Amp — sync writes there once and dedupes.

package-boost:install command

Interactive picker for the agent set:

vendor/bin/testbench package-boost:install







Defaults pre-fill in this order: existing package-boost.agents config → import from laravel/boost's boost.json if Boost is installed → detection-marker scan against the project (.cursor/, .kiro/, CLAUDE.md, etc.) → all 9. The selection persists to workbench/config/package-boost.php via a single-line regex-replace of the 'agents' => key, preserving comments and unrelated keys. Non-interactive flags: --all, --agents=claude_code,cursor, --no-import. Adversarial config shapes (multi-line array, missing key, hand-customised formatting) refuse with a clear diagnostic.

agents config key

// config/package-boost.php
'agents' => null,  // null = all 9; or e.g. ['claude_code', 'cursor']







Unknown agent names trigger a non-fatal warning naming each typo and listing the supported set, so a misconfigured selection is visible without breaking sync. When claude_code is filtered out, MCP sync is skipped (--check reports claude-not-selected) — per-agent MCP serializers are out of scope for this release.

Migration: legacy .github/copilot-instructions.md

Upstream Boost migrated Copilot guidelines from .github/copilot-instructions.md into AGENTS.md. Package-boost matches that — the legacy file is no longer written. Sync detects the leftover with our <package-boost-guidelines> tag block and warns. To remove it automatically:

vendor/bin/testbench package-boost:sync --prune







--prune refuses if the file has user content outside the block, or if the block has been hand-edited / is stale relative to current .ai/ sources. Run a regular package-boost:sync first to refresh the block, then --prune to clean up.

Deselected-agent artifact warnings

When package-boost.agents is narrowed after a previous broader sync (for example, dropping from "all" to ['claude_code']), the generated files for the now-deselected agents stay on disk — .cursor/skills/, GEMINI.md, .mcp.json, etc. Sync now scans for these and warns:

WARN  Generated artifacts exist for agents NOT in `package-boost.agents`:
  - .cursor/skills/ (14 entries)
  - GEMINI.md (contains <package-boost-guidelines> block)
  - .mcp.json (laravel-boost mcpServers entry present)
  These were synced under a previous selection. Re-include the agent
  or delete the paths manually.







Auto-removal is intentionally not done — guideline files may carry user content outside the package-boost-guidelines block. Surface and let the user decide.

JSON output: new claude-not-selected skip reason

--format=json adds a stable shape for the gated MCP case:

{ "mcp": { "action": "skipped", "reason": "claude-not-selected" } }







Joins the existing laravel-boost-not-installed reason. The schema's skipped semantics are unchanged; only the reason identifier is new.

Breaking change

.github/copilot-instructions.md is no longer written. Existing consumers will see a warning on the next sync; clean up via package-boost:sync --prune or by deleting the file manually. No config or API change is required — Copilot reads AGENTS.md now, which package-boost has been writing alongside CLAUDE.md since 0.7.0.

Internals

  • Agents\Registry is the single source of truth for agent paths, detection markers, and selection filtering. The 9 entries are frozen against laravel/boost@8ed9f84 (verified by direct source read of src/Install/Agents/* and src/BoostManager.php:22-32).
  • Agents\BoostImporter reads boost.json at the project root, filters against the registry, returns null for missing / malformed / unknown-only inputs.
  • Console\DeselectedAgentArtifacts enumerates orphans across skills, guidelines, and MCP for the warning above.
  • Console\LegacyCopilotInstructions owns the legacy-file detect / prune contract, with the prune-safety check that compares the file's tag block to the freshly composed expected block.
  • SyncCommand's class cognitive complexity stays under PHPStan's budget by extracting the post-categories rendering and final-exit decisions into named helpers.

Full Changelog: https://github.com/SanderMuller/package-boost/compare/0.9.0...0.10.0

0.9.0

Package Boost v0.9.0

Discovers skills and guidelines shipped by sibling packages. package-boost:sync now walks vendor/*/*/resources/boost/ and merges contributions between the shipped defaults and the host's .ai/. First native path that doesn't rely on Laravel Boost's Composer resolver, sidestepping the testbench-skeleton discovery bug that blocks Boost's own scan under package development.

What's new

Vendor-contributed skills and guidelines

Any installed Composer package that ships resources/boost/skills/<name>/SKILL.md or resources/boost/guidelines/*.md is now picked up by package-boost:sync automatically. Load order:

  1. Package-boost's shipped defaults
  2. Vendor packages (alphabetical by vendor/name)
  3. Host .ai/

For skills, later entries override earlier ones on name collisions — host/.ai/skills/<name> always wins over a vendor skill of the same name. For guidelines, each source contributes its own block and they concatenate in load order, separated by ---.

This means a package author can ship, for example, a resources/boost/skills/fluent-validation-testing/SKILL.md bundled with their library, and downstream consumers running package-boost:sync will pick it up in their .claude/skills/ and .github/skills/ directories alongside their own content — no extra wiring, no manual copy.

Configuration

Two new keys in config/package-boost.php, both shipped with sensible defaults so existing consumers see the behavior activate on composer update with no publish step required:

'discover_vendor_packages' => true,

'excluded_vendor_packages' => [
    'sandermuller/package-boost',
],








  • discover_vendor_packages — toggle off to restore 0.8.x behavior (shipped + host .ai/ only). No consumer has asked for this yet; the flag exists as an escape hatch.
  • excluded_vendor_packages — skip specific packages by vendor/name. Default excludes package-boost itself so a transitively-installed copy can't double-ingest shipped content through its own resources/boost/.
Self-ingestion guard

Beyond the configurable exclude list, SyncSources::vendorDirs() realpath-compares each vendor match against the shipped resources/boost/<kind> directory and drops exact matches. This is structural, not user-tunable — so even a consumer who deliberately clears excluded_vendor_packages can't double- ingest shipped skills through a symlinked dev checkout or a transitive dep surfacing package-boost under its own vendor/ tree.

Why now

Laravel Boost's upstream package discovery reads base_path('composer.json'), which under Testbench resolves to the testbench-core skeleton with no require entries. That means resources/boost/{skills,guidelines}/ content shipped by third-party packages is invisible to Boost itself when run via vendor/bin/testbench boost:install inside a package repo.

Package Boost's shipped-bundling approach (0.3.3+) carried package-boost's own skills through this gap. Vendor discovery (0.9.0) extends the same idea to arbitrary packages — any dependency that ships resources/boost/ gets surfaced, whether Boost is installed or not.

Upgrading

composer update sandermuller/package-boost
vendor/bin/testbench package-boost:sync








The first sync after upgrading may add skills or guidelines contributed by your existing dependencies. Review the generated .claude/skills/ / .github/skills/ / guideline blocks; if a vendor contribution isn't wanted, add its vendor/name to excluded_vendor_packages in a published config file.

If you previously relied on your .ai/skills/<name> containing the only copy of a given skill name, behavior is unchanged — host .ai/ still wins on collisions.

Compatibility

No breaking changes. No schema changes to --format=json output — vendor contributions flow through the existing skills / guidelines arrays indistinguishably from shipped and host entries, so CI gates on the JSON drift report continue to work.

Config file additions are forward-compatible: consumers on a published 0.8.x package-boost.php keep working because applyUserConfigOverrides uses array_replace (missing keys retain shipped defaults).

Internals

  • SyncSources::vendorDirs() globs vendor/*/*/resources/boost/<kind> with GLOB_ONLYDIR, sorts by vendor/name, and filters via exclude list + realpath guard.
  • Existing skill planning / writing / drift-reporting code paths are untouched — vendor dirs simply appear in the SyncSources::dirs() sequence between shipped and host .ai/, so all of planSkills, planGuidelines, and --check drift detection work without modification.
  • Five new tests in tests/SyncCommandTest.php: discovery, host-wins-on-collision, guideline merge, --check drift reporting, discover_vendor_packages=false, excluded_vendor_packages respect, and the self-mirror realpath guard. Total suite: 53 passing, 184 assertions.
0.8.1

Package Boost v0.8.1

Hygiene release. No code changes, no schema changes. Ships the repo housekeeping that accumulated since 0.8.0 — nothing here requires downstream action.

What's new

Composer auto-sync hook documented

New Composer auto-sync hook section in the README under Composer script, documenting three variants that pair well with the 0.4.0 --check gate:

  • Strict (recommended)[@php](https://github.com/php) vendor/bin/testbench package-boost:sync --check as a post-autoload-dump entry. Fails the install if anything drifted.
  • Auto-fix — runs the sync without --check; friendlier but leaves uncommitted changes on a dirty branch.
  • Boost-less — narrows the hook to --check --skills --guidelines so Boost-less packages don't see the "Laravel Boost is not installed" warn on every composer run (direct response to the js-store peer's 0.8.0 verification feedback).

Cross-platform note: the hook form works on both posix (/bin/sh) and Windows (cmd.exe). Chained shell operators (&&, ||) are not portable across composer's shell layers — use separate array entries if you need multiple steps.

Cross-linked from the shipped package-development skill's Syncing section so discoverability works both from the README and from the skill bundle downstream users see.

CHANGELOG.md

CHANGELOG.md now lives at the repo root, auto-maintained by a new .github/workflows/update-changelog.yml workflow. On each published GitHub release the workflow prepends the release body to CHANGELOG.md and commits back to main via stefanzweifel/changelog-updater-action. Seeded with entries from v0.4.0 through v0.8.0.

README now links to CHANGELOG.md between How It Differs and License.

shields.io status badges

README header carries four badges matching the sibling package's style: Packagist version, test workflow status, code-style workflow status, Laravel compatibility. Existing content-only badge (Laravel Compatibility) updated to ?style=flat for visual consistency.

Package-boost dogfoods itself

.ai/guidelines/ and .ai/skills/ are now committed:

  • Guidelines: release-automation (explains the CHANGELOG.md automation), verification-before-completion (evidence-before-claims rule, mirrored from laravel-fluent- validation with a preamble note pointing at the canonical copy).
  • Skills: ai-guidelines, backend-quality, bug-fixing, code-review, codex-review, evaluate, implement-spec, pr-review-feedback, pre-release, write-spec — 10 workflow skills carried over from the sibling, adapted where they referenced fluent-validation internals (backend-quality's benchmark group → rector; bug-fixing's FluentRule example → SyncCommand fixture; pr-review-feedback's GraphQL repo name; pre-release rewritten for package-boost's matrix). The autoresearch skill was deliberately skipped — its premise is autonomous perf-optimization with a benchmark harness, which package-boost doesn't have.

testbench.yaml is now committed (previously gitignored) so contributors can run vendor/bin/testbench package-boost:sync without manual setup.

Generated outputs (CLAUDE.md, AGENTS.md, .github/copilot- instructions.md, .claude/skills/, .github/skills/) remain gitignored — the sync-command tests exercise those exact filesystem paths and would clobber any committed copies every pest run. Run sync locally after composer install.

tests/SyncCommandTest.php::wipeArtifacts() now targets only test-created fixtures (test-skill, keep-me, stale-skill, test.md) so committed .ai/ content survives the suite. One test (it ships foundation guideline even without a user .ai/guidelines directory) renames-and-restores the dogfood guidelines dir to exercise the no-user-guidelines path that downstream consumers hit before authoring their own content.

Upgrading

composer update sandermuller/package-boost









Nothing changes at runtime. Consumers see the README additions and the new CHANGELOG.md link on the next visit to the repo.

If you want the auto-sync hook in your own package, add the relevant post-autoload-dump variant from the README to your package's composer.json scripts block.

Compatibility

No breaking changes. No schema changes. No config schema changes. Text and JSON sync output byte-compatible with 0.8.0.

0.8.0

Hygiene release. Ships a deprecation alias for the command name that keeps showing up in stale skill bundles.

0.7.0

Closes a silent-drift hole in --check that affected any consumer on a filesystem without symlink support (Windows-without-dev-mode, some sandboxed CI runners). Before 0.7.0, SyncCommand::linkOrCopy fell back to a recursive file copy when [@symlink](https://github.com/symlink)() failed — and every subsequent --check reported those copied skill directories as unchanged regardless of whether the shipped skill's content had drifted. CI passed, local content was stale, nobody knew.

0.6.1

Documentation-only release. Pins the --format=json schema-v1 contract ahead of the first downstream CI integration (landing in laravel-fluent-validation v1.13) — locks the shape so future consumers don't have to guess what fields mean or hit the same mcp-as-array foot-gun as the pre-integration peer review caught.

0.6.0

Structured output for package-boost:sync. CI scripts and release automation can now parse drift detection results instead of regex- matching glyph lines. Directly requested by the laravel-fluent-validation peer after 0.4.0's --check landed; deferred two releases while the trigger-word skills (0.5.0) shipped first.

0.5.0

Shipped content release — driven by real feedback from two downstream peers (laravel-fluent-validation, laravel-js-store) running package-boost 0.3–0.4 in anger. Two new skills land, the foundation stops assuming Pest-first, and Boost-specific commands move into their own table so PHPUnit-only and Boost-less packages stop reading dead copy.

0.4.1

Cosmetic follow-up to 0.4.0: the MCP: section of package-boost:sync output now emits a total: ... summary line matching the Skills and Guidelines sections.

0.4.0

Two major additions driven by real-world feedback from users running package-boost against their packages: a CI drift-check mode and per-target delta output on every sync. Also hardens .mcp.json handling against malformed input.

What's

--check mode for CI

vendor/bin/testbench package-boost:sync --check









Computes planned actions, writes nothing, exits non-zero if any skill, guideline, or MCP target diverges from its source. Use in CI to catch commits where .ai/* content was edited but the generated files (.claude/, .github/, CLAUDE.md, AGENTS.md, .mcp.json) weren't re-synced.

Combines with the subcommand flags:

vendor/bin/testbench package-boost:sync --check --guidelines









Per-target delta output

Every sync now shows a per-target line for changes, with glyphs and a per-category summary:

Skills:
  + .claude/skills/package-development
  + .github/skills/package-development
  total: 2 new, 0 unchanged

Guidelines:
  ~ CLAUDE.md (+12 lines)
  ~ AGENTS.md (+12 lines)
  ~ .github/copilot-instructions.md (+12 lines)
  total: 3 updated

MCP:
  = .mcp.json (unchanged; not listed)









Glyphs:

glyph meaning
+ new — target doesn't exist yet
~ updated — content or symlink target differs
- removed — stale target no longer in sources
= unchanged — hidden by default, counted in summary

Skill updates annotate the new symlink target:

~ .claude/skills/package-development (symlink → ../../vendor/sandermuller/package-boost/resources/boost/skills/package-development)









Guideline updates show line-delta:

~ CLAUDE.md (+12 lines)









--show-unchanged flag

vendor/bin/testbench package-boost:sync --show-unchanged









Default output is compact — unchanged targets are folded into total: ... rather than listed per line, to avoid flooding large guideline trees. Pass --show-unchanged to print every = entry for debugging. Explicit flag name chosen over -v / --verbose because Symfony already owns those for log verbosity.

.mcp.json hardening

Previous versions assumed .mcp.json was always valid and mcpServers was always an array. v0.4.0 survives:

  • null, invalid JSON, or scalar roots ("hello", 42) — treated as empty config.
  • mcpServers being a scalar — coerced to array before adding the laravel-boost entry.
  • Extra user keys at any level — preserved on write.

Four regression tests guard these paths.

Upgrading
composer update sandermuller/package-boost
vendor/bin/testbench package-boost:sync









Add a drift check to CI. Example GitHub Actions step:

- name: Check package-boost sync
  run: vendor/bin/testbench package-boost:sync --check









Migration

Downstream --check will report drift on the first run after upgrade:

  • GuidelinesCLAUDE.md, AGENTS.md, .github/copilot-instructions.md all pick up the runner-agnostic row, new sub-table, trimmed Cross-Version section.
  • Skills.claude/skills/package-development/SKILL.md and .github/skills/package-development/SKILL.md pick up the Authoring guidelines section + the Cross-Version trim + the table reshape.
  • New skills.claude/skills/cross-version-laravel-support/ and .claude/skills/ci-matrix-troubleshooting/ appear (plus their .github/skills/ mirrors).

Expected one-time re-sync.

Internals
  • Tests introduce a SHIPPED_SKILLS constant so each new shipped skill gets automatic coverage via a Pest dataset-driven test. No more per-skill test-count drift.
  • Seeded ROADMAP.md + specs/ directory in the repo as the plan of record for 0.5.x / 0.6.x / 0.7.x work.
Internal
  • Extracted SyncReporter — pure functions for planning actions (planSkillAction, planGuidelineAction, planMcpAction), rendering glyphs, line-delta computation, and relative-path calculation. No side effects, fully unit-testable.
  • Extracted SyncSources — shipped-then-user directory iteration for skills and guidelines, plus safe .mcp.json reading that handles malformed input.
  • SyncCommand shrunk to orchestration + IO; class cognitive complexity stays under the project's guardrail.
Fixes
  • array_any() (PHP 8.4-only) usage replaced with a collection-based drift check — was failing the CI matrix's PHP 8.2 / 8.3 cells before the fix landed.
  • storage/logs/ now gitignored; a test-generated laravel.log had been accidentally committed in a prior release and un-tracked.
Fix

Before (0.4.0):

Skills:
  total: 24 unchanged
Guidelines:
  total: 3 unchanged
MCP:









After (0.4.1):

Skills:
  total: 24 unchanged
Guidelines:
  total: 3 unchanged
MCP:
  total: 1 unchanged









The three categories now render uniformly. --show-unchanged still controls whether the per-target = .mcp.json line is printed alongside the summary.

Deferred
  • --format=json: structured output for CI parsing. Tracked for a follow-up; current stdout diff is enough for most CI gates via exit code.
  • Content-drift detection on copied (non-symlink) skills: requires recursive tree hashing; edge case for filesystems without symlink support. Tracked.
Compatibility

No breaking changes. Existing CI jobs that run vendor/bin/testbench package-boost:sync without flags continue to work; they now produce delta output alongside the previous "Synced …" info lines.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle