Laravel Tackle is an open-source package that gives your Laravel app its own AI coding agent. Run `php artisan ai:code`, describe a task, and the agent reads, edits, tests, and formats your codebase.
Your Laravel app deserves its own AI agent.
Claude Code is great. Cursor is great. But they both live outside your project, and getting them properly oriented to your codebase's structure, patterns, and conventions takes real effort every session. Laravel Tackle takes a different approach: install it once via Composer, and your Laravel app gets its own AI coding harness, accessible at php artisan ai:code.
I open-sourced it today. Here's what it is and how it works.
Run php artisan ai:code, describe a task in plain language, and the harness gets to work. It reads files, searches code, edits what needs editing, runs your tests, formats with Pint, and reports back. It operates inside your project with full awareness of your structure, models, migrations, and conventions.
Here is what a session looks like in practice. Say you ask it to add a slug field to your Post model:
slug to $fillable.That's the loop. You describe the work, the agent does it, and every file change lands unstaged in your working tree so you can git diff and review before committing anything.
laravel/aiTackle is built on laravel/ai, which means it works with any provider that supports tool calling: Anthropic (Claude), OpenAI (GPT-4), Google (Gemini), Groq, and Ollama. The default is Claude Sonnet, but switching providers is a one-line change in your .env:
AI_CODE_PROVIDER=openai
AI_CODE_MODEL=gpt-4o
The agent has nine built-in tools:
| Tool | What it does |
|---|---|
ReadFile |
Reads a file's contents |
Glob |
Lists files matching a pattern |
SearchCode |
Grep-style search across the codebase |
EditFile |
str_replace edit with exact match required |
WriteFile |
Creates a new file (refuses if path already exists) |
RunArtisan |
Runs php artisan <command> against an allowlist |
RunTests |
Runs Pest or php artisan test, returns full output |
RunPint |
Formats files with Laravel Pint |
RunShell |
General shell access, gated by your shell mode |
The tools map to exactly what a developer does when working in a Laravel app. No generic file-system sprawl, no web browsing, no external API calls. Just the operations that matter for building Laravel projects.
The agent can run shell commands, and "an AI running shell commands" is the kind of thing that should give you pause. Tackle ships with four shell modes:
off: No shell commands, period.allowlist: Only commands in your configured allowlist are permitted.approve (default): Every shell command is shown to you and requires confirmation before it runs.yolo: Unrestricted. Use this only on throwaway environments.You set the default in your .env and override it per session:
php artisan ai:code --shell=approve
php artisan ai:code --shell=off
php artisan ai:code --yolo
Protected paths are blocked at the code level, not by instructing the agent to stay away from them. .env, storage/, vendor/, and .git/ cannot be read or written regardless of what the model wants to do. This matters because prompt-based restrictions can be reasoned around. Code-level restrictions cannot.
There is also a hard budget cap. Set AI_CODE_BUDGET=1.00 in your .env and the session terminates when spending hits that limit. The agent does not overshoot because it cannot.
Three steps:
composer require jordandalton/laravel-tackle
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
php artisan vendor:publish --tag="laravel-tackle-config"
Then add your API key to .env:
ANTHROPIC_API_KEY=sk-ant-...
And run it:
php artisan ai:code
If the built-in tools do not cover something specific to your app, you can add tools without modifying the package. Extend AbstractTool, extend DefaultCodingAgent to register it, and rebind the CodingAgent contract in a service provider:
class LookupCustomer extends AbstractTool
{
public function name(): string
{
return 'LookupCustomer';
}
public function description(): string
{
return 'Look up a customer record by email address.';
}
public function parameters(): array
{
return [
'email' => ['type' => 'string', 'description' => 'Customer email address'],
];
}
public function handle(Request $request): string
{
$customer = Customer::where('email', $request->string('email'))->first();
return $customer
? json_encode($customer->only(['id', 'name', 'email', 'plan']))
: 'No customer found with that email.';
}
}
The Request object gives you typed accessors (string(), boolean(), integer(), get(), all()). Returning a string explanation instead of throwing lets the agent handle refusals gracefully without breaking the session.
Laravel Tackle is open source and on GitHub now:
github.com/JordanDalton/laravel-tackle
One word of caution: laravel/ai is new and fast-moving, so breaking changes upstream are possible before it stabilizes. Always start from a clean, committed git state so every file the agent touches is reviewable. The discipline here is simple: git diff before you commit anything the agent wrote.
If you've wanted an AI coding harness that understands your Laravel project without spending ten minutes orienting it each session, Tackle is worth a look. Star it if it's useful, open an issue if something's broken.
Written by Jordan Dalton. More at jordandalton.com.
Take the ideas in here from concept to working software in one focused day.
Book a build day →