Laravel Tackle, створений Джорданом Далтоном, - це AI-агент для кодування, який працює як Artisan-команди всередині вашого додатка. Завдяки тому, що він завантажується разом із фреймворком, його інструменти - це ті самі, які ви використовуєте щодня: він може вивести список маршрутів, прочитати виняток із Telescope, виконати SELECT запит до бази даних і запустити Pint після завершення редагування.
Запуск всередині додатка також змінює місце розташування захисних механізмів. Обмеження шляхів, дозволений список Artisan-команд і ліміт витрат на сесію - це PHP-код у пакеті, а не інструкції в промпті, які модель може проігнорувати. Пакет побудований на laravel/ai і за замовчуванням використовує Claude, хоча змінна AI_CODE_PROVIDER дозволяє переключитися на OpenAI, Gemini, Groq або локальну модель через Ollama.
Агенти та команди
Пакет постачається з кількома агентами:
ai:code - інтерактивна сесія: REPL із режимом планування, slash-командами, можливістю прикріплення зображень та історією, що зберігається між запусками
ai:run - той самий агент без підключеного терміналу: одне завдання, код виходу та --output=json, коли конвеєр потребує прочитати результат
ai:fix - запускає сфокусовану сесію виправлення з вставленого винятку, проблеми Sentry (--sentry=ID) або GitHub issue (--issue=N)
ai:review - читає diff або pull request і публікує знахідки як вбудовані коментарі з рівнями серйозності
ai:upgrade - переводить Composer-пакет через мажорну версію, працюючи з власним гайдом апгрейду пакета у vendor/
- Self-healer - спостерігає за невдалими завданнями черги та заплановими задачами, виправляє код в ізольованому worktree і відкриває pull request
- Tackle Remote - супутній пакет, що надає той самий інструментарій як UI в мобільному браузері, включаючи промпти підтвердження
Встановлення
Tackle потребує PHP 8.3 і Laravel 12 або 13. Встановіть його, потім опублікуйте обидва конфіги:
composer require jordandalton/laravel-tackle
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
php artisan vendor:publish --tag="tackle-config"
Опублікований config/ai.php вже містить блок Anthropic-провайдера, тому все, що залишилось - додати API-ключ у .env:
ANTHROPIC_API_KEY=sk-ant-...
Перехід на іншого провайдера потребує двох змінних. Ollama потребує ще двох, оскільки локальна модель не коштує нічого за токен і вбудований каталог цін не має для неї тарифу:
AI_CODE_PROVIDER=ollama
AI_CODE_MODEL=deepseek-coder-v2
AI_CODE_PRICE_INPUT=0
AI_CODE_PRICE_OUTPUT=0
Закомітьте або сховайте свою роботу перед першою сесією. Агент редагує файли на місці, якщо ви не увімкнете режим worktree, і git checkout -- . - це безпечний спосіб повернутися назад тільки якщо решта вашої роботи вже закомічена.
Сесія кодування
php artisan ai:code відкриває REPL. Введіть завдання, спостерігайте за потоком викликів інструментів і читайте git diff --stat, який Laravel Prompts відображає як блок нотаток після кожного кроку.
Режим планування - це прапорець, який варто знати першим. З --plan агент планування (тільки для читання) досліджує кодову базу і стрімить пронумерований план, що охоплює файли, зміни та ризики, перш ніж щось буде записано. Потім ви обираєте Execute, Revise або Cancel. Те саме працює для кожного завдання всередині сесії:
> /plan expire abandoned carts on a nightly schedule
Доступ до shell має чотири режими, які можна встановити для кожної сесії без торкання конфігу:
php artisan ai:code --off # RunShell відхиляє все
php artisan ai:code --approve # підтверджувати кожну команду (за замовчуванням)
php artisan ai:code --allowlist # тільки команди зі shell_allowlist
php artisan ai:code --yolo # без промптів взагалі
--off - це той, який варто використовувати для питань. Він залишає доступними інструменти читання, щоб ви могли запитати, як працює автентифікація в додатку, без можливості агента щось виконати.
Транскрипти зберігаються в storage/ai-code/ і відновлюються при наступному запуску, а --session=search-rewrite зберігає окремі історії для окремих потоків роботи. Коли розмова перевищує 60,000 символів, Tackle автоматично узагальнює старіші обміни та зберігає останні чотири повідомлення дослівно. /compact примусово робить це, а /clear видаляє історію.
Межі безпеки
Все в config/tackle.php перевіряється перед запуском інструменту, і жодна інструкція в промпті не може це перевизначити:
return [
'budget_usd' => env('AI_CODE_BUDGET', 1.00),
'shell' => [
'local' => env('AI_CODE_SHELL', 'approve'),
'staging' => env('AI_CODE_SHELL', 'approve'),
'production' => env('AI_CODE_SHELL', 'off'),
],
'artisan_allowlist' => [
'local' => ['make:*', 'migrate:*', 'db:seed', 'route:list', 'test'],
'staging' => ['migrate', 'route:list'],
'production' => ['route:list'],
],
'worktree' => [
'local' => env('AI_CODE_WORKTREE', false),
'staging' => env('AI_CODE_WORKTREE', false),
'production' => env('AI_CODE_WORKTREE', true),
],
'protected_paths' => ['.env', '.env.*', 'storage/*', 'vendor/*', '.git/*'],
];
protected_paths блокує як читання, так і запис, тому агент не може побачити ваш .env і процитувати його назад. Artisan-команди, які не входять ні до allowlist, ні до artisan_destructive, відхиляються відразу, а деструктивний список (migrate:fresh, db:wipe та інші) потребує підтвердження в терміналі. Бюджет - це жорстка зупинка: сесія перервається, коли оцінені витрати перевищать його, а попередження з'явиться на 80%.
Режим worktree покриває випадок, коли ви хочете прочитати diff перед тим, як щось потрапить у ваше робоче дерево. Редагування потрапляє в тимчасовий git worktree, заголовок сесії показує worktree: on, а diff stat за крок позначається як "Worktree changes (live files untouched)". Worktree очищаються після завершення сесії, а tackle:prune видаляє будь-які, залишені перерваним запуском.
Інструкції проєкту
Кожен агент завантажує TACKLE.md з кореня проєкту на початку сесії. php artisan tackle:init сканує composer.json, ваш тестовий фреймворк і структуру app/, а потім пише каркас із заголовками Conventions, Boundaries та Gotchas для вас, щоб заповнити:
**Conventions**
- Timestamps are stored in UTC and cast with `immutable_datetime`.
- Queued jobs must be idempotent, because workers retry three times.
**Gotchas**
- `Order::open()` excludes anything in the `pending_review` state.
- The `reporting` connection is a read replica, so writes against it throw.
Якщо немає TACKLE.md, Tackle відкочується до AGENTS.md, а потім до CLAUDE.md, тому інструкції, які ви вже зберігаете для інших інструментів, працюють без другого файлу. Вміст обмежений 20,000 символами для захисту вашого контекстного вікна та бюджету сесії, а рівень безпеки застосовується незалежно від того, що каже файл.
Перегляд pull request'ів
ai:review запускає агента тільки для читання над diff. Він має ReadFile, Glob та SearchCode, але не має інструментів редагування, і він читає повний файл навколо кожної зміненої функції перед коментуванням, тому знахідки базуються на більшому, ніж просто diff:
php artisan ai:review # staged та unstaged
php artisan ai:review --against=main # у стилі PR
php artisan ai:review --pr=118 --comment # опублікувати вбудовані коментарі в GitHub PR
Знахідки повертаються згрупованими за файлами на трьох рівнях серйозності, закінчуючи вердиктом LGTM, LGTM з незначними нотатками або Needs changes. --fail-on=critical перетворює цей вердикт у код виходу, що дозволяє workflow заблокувати злиття.
Повторний запуск проти pull request не повторює весь перегляд. Кожен опублікований перегляд вбудовує невидимий маркер, що записує head commit, який він охоплював; наступний запуск порівнює з ним, переглядає лише те, що було запушено з тих пір, повідомляє агенту, що він вже повідомляв, і виходить раніше з "Nothing new to review", якщо head не рухався. Force-push, який втрачає старий commit, відкочується до повного перегляду, а --full примусово запускає його на вимогу.
php artisan tackle:install review створює для вас каркас workflow:
name: Tackle Review
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: JordanDalton/tackle-review@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
fail-on: critical
Коли рев'юер відповідає на знахідку коментарем /tackle, ai:respond завантажує коментар і його потік, запускає агента кодування проти інструкції, пушить commit до гілки PR і відповідає в потоці з SHA та diff stat. Pull request'и з форків відхиляються в PHP, а checkout, який не відповідає head PR, перервається до запуску агента. Якщо коментар ставить питання, а не запитує зміну, агент відповідає і нічого не редагує. AI-асистований перегляд сам по собі не новий, але прийняття відповіді та пушинг commit'а з неї - менш поширене явище.
Самовиправлення завдань черги
Самовиправлення вимкнено за замовчуванням. Встановіть AI_CODE_HEALING_ENABLED=true, опублікуйте та запустіть міграцію, і запустіть воркер на черзі healer:
php artisan vendor:publish --tag="tackle-migrations"
php artisan migrate
php artisan queue:work --queue=healer
З цього моменту невдале завдання викликає подію Laravel JobFailed, слухач Tackle відправляє завдання HealJobFailure до цієї виділеної черги, і агент виправлення запускається в свіжому worktree на гілці tackle/heal-{id}. Він отримує клас винятку, повідомлення та трасування стеку, плюс повний запис із Telescope, коли він встановлений. Агент застосовує мінімальне виправлення, запускає ваш тестовий набір, а потім або відкриває pull request із своїм обґрунтуванням як описом, або, в режимі patch, зливається у вашу робочу гілку та перевідправляє оригінальне завдання. Невдалі заплановані завдання проходять тим же шляхом через ScheduledTaskFailed.
Деякі завдання не повинні автоматично виправлятися. Атрибут утримує healer від них:
use Tackle\Attributes\Healable;
#[Healable(false)]
class IssueRefund implements ShouldQueue
{
public function handle(): void
{
// Пропускається повністю, навіть із увімкненим виправленням.
}
}
Слухач перевіряє його через рефлексію перед відправкою чого-небудь. AI_CODE_HEALING_THRESHOLD=3 - м'якша версія тієї ж ідеї, що затримує виправлення, доки завдання не провалиться тричі, щоб тимчасові збої мали шанс вирішитися самостійно.
Кожна спроба записується в таблицю tackle_healing_log, незалежно від того, спрацювало воно чи ні:
php artisan tackle:healing-log --type=job
php artisan tackle:healing-log --outcome=patched --limit=50
Таблиця показує, що провалилося, чи пройшли тести, результат і посилання на PR або гілку. В режимі patch невдалий запуск тестів відкочується до відкриття pull request, тому нічого не зливається неперевіреним, а healer завдання запускаються з $tries = 1, щоб зламаний healer не міг зациклитися.
Обслуговування інструментів через MCP
Інструменти, що розуміють Laravel, корисні поза власними агентами Tackle. tackle:mcp обслуговує їх через MCP на stdio, тому Claude Code, Cursor або Zed можуть викликати ListRoutes, QueryDatabase, ReadTelescopeEntry та RunLarastan проти вашого додатка:
claude mcp add tackle -- php artisan tackle:mcp
Відкритий набір надходить із config('tackle.mcp.tools') і за замовчуванням включає інструменти читання та аналізу без запису файлів і без shell. Охоронці шляхів, дозволений список Artisan і обмеження бази даних тільки SELECT все ще застосовуються, оскільки інструменти виконують їх незалежно від того, хто їх викликає. AskUser та ConfirmAction відхиляються відразу, оскільки MCP-клієнт не має терміналу для відповіді на їхні промпти.
Два обмеження варто знати перед встановленням. Агент не має доступу до інтернету, тому він працює лише з файлів у вашому робочому просторі і не може завантажити документацію пакета. Ліміт витрат оцінюється з підрахунку токенів проти вбудованого каталогу цін, тому те, що фактично виставить рахунок ваш провайдер, буде трохи відрізнятися.
Tackle ліцензований під MIT і зараз у версії v1.27.3 на GitHub, з повною документацією на tackle.jordandalton.com.