sandermuller/boost-core 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

sandermuller/boost-core

Composer 安装命令:

composer require sandermuller/boost-core

包简介

AI agent configuration sync for PHP projects. Author skills and guidelines once, publish to every agent.

README 文档

README

Latest Version on Packagist Tests Total Downloads License Laravel Boost

AI agent configuration sync for any PHP project. Write skills, guidelines, and commands once in .ai/; boost-core publishes them to nine agents: Claude Code, Cursor, Copilot, Codex, Gemini, Junie, Kiro, OpenCode, Amp. No framework dependency.

overview image

Contents

How sync works

You author three kinds of content under .ai/, and boost sync fans each out to every agent you selected in withAgents(...). One source, many agent-native copies:

You write in What it is boost sync fans it out to
.ai/skills/ Agent Skills (<name>/SKILL.md) .{agent}/skills/<name>/SKILL.md per agent
.ai/guidelines/ Always-loaded guidance CLAUDE.md, AGENTS.md, GEMINI.md, Copilot file
.ai/commands/ Slash-command prompt templates Per-agent command dirs (see Commands)

Skills and commands land in gitignored per-agent directories; the guidance files stay tracked. See File ownership for why.

Install

boost-core is the engine. You rarely install it directly. Instead you install the family package (a thin wrapper that bundles boost-core with a curated skill set) that matches what you're building, and it pulls boost-core in.

You're building Install Ships
A PHP application (not a package) sandermuller/project-boost App-dev skills — DDD layering, repository pattern, DI, domain modeling, legacy coexistence
A Laravel application sandermuller/project-boost-laravel laravel/boost MCP coexistence + nine-agent fanout + tag filter + remote skills
A framework-agnostic Composer package sandermuller/package-boost-php Package-author skills + lean / gitattributes commands
A Laravel package sandermuller/package-boost-laravel Laravel-package skills + McpJsonEmitter
Your own skill bundle / tooling sandermuller/boost-core directly Just the sync engine — you supply the skills ← you are here
composer require --dev sandermuller/boost-core

Coexists with laravel/boost in Laravel projects via project-boost-laravel.

family overview image

Quickstart

vendor/bin/boost install   # scaffold boost.php + pick agents, vendor allowlist, tags
vendor/bin/boost sync      # fan out to selected agents
vendor/bin/boost sync --check   # dry run — report drift, no writes

Config lives at boost.php (repo root) or .config/boost.php; see File ownership for the layout details. A minimal config:

use SanderMuller\BoostCore\Config\BoostConfig;
use SanderMuller\BoostCore\Enums\Agent;

return BoostConfig::configure()
    ->withAgents([Agent::CLAUDE_CODE, Agent::CURSOR]);

boost-core runs no install-time code of its own. It's a plain library, not a Composer plugin. Run vendor/bin/boost sync yourself (e.g. in CI), or wire the autosync hook to re-sync on composer install.

What you get

laravel/boost boost-core
Framework scope Laravel only Any PHP (Laravel, Symfony, plain-PHP, packages)
Skill sources bundled + .ai/skills/ .ai/skills/ + Composer packages (resources/boost/skills/) + withRemoteSkills() + withAllowedVendors() filter
Tag filtering none withTags() subset rule
Remote skill sources none withRemoteSkills() — GitHub bundles + path imports
User-scope sync none boost sync --scope=user for globally-installed CLI tools
Origin tracing none boost where + boost where --diff=<name> (host / vendor / remote / shadow)
Doctor / path-repo audit none boost doctor, boost doctor --check-versions
.ai/commands/ fan-out none per-agent argument transpilation across 7 emit targets
Project Conventions none JSONSchema-validated slot fill-in via boost validate / boost slots

The MCP server (Model Context Protocol) + Laravel docs API are laravel/boost's domain, so boost-core defers to them in Laravel projects (see project-boost-laravel for coexistence).

Skill sources

Skills come from three places, all resolved on the same composer install / update lifecycle and fanned out side by side:

  1. Host — your project's own .ai/skills/.

  2. Vendor packages — any Composer package that ships resources/boost/skills/<name>/SKILL.md. Allowlist the vendor to pick it up:

    return BoostConfig::configure()
        ->withAllowedVendors(['vendor/package'])
        ->withAgents([Agent::CLAUDE_CODE]);

    This is how a team distributes one curated skill set across many repos: author once in a package, allowlist everywhere. sandermuller/boost-skills is one example of the pattern.

  3. Remote sources — GitHub repos shipping .skill release bundles or skill subdirs, declared with withRemoteSkills() (below).

Remote skill sources

use SanderMuller\BoostCore\Skills\Remote\RemoteSkillSource;

