jiannius/playbook
jiannius/playbook is a Laravel package for defining and running reusable playbooks, helping you organize multi-step business logic into clean, composable, and testable units that are easy to maintain and reuse across projects.
This package wires Laravel Boost into a set of Claude Code task agents — a "playbook" of specialised AI helpers (architect, debugger, data-backfill, pr-reviewer, etc.) plus a routing rule that tells Claude when to hand work to each one.
Minimal adoption:
composer require --dev jiannius/playbook:^0.6php artisan boost:update — this now runs playbook:sync for you and writes:
.claude/agents/playbook/*.md.claude/rules/playbook/*.mdAGENTS.md (with CLAUDE.md importing it via @AGENTS.md)php artisan playbook:check and expect exit 0.composer.*, AGENTS.md, .claude/skills/, .claude/agents/, .claude/rules/ together.First use case: open Claude Code in the repo and ask it to investigate a failing job. The routing rule hands it to debugger (and data-investigator if it needs to look at data), which picks its own model and effort. You don't invoke agents by name — Claude routes based on the rule.
Where to look first:
config/playbook.php — the only file you'll edit day to day..claude/agents/playbook/ — read the twelve agent prompts to know what each is good at..claude/rules/playbook/ — the routing logic, so you understand why Claude chose an agent.Task-to-agent mapping (let the router do its job). Day to day you describe the task, not the agent. Typical flows:
debugger → pr-fixer.pr-reviewer.orders.status from the legacy column" → data-backfill (will stop to ask for staging permission — see gotchas).architect → plan-executor.dependency-updater → pr-fixer.qa-tester (requires Playwright).Agent-level opt-outs via config. Use config/playbook.php for team-wide choices:
'agents' => [
'enabled' => true, // flip to false to ship none of ours
'except' => ['qa-tester'], // per-agent opt-out for everyone
],
For a personal opt-out that doesn't touch the repo, deny the tool in your own Claude settings (Agent(qa-tester)) so the rule can still route to it for teammates who want it.
CI integration via claude.yml. @claude mentions still work, but task agents are disallowed in CI (--disallowedTools "Agent") — so PR comments stay lightweight and don't spin up pr-fixer from an @claude ping. Keep the interactive agentic work local; use CI for the lighter review/comment flow.
Manual sync when Boost isn't in your post-update-cmd. If you don't already run boost:update on composer update, either add it to scripts.post-update-cmd or invoke php artisan boost:update (which triggers playbook:sync) after every composer update.
Keeping custom agents. If you already have a Claude agent with a name that collides with ours, decide per agent: opt out of ours in config/playbook.php, or rename/delete yours. Don't keep both with the same name — playbook:check will fail (exit 2).
playbook:check exit codes carry the signal.
exit 1 → files are stale; run php artisan boost:update and commit.exit 2 → a playbook/ folder is gitignored, or a name clash with one of your own agents. Fix the ignore rule (agents and rules must be committed), or resolve the clash via config.exit 0 → clean. Wire this into CI to catch stale agent files on PRs.Restart Claude Code after pulling. A brand-new agents folder is only picked up at Claude Code startup — teammates must restart once after git pull or the new agents simply won't be routed to.
playbook:sync only writes inside .claude/agents/playbook/ and .claude/rules/playbook/. It copies byte-for-byte, refuses to follow symlinked folders, and never deletes outside those two directories. If you symlink .claude/ into another repo, sync will no-op — that's intentional.
qa-tester needs a browser tool. Install/configure Playwright in Claude Code before expecting it to work; without it the agent will fail mid-task.
Data agents will ask for staging, not assume it. data-investigator and data-backfill may run against staging only when the person who asked for the task explicitly grants it. Production stays off-limits — if you're seeing the agent refuse, that's the guardrail working, not a bug.
Agent files go stale silently on guideline changes. If a teammate's playbook:check starts failing with exit 1 after merging, they're behind on boost:update — the agents are only "current" relative to AGENTS.md, so treat AGENTS.md and .claude/agents/ as a package deal in every PR.
@claude in CI is intentionally weaker than local Claude. Don't rely on it to run pr-fixer or debugger; those are --disallowedTools in claude.yml. Move that work into a local session or a dedicated workflow you own.
Upgrading from <0.5. Step 4 of the adoption guide (converting CLAUDE.md → @AGENTS.md) is a prerequisite — skipping it means the routing rule reads a CLAUDE.md that doesn't import AGENTS.md and the agents won't see the guidelines.
Extension points worth knowing. agents.enabled for a full kill-switch (useful in forks or when trialling other agent stacks), agents.except for per-agent team opt-outs, and per-developer denial via Agent(<name>) — three escalation levels for "our team doesn't want this agent" without forking the package.
How can I help you explore Laravel packages today?