# CLAUDE.md Guidance for working in this repository. ## What this is A **starter WordPress plugin** built on the [Roots Acorn](https://roots.io/acorn/) framework (Laravel components inside WordPress) with **Livewire 4** for reactive front-end components. It is a scaffold/template designed to **coexist with other Acorn-based plugins** in the same WordPress install without booting the framework more than once. - `roots/acorn: ^6.0`, `livewire/livewire: ^4.1` - Requires PHP 8.4, WordPress 5.2+ - PSR-4: `AcornPlugin\` → `app/`, `AcornPlugin\Tests\` → `tests/` - Acorn is bundled (in `vendor/`); the plugin `wp_die`s if `Roots\Acorn\Application` is somehow absent. ## The single-Acorn contract (read this before touching `bootstrap.php`) PHP classes and the Acorn container are **global to a request**. If two Acorn plugins each call `Application::configure()->boot()`, the second clobbers the first. This plugin avoids that with a cooperative **boot election** that every Acorn plugin in the install must follow: 1. **One booter per request, elected via a shared action.** On `after_setup_theme` priority 0, a plugin boots Acorn only if `did_action('acorn/booted')` is false, then fires `do_action('acorn/booted')`; otherwise it stands down. This lives in `app/Acorn/BootCoordinator.php` (`BootCoordinator::BOOTED_ACTION = 'acorn/booted'`). `did_action()` is used deliberately — it is a **read-only** probe, unlike `Application::getInstance()`, which force-creates and installs an empty container. 2. **Providers are auto-discovered, never hand-registered.** Each plugin declares its provider in `composer.json` under `extra.acorn.providers`. Whichever plugin wins the election scans **all** active plugins' manifests and registers every provider — so a plugin's provider boots even when a *sibling* booted Acorn. 3. **Livewire assets are emitted once, by the boot owner.** Only the elected booter calls `LivewireAssets::registerOnce()` (`@livewireStyles` on `wp_head`, `@livewireScripts` on `wp_footer`). Livewire 4 self-initialises — never add `Livewire.start()` or a hand-rolled ESM `