return BoostConfig::configure()
    ->withAgents([Agent::CLAUDE_CODE])
    ->withRemoteSkills([
        // Bundle mode — fetch the named `.skill` release asset and unzip it.
        RemoteSkillSource::githubBundle('peterfox/agent-skills', 'v1.2.0', [
            'composer-upgrade',
            'phpstan-developer',
        ]),

        // Path mode — fetch the repo tarball at a ref and extract named subdirs.
        // `.` covers a whole-repo-is-one-skill layout.
        RemoteSkillSource::githubPath('mattpocock/skills', 'main', [
            'grill-with-docs' => 'skills/engineering/grill-with-docs',
        ]),
    ]);

Each fetched skill fans out exactly like host and vendor skills: same layout, same withTags() filtering, same withExcludedSkills(['<owner>/<repo>:<name>']) deny-list. Removing an entry prunes its output on the next sync.

  • Cache. Bundles and tarballs land under ${BOOST_CACHE_HOME:-${XDG_CACHE_HOME:-$HOME/.cache}}/boost/remote-skills/. Pinned refs (a tag or 40-char SHA) cache forever; moving refs (main, a branch) re-resolve every 24h.
  • Offline. boost sync --check never hits the network. boost doctor lists every source, flags moving refs, and reports cache presence.
  • Rate limit. Anonymous GitHub caps at 60 req/h. Set BOOST_GITHUB_TOKEN (any token with public_repo scope) to lift it to 5000/h. Cold CI runs and boost doctor over many sources need it.
  • Trust. Sources are opt-in by full path: peterfox/agent-skills:composer-upgrade grants access to nothing else in the repo. Pin to a tag or SHA in production; moving refs are convenient, but a source-side push silently changes what lands. Archive extraction rejects path traversal, absolute paths, symlinks, and oversized payloads (200 MB total / 50 MB per file / 10000 entries), and any violation rejects the whole source rather than extracting part of it.
  • Strict mode. BOOST_REMOTE_STRICT=1 escalates any source failure to a sync-aborting error. Default is warn-and-skip.

Publishing a source for remote consumption: treat the SKILL.md frontmatter name as durable public API (renaming breaks moving-ref consumers), keep source dirs symlink-free (extraction rejects any symlinked entry), and align metadata.boost-tags with the family's tag vocabulary.

Tag filtering

