
I got tired of copy-pasting the same PHPStan/Pint/Pest setup into every Laravel repo — and my AI agent kept ignoring the rules anyway. So I fixed both.
The problem
Every time I spun up a Laravel project, I'd do the same dance: copy phpstan.neon from the last repo, copy pint.json, wire up Pest, set up a pre-commit hook, write a CLAUDE.md full of
engineering rules… and then drift would set in. Repo A was on PHPStan level 5, repo B on 7. One had architecture tests, the others didn't. The "rules" lived in my head.
Then I started leaning on AI agents (Claude Code, Cursor, Copilot) and a new problem showed up: the agent would happily ignore the conventions. It'd write untyped code, skip tests,
invent patterns the rest of the repo didn't use. A CLAUDE.md full of rules helps, but rules a model can choose to skip aren't guardrails — they're suggestions.
What I wanted
- One command to set up a fresh Laravel repo with the same guardrails every time.
- A quality gate the agent literally cannot skip — not just docs it might read.
- The same gate running everywhere: at commit time, at the end of every AI turn, and in CI. If it passes locally it passes in CI, no surprises.
What I ended up building
A small Composer dev package. You run:
composer require --dev mohamed-ashraf-elsaed/claude-kit
php artisan claude-kit:install
It detects your frontend stack (Inertia+Vue, Inertia+React, Blade/Livewire, or API-only), asks what you actually want (PHPStan? which level? strict-rules? Pest or PHPUnit? coverage
threshold? arch tests? git hooks?), and scaffolds it — without clobbering existing files (composer.json / package.json get merged, not overwritten).
The part I care about most: the quality gate is one shell script (Pint + PHPStan level 7 + strict-rules + Pest with an 80% coverage gate + frontend lint) that backs three things — the git
pre-commit hook, Claude Code's Stop hook, and the CI workflow. So the AI agent's turn doesn't "finish" until the gate is green. Same script everywhere = no "works on my machine, red in
CI."
There's also a hybrid update model: the machinery (the gate script, the hook) is referenced from vendor/, so a composer update propagates fixes to every project. The content you own
(CLAUDE.md, linter configs, skills) is written into your repo so you can edit it freely.
It's MIT, PHP 8.2–8.4, Laravel 11/12/13. Repo + docs: github.com/mohamed-ashraf-elsaed/claude-kit
The actual question I'm curious about: for those of you using AI agents on real codebases — how are you enforcing conventions? Just prompt/CLAUDE.md, hooks like this, CI-only, or something
else? Genuinely want to hear what's working, because the "agent skips the rules" problem feels underrated.