Laravel Tackle: el agente de IA que vive dentro de tu app

Laravel Tackle es un harness de agentes de IA que se instala con Composer y corre como comandos Artisan dentro de tu propia aplicación. No es una CLI que abre tu carpeta desde fuera: vive dentro del framework, así que puede listar tus rutas, consultar tu base de datos, leer una excepción de Telescope y formatear con Pint porque esas herramientas ya están ahí.
Y la parte que de verdad me interesó: los límites están escritos en PHP, no pedidos por prompt. Las rutas protegidas, la lista blanca de comandos y el techo de gasto no son instrucciones que el modelo pueda decidir ignorar, son código que se ejecuta antes que él.
Lo publicó Jordan Dalton y Laravel News le dedicó una nota, que es por donde le llegó visibilidad. Aviso de siempre: esto sale del repositorio, del README y de Packagist, no de haberlo puesto en producción yo.
La diferencia real con Claude Code
Cuando usas Claude Code en un proyecto Laravel, el agente ve archivos. Sabe leer PHP, entiende el framework porque lo tiene en el entrenamiento, y si le pones Boost aprende un poco más. Pero está fuera: para saber qué rutas existen tiene que abrir los archivos de rutas y deducirlas.
Tackle invierte eso. Al correr como comando Artisan está dentro del ciclo de vida de la aplicación, con el contenedor de servicios levantado. Cuando quiere saber las rutas, llama a la herramienta ListRoutes, que es tu route:list de verdad, con los middlewares resueltos. Cuando quiere entender un fallo, ReadTelescopeEntry le da la entrada real. Puede correr RunLarastan o consultar la base con QueryDatabase.
La arquitectura son tres capas, y así las describe el propio README:
| Capa | Qué es |
|---|---|
| Tools | Primitivas de acción: ReadFile, EditFile, RunTests, RunShell. Cada una pasa por PathGuard y por la política de shell antes de ejecutarse. |
| Agents | Clases que implementan CodingAgent, reciben un prompt, llaman herramientas y devuelven un resultado. Vienen tres, puedes añadir las tuyas. |
| Safety | PathGuard bloquea lecturas y escrituras fuera del workspace. BudgetTracker aborta la sesión al pasar el límite de gasto. Los modos de shell controlan la ejecución de comandos. |
La frase que cierra esa tabla en el README es la tesis del proyecto entero: "All enforced in PHP, not advisory".
Los comandos
composer require jordandalton/laravel-tackle
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
php artisan vendor:publish --tag="tackle-config"Requiere PHP 8.3 o superior y Laravel 12 o 13. La API key va en .env, por defecto ANTHROPIC_API_KEY, aunque el proveedor se cambia con dos variables porque debajo está laravel/ai:
AI_CODE_PROVIDER=ollama
AI_CODE_MODEL=deepseek-coder-v2Los cinco comandos que importan:
ai:codees la sesión interactiva. Tiene plan mode, slash commands, entrada de imágenes, memoria de sesión y compactación automática de contexto.ai:runes el mismo agente sin terminal: devuelve código de salida y JSON opcional, para pipelines.ai:fixataca un problema concreto a partir de una excepción pegada, un ID de Sentry o un enlace a un issue de GitHub.ai:reviewrevisa un diff o un pull request en modo solo lectura y publica comentarios en línea con niveles de severidad, con veredicto que va de "LGTM" a "Needs changes".ai:upgradeplanifica subidas de versión mayor de paquetes de Composer leyendo las guías del propio paquete y validando con tus tests.
Hay además tackle:init, que crea un TACKLE.md en la raíz con convenciones, límites y trampas del proyecto. Si no existe, el agente cae a AGENTS.md o CLAUDE.md, con un tope de 20.000 caracteres para no fundirse el contexto. Reutilizar los archivos que ya tienes en vez de exigir el suyo es la decisión correcta.
La configuración es el producto
Aquí es donde Tackle se separa del resto, y merece leerse el config/tackle.php entero porque los valores por defecto están pensados por entorno:
'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),
'production' => env('AI_CODE_WORKTREE', true),
],
'protected_paths' => ['.env', '.env.*', 'storage/*', 'vendor/*', '.git/*'],
'budget_usd' => env('AI_CODE_BUDGET', 1.00),Léelo despacio, porque cada línea es una decisión que casi nadie más toma:
En producción el shell está apagado y lo único que puede correr es route:list. En producción el worktree está activo por defecto, así que las ediciones van a un árbol temporal de Git y no a los archivos vivos. Los comandos que no están ni en la lista blanca ni en la de destructivos se rechazan directamente, no se preguntan. Y hay un presupuesto de un dólar por sesión que aborta cuando se pasa.
Los cuatro modos de shell van de off (rechaza todo), a allowlist (solo composer, npm, php artisan), a approve (el default: confirmación por comando, y "permitir siempre este comando exacto" se guarda en .tackle/permissions.json), a yolo, que el propio README marca como peligroso y solo para CI o entornos de confianza total.
Compara eso con el patrón habitual de la industria, que es un AGENTS.md diciéndole al modelo "por favor no toques .env". Una de las dos cosas es una garantía y la otra es una esperanza.
Subagentes, y por qué están bien planteados
Vienen dos activados: explorer, de solo lectura, para localizar archivos y trazar cómo funciona una feature; y test-writer, que escribe un test de Pest y lo corre.
La razón de existir la explica bien el README: leer veinte archivos para responder "¿cómo funciona la facturación aquí?" ya no cuesta veinte archivos de contexto en la conversación principal. La exploración pasa en el hijo, vuelven solo las conclusiones.
Las garantías son las que uno querría y rara vez encuentra: presupuesto compartido (el subagente cuenta contra el mismo BudgetTracker, así que delegar no puede saltarse tu límite), la misma capa de seguridad, un solo nivel de profundidad, sin preguntas al usuario, y fallo blando (si un subagente revienta devuelve el error al padre, que sigue).
El autocurador de colas
Esta es la parte que no tiene equivalente claro en otras herramientas, y la que justifica el nombre de "harness" en vez de "asistente".
Cuando un job de cola o una tarea programada falla, un runtime dirigido por eventos levanta un agente por su cuenta, sin nadie mirando, en un worktree de Git aislado, diagnostica, parchea, corre los tests y abre un pull request.
Se activa aparte:
php artisan vendor:publish --tag="tackle-migrations"
php artisan migrate
php artisan queue:work --queue=healerLos detalles que muestran que esto se pensó con la cabeza puesta en producción: un job puede excluirse con el atributo #[Healable(false)]; AI_CODE_HEALING_THRESHOLD retrasa la curación hasta que el job falle varias veces, para que los fallos transitorios se resuelvan solos sin quemar tokens; todo intento se registra en la tabla tackle_healing_log con resultado, tests y el PR asociado; y si los tests fallan, el parche no se mergea.
Es decir: no arregla producción a tus espaldas, prepara un candidato y te lo pone en una cola de revisión. Esa distinción es todo.
El servidor MCP
Tackle también expone sus herramientas por MCP, lo que te deja usarlo desde fuera:
claude mcp add tackle -- php artisan tackle:mcpA partir de ahí Claude Code, Cursor o Zed acceden a ListRoutes, QueryDatabase, ReadTelescopeEntry y RunLarastan. Y lo importante: las restricciones de rutas, listas blancas y límites de base de datos siguen aplicándose sin importar quién llama. Los guardarraíles no viven en el cliente, viven en el paquete.
Ese detalle convierte a Tackle en algo más interesante que un competidor de Claude Code: puede ser la capa de permisos debajo de Claude Code. Es una respuesta concreta a algo que ya discutí en si PHP y Laravel son buenos lenguajes para programar con agentes.
Dónde está lo frágil
Y ahora la parte que el entusiasmo se salta. Nada de esto invalida el proyecto, pero cambia bastante cuándo lo adoptas.
La base es un 0.x que se mueve. Tackle está construido sobre laravel/ai, el SDK de IA oficial de Laravel, que sigue en versiones cero. El propio README lo documenta como riesgo conocido, y la redacción es más seria de lo que parece: laravel/ai "reshapes its Agent contract on most 0.x minors", y una firma de método incompatible es un fatal en tiempo de compilación, o sea que la clase del agente no se puede ni declarar y se cae con ella cualquier comando.
Tackle declara compatibilidad con >=0.1 <0.11. Comprobado ayer contra Packagist: laravel/ai publicó la 0.11.0 el 19 de agosto de 2026, justo fuera de ese rango. No rompe nada, Composer resolverá una anterior, pero significa que la versión más reciente de la base todavía no está cubierta por su matriz de CI. Es el riesgo que el autor documentó, materializándose a la semana.
Es muy joven y muy pequeño. El repositorio se creó el 13 de junio de 2026. Tiene 57 estrellas y 205 descargas totales en Packagist. El 16 de agosto salieron cuatro releases (1.27.0 a 1.27.3) en veintiocho minutos. Eso es un mantenedor atento, y también un proyecto que todavía se está encontrando. La licencia es MIT, declarada en composer.json y en el README, aunque el repositorio no tiene archivo LICENSE.
El agente no tiene internet. Es una limitación declarada en la v1: no puede leer documentación, ni buscar en la web, ni llamar APIs externas. Solo trabaja con los archivos del workspace. Para ai:upgrade esto es notable, porque significa que las guías de actualización tienen que estar ya en vendor/.
El presupuesto es estimado, no exacto. Se calcula con conteo de tokens contra un catálogo interno de precios. Lo que te cobre el proveedor puede diferir. Con un dólar de límite por defecto, la diferencia es irrelevante; si lo subes a cincuenta, ya no.
No hay commits automáticos en modo normal: las ediciones quedan sin stagear. En modo worktree puede commitear y empujar a una rama de PR existente, pero siempre llamando antes a ConfirmAction.
Entonces, ¿lo instalo?
Tres respuestas según dónde estés.
Si te interesa el problema de los permisos, sí, y ya. Es la implementación más seria que he visto de la idea de que los límites de un agente deben ser código y no cortesía, y el modelo por entorno con producción en solo lectura debería copiarse en todas partes. Aunque no lo adoptes, léete su config/tackle.php.
Si buscas tu agente de programación diario, todavía no. Claude Code y compañía están años por delante en la experiencia interactiva, tienen internet, y no dependen de un 0.x que rompe contratos. Tackle no está compitiendo ahí de verdad, y su servidor MCP sugiere que su autor tampoco cree que deba.
Si tienes colas que fallan de noche, es lo más interesante del artículo. Un autocurador que diagnostica en un worktree aislado, corre los tests y abre un PR es una categoría casi vacía. Yo lo probaría en staging, con el threshold alto, y mirando el tackle_healing_log durante un par de semanas antes de creerle nada.
Preguntas frecuentes
¿Tackle reemplaza a Claude Code o a Cursor?
No, y su propio servidor MCP lo deja claro: está pensado para poder correr debajo de ellos, aportando herramientas conscientes de Laravel y los guardarraíles. Como agente interactivo diario está muy por detrás de las herramientas dedicadas, entre otras cosas porque no tiene acceso a internet.
¿Necesito una API key de Anthropic?
Es el proveedor por defecto, pero no es obligatorio. Al construirse sobre laravel/ai acepta OpenAI, Gemini, Groq u Ollama en local, y se cambia con AI_CODE_PROVIDER y AI_CODE_MODEL. Con Ollama puedes poner los precios a cero y el presupuesto deja de aplicar.
¿Es seguro dejarlo tocar producción?
Sus valores por defecto están del lado prudente: en producción el shell viene apagado, el único comando Artisan permitido es route:list y el aislamiento por worktree está activo. Dicho eso, es un paquete de dos meses sobre una dependencia 0.x, así que yo empezaría en local con el modo approve, que pide confirmación comando por comando.
¿Qué versiones de PHP y Laravel necesita?
PHP 8.3 o superior y Laravel 12 o 13. Un detalle del README que conviene leer: laravel/ai 0.1.x requiere PHP 8.4, así que en PHP 8.3 Composer resolverá la 0.2 o posterior.
Recursos
- Documentación: tackle.jordandalton.com
- Código, README completo y riesgos conocidos: github.com/jordandalton/laravel-tackle
- Paquete: packagist.org/packages/jordandalton/laravel-tackle
- La base sobre la que corre: github.com/laravel/ai
- Cobertura: Laravel News