Vendor skills can be scoped to projects that want them, so a project with no Jira work never receives a jira-triage skill (and its description never pollutes the agent's skill-selection index).

A skill declares tags in its SKILL.md frontmatter:

---
name: jira-triage
description: Triage and label incoming Jira issues.
metadata:
  boost-tags: "php jira"
---

A project declares the tags it wants in boost.php:

use SanderMuller\BoostCore\Enums\Tag;

return BoostConfig::configure()
    ->withAgents([Agent::CLAUDE_CODE])
    ->withTags([Tag::Php, Tag::Jira])        // Tag enum cases or raw strings
    ->withExcludedSkills(['acme/pack:unwanted-skill'])
    ->withExcludedGuidelines(['acme/pack:unwanted-guideline']);

The rule: a vendor skill ships only when every tag in its boost-tags is among the project's withTags() (skillTags ⊆ projectTags). An untagged skill always ships, so the feature is inert until skills and projects opt in. withExcludedSkills() drops a specific vendor/package:skill-name regardless of tags. Vendor guidelines filter the same way, tagged either by metadata.boost-tags or a sidecar resources/boost/guidelines/.boost-tags.yaml manifest (for guidelines that must stay frontmatter-free for laravel/boost).

The Tag enum is just a convenience; the vocabulary is open, and any string is a valid tag. vendor/bin/boost tags lists every tag installed skills/guidelines declare, which your withTags() filters out, and what to add to receive them; boost install's interactive picker offers the same. When sync drops tagged skills because withTags() is empty, it prints a one-line nudge at boost tags.

Warning

Adding a tag to an already-shipped skill is consumer-breaking: every project that hasn't declared that tag loses the skill. Treat it as a breaking change.

Use boost where to trace where every resolved skill, guideline, and command comes from (host / vendor / remote), with host-override shadowing annotated inline. boost where --diff=<name> prints a unified diff between a host override and the vendor copy it shadows.

Commands

.ai/commands/*.md holds reusable prompt templates: the slash-command files agents surface in their palette. boost sync fans each out to the seven agents with a command surface:

Agent Command target
Claude Code .claude/commands/
Cursor .cursor/commands/
Copilot .github/prompts/ (as <name>.prompt.md)
Junie .junie/commands/
OpenCode .opencode/commands/
Amp .agents/commands/
Kiro .kiro/skills/<name>/SKILL.md (slash-command)

Codex and Gemini have no committable command target boost-core can write into (Codex's prompts are deprecated/personal-only, Gemini uses TOML). When .ai/commands/ is populated and one of those agents is selected, boost doctor prints the manual authoring path so the gap isn't silent. Override the source dir with ->withCommandsPath(...).

Argument placeholders are transpiled per-agent. Author once using the canonical syntax: $ARGUMENTS (unsplit), $1/$2/… (positional), $name (named, optionally declared in frontmatter arguments:), and \$ escapes for literals. On sync, boost-core converts each to the agent's native shape (Claude $0-indexed, Copilot ${input:…}, and so on). Cursor and Amp have no placeholder support and emit verbatim with a warning. The bundled command-arguments skill documents the full table.

Skill rendering

Skill files default to plain markdown (SKILL.md). For template-flavored content (Blade, Twig, anything needing a render step), register a SkillRenderer in boost.php:

use SanderMuller\ProjectBoostLaravel\Rendering\BladeRenderer;

return BoostConfig::configure()
    ->withAgents([Agent::CLAUDE_CODE])
    ->withSkillRenderers([new BladeRenderer]);

The dispatcher matches longest-extension-first, so a BladeRenderer claiming blade.php handles SKILL.blade.php. The built-in PassthroughRenderer always handles .md. Render failures default to warn-and-skip (recorded in SyncResult::errors); BOOST_RENDER_STRICT=1 escalates the first failure to a sync-aborting error. A source whose extension has no registered renderer (e.g. a SKILL.blade.php with no BladeRenderer) is flagged by boost sync and boost doctor. Register a renderer for it, or rename it to SKILL.md.

The SkillRenderer contract is @api (locked at 1.0). Plugin authors writing renderers, FileEmitters, or a BoostWrapperContract should work from PUBLIC_API.md, which pins the frozen contract surface.

Automating the sync

boost-core ships no Composer plugin, so a composer install re-sync is opt-in. Pick the entry point that fits:

Entry point Use for
BoostAutoSync::run post-install-cmd / post-update-cmd hooks — silent on a no-op
BoostAutoSync::runWithSummary User-invoked scripts (composer sync-ai) — prints a summary always
BoostAutoSync::syncUserScopeOnce A globally-installed CLI tool self-syncing its own bundled skills

All three honor BOOST_SKIP_AUTOSYNC=1.

Composer hook (consumer project)

"scripts": {
    "post-install-cmd": ["SanderMuller\\BoostCore\\Scripts\\BoostAutoSync::run"],
    "post-update-cmd":  ["SanderMuller\\BoostCore\\Scripts\\BoostAutoSync::run"],
    "sync-ai":          ["SanderMuller\\BoostCore\\Scripts\\BoostAutoSync::runWithSummary"]
}

run checks Event::isDevMode(), resolves the bin-dir, runs vendor/bin/boost sync, surfaces non-zero exits through Composer's IO, and is silent on a true no-op (wrote=0, deleted=0). Output appears only when something changed or errored. runWithSummary prints the one-line success summary on every sync, including the no-ops run keeps quiet (useful when debugging "did the hook fire?"). Both work on Windows + Unix.

Important

On Laravel + project-boost-laravel, use @php artisan project-boost:sync instead of BoostAutoSync::run. The artisan path runs through the Laravel container, which bootstraps BladeRenderer and delivers laravel/boost's bundled skills to every agent. The bare-CLI path bypasses both. See project-boost-laravel's install guide for the canonical scripts shape.

CLI tool you publish (self-sync from bin script)

A tool installed with composer global require keeps its own bundled skills current by self-syncing from its bin script:

#!/usr/bin/env php
<?php declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

\SanderMuller\BoostCore\Scripts\BoostAutoSync::syncUserScopeOnce(
    packageRoot: dirname(__DIR__),
    packageName: 'your-vendor/your-tool',
);

// ... the tool's own dispatch ...

syncUserScopeOnce() runs a user-scope sync the first time it sees a given version, then writes a per-version sentinel so later runs are free. syncUserScope() is the ungated form. Both never throw, so the tool keeps running even if its sync fails.

After composer global require-ing skill-bearing packages, run vendor/bin/boost sync --scope=user --all once to user-scope-sync every globally installed package that ships resources/boost/skills/, into ~/.{agent}/skills/<vendor>__<package>/<skill>/SKILL.md. User scope publishes a package's skills wholesale: there's no boost.php, so tag filters and the vendor allowlist (both project-scope controls) don't apply. Removed packages are reaped on the next --all run; see File ownership.

Project Conventions

Vendor skills often need project-specific context: a Jira key, a branch pattern, a test runner. Project Conventions injects it via a JSONSchema slot fill-in. Vendors declare slots in resources/boost/conventions-schema.json; consumers fill them in boost.php:

return BoostConfig::configure()
    ->withAgents([Agent::CLAUDE_CODE])
    ->withConventions([
        'jira' => ['project_key' => 'HPB'],
        'github' => ['default_base_branch' => 'develop'],
    ]);

Skills consume a slot either with an inline <!--boost:conv path="…" mode="…"--> token (resolved into the emitted file) or via the rendered ## Project Conventions block in CLAUDE.md. boost validate --strict hard-fails CI on a leaked token; boost slots / boost where --conventions audit what's set.

See docs/conventions.md for the full reference: inline tokens, observability, legacy-ref migration, and migrating vendor skills.

File ownership

boost-core generates files into your repo and home directory and tracks what it owns in a manifest, so a sync never silently overwrites hand-written content:

  • Guidance files (CLAUDE.md, AGENTS.md, GEMINI.md, Copilot) are wholesale boost-owned, markerless, and regenerated from .ai/guidelines/ on every sync, but kept tracked so output is reviewable in diffs. Author guidance in .ai/guidelines/, never by hand-editing the target.
  • Skill + command directories are gitignored (100% generated from .ai/).
  • A file you've hand-edited (sha diverged from the manifest) is never blanked or reaped. Adopting boost-core in a repo with an existing CLAUDE.md won't wipe it.
  • Removing a vendor dep or de-selecting an agent reaps the now-orphaned files it owned.

See docs/file-ownership.md for the manifest, lifecycle reap, the empty-assembly guard, .config/ layout + relocation, managed .gitignore, and user-scope cleanup-on-remove.

CLI reference

Command Purpose
boost install Scaffold boost.php (if missing) + interactive agent / vendor / tag picker
boost sync Fan out skills / guidelines / commands to selected agents
boost sync --check Dry run — report drift, no writes (offline; gate CI on this)
boost sync --scope=user [--all] User-scope sync for globally-installed CLI tools
boost where Origin-traced listing of every skill / guideline / command that would ship
boost where --diff=<name> Unified diff (skill OR guideline) between a host override and the vendor copy
boost where --conventions [--json] Effective resolved conventions slots + provenance + block keep/drop status
boost doctor Offline health check — config, remote sources, cache, emitters, token leaks. Advisory only — exits 0 unless config fails to load
boost doctor --check-versions Opt-in Packagist comparison for path-repo shadows (one HTTP call per package)
boost doctor --check-conventions Report conventions slot status (missing, unknown, file-existence)
boost doctor --check-stale-paths Read-only audit of the retired-paths registry — what the next sync would clean up
boost tags List available tags + their unlock counts across allowlisted vendors
boost validate [--strict] Validate withConventions([...]) + scan for leaked tokens (--strict fails CI)
boost slots [--missing|--filled] List conventions slots, optionally filtered by fill state
boost paths List path globs boost-core manages
boost convert-conventions Legacy one-shot: extract 0.8.x marker YAML into boost.php (hidden, not a contract)

Exit codes: 0 ok, 1 failure, 2 usage. boost doctor is advisory, so gate CI on sync --check / validate --strict instead.

Environment variables

Every variable is opt-in; unset = default behavior.

Variable Effect
BOOST_SKIP_AUTOSYNC=1 Skip the BoostAutoSync composer-hook sync entirely
BOOST_SKIP_GITIGNORE=1 Skip managed .gitignore updates (handy for CI / ephemeral Docker installs)
BOOST_GITHUB_TOKEN GitHub token (public_repo scope) — lifts remote-skill fetches from 60 to 5000 req/h
BOOST_REMOTE_STRICT=1 Escalate any remote-skill source failure to a sync-aborting error (default: warn-and-skip)
BOOST_RENDER_STRICT=1 Escalate the first skill-render failure to a sync-aborting error (default: warn-and-skip)
BOOST_CACHE_HOME Override the remote-skill cache root (defaults to $XDG_CACHE_HOME / ~/.cache)

Versioning & stability

boost-core follows Semantic Versioning. The promise covers the public surface only:

  • Config authoring APIBoostConfig::configure(), the BoostConfigBuilder with*() methods, the Agent / Tag enums, and RemoteSkillSource.
  • CLI — command names, documented options, and exit codes.
  • Composer hooksBoostAutoSync::run / runWithSummary (new parameters always optional-with-default).
  • Plugin contractsFileEmitter, SkillRenderer, BoostWrapperContract and their DTOs. Parameterless constructors only.

Everything marked @internal (the whole engine) and on-disk regenerable state (the sync manifest, ledgers, runtime dirs) may change in any release. The full committed surface is enumerated in PUBLIC_API.md. From 1.0.0 on, breaking changes land only in a MAJOR bump and are called out in CHANGELOG.md and UPGRADING.md.

More

Testing

composer test            # full Pest suite (unit + integration, real composer-install subprocesses)
composer test-coverage   # with coverage report

Security

Email security issues to github@scode.nl rather than filing a public issue. See SECURITY.md for the disclosure policy.

Credits

Heavily inspired by laravel/boost. It's the framework-free sibling.

License

MIT. See LICENSE.

统计信息

  • 总下载量: 2.8k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 9
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-17

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固