PHPackages                             laravel-doctor/laravel-doctor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. laravel-doctor/laravel-doctor

ActiveLibrary[Database &amp; ORM](/categories/database)

laravel-doctor/laravel-doctor
=============================

Auditor determinista para codebases Laravel: seguridad, performance, Eloquent y arquitectura.

v0.1.1(1mo ago)10MITPHPPHP &gt;=8.2CI passing

Since Jun 2Pushed 1mo agoCompare

[ Source](https://github.com/PauloFragaDev/laravel-doctor)[ Packagist](https://packagist.org/packages/laravel-doctor/laravel-doctor)[ Docs](https://github.com/PauloFragaDev/laravel-doctor)[ RSS](/packages/laravel-doctor-laravel-doctor/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (6)Versions (26)Used By (0)

🩺 laravel-doctor
================

[](#-laravel-doctor)

### Tu agente escribe Laravel a medias. Esto lo diagnostica.

[](#tu-agente-escribe-laravel-a-medias-esto-lo-diagnostica)

**Auditor determinista para codebases Laravel** — seguridad, performance, Eloquent, arquitectura y Blade. Sin magia, sin falsos positivos de relleno: análisis estático del AST + (opcional) inspección en runtime.

[![PHP](https://camo.githubusercontent.com/fe60a3918bae3bc2ed56c6c5329ac0cb7462196b3061d0afb91fc4a241fe4172/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322b2d3737374242343f7374796c653d666c6174266c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://php.net)[![Laravel](https://camo.githubusercontent.com/d49f0258f1315b57117a8d26ada6bf32bd4742b2d4d7d6571c256f91a3fe652d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3130253230254332254237253230313125323025433225423725323031322d4646324432303f7374796c653d666c6174266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://laravel.com)[![CI](https://github.com/PauloFragaDev/laravel-doctor/actions/workflows/ci.yml/badge.svg)](https://github.com/PauloFragaDev/laravel-doctor/actions/workflows/ci.yml)[![Tests](https://camo.githubusercontent.com/b6f425679fdc658dd16dd63c663545e225ea7b105024f4d33a0095ed80c9e324/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d31373425323070617373696e672d3232633535653f7374796c653d666c6174)](#desarrollo)[![Packagist](https://camo.githubusercontent.com/2c3ea0256fe2b9aa85a237665eb829ffa0c905f724a66b0e965d14ec6745998c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c61726176656c2d646f63746f722f6c61726176656c2d646f63746f723f7374796c653d666c6174266c6f676f3d7061636b6167697374266c6f676f436f6c6f723d7768697465)](https://packagist.org/packages/laravel-doctor/laravel-doctor)[![License](https://camo.githubusercontent.com/2d238b27a91bb14ba9c2e1f126042acfd68cfbb525063be5a181f79c4058177e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d3030303030303f7374796c653d666c6174)](LICENSE)

---

¿Qué hace?
----------

[](#qué-hace)

Escaneas tu proyecto y obtienes una **nota de 0 a 100** con los problemas priorizados, listos para que tú —o tu agente de IA— los arregléis:

```
laravel-doctor — Score: 74/100 (Needs work)

[ERROR]   app/Http/Controllers/PayController.php:12  no-env-outside-config
    env() fuera de config/ devuelve null con la config cacheada en producción.
    → Mueve el valor a un archivo de config/ y léelo con config().

[WARNING] app/Models/User.php:8  no-mass-assignment-guarded-empty
    $guarded = [] deja todos los campos asignables en masa.
    → Define $fillable con los campos permitidos.

[WARNING] resources/views/show.blade.php:3  no-unescaped-blade-output
    Salida sin escapar de una variable ({!! !!}): XSS si el contenido viene del usuario.
    → Usa {{ }} (escapa solo) o sanea el HTML antes.

```

Cada hallazgo trae **dónde** está, **por qué importa** (impacto real, no jerga de linter) y **cómo** arreglarlo.

⚡ Inicio rápido
---------------

[](#-inicio-rápido)

**Requisitos:** PHP 8.2+ y Composer.

```
# Instálalo como herramienta global (una sola vez):
composer global require laravel-doctor/laravel-doctor

# Úsalo desde la carpeta que contiene tus apps:
cd /var/www/html
laravel-doctor          # abre el menú: elige proyecto y qué auditar
```

> El binario queda en `~/.composer/vendor/bin` (o `~/.config/composer/vendor/bin`). Si el comando no aparece, añade esa carpeta a tu PATH: `export PATH="$HOME/.composer/vendor/bin:$PATH"` (Composer te indica la ruta exacta al instalar).

**Dentro de una app concreta** (recomendado para habilitar `--boot`, que arranca la app):

```
composer require --dev laravel-doctor/laravel-doctor
./vendor/bin/laravel-doctor          # audita la app actual
```

### Desde el código fuente

[](#desde-el-código-fuente)

Si prefieres clonar el repositorio:

```
git clone https://github.com/PauloFragaDev/laravel-doctor
cd laravel-doctor && composer install
./bin/laravel-doctor                 # menú, usando el directorio actual como base
```

> Ojo: `composer install` en el repo clonado **no** crea por sí solo un comando `laravel-doctor`global (Composer solo enlaza binarios de las *dependencias*, no del propio paquete). Usa `./bin/laravel-doctor` por su ruta, o enlázalo: `ln -s "$(pwd)/bin/laravel-doctor" ~/.local/bin/laravel-doctor`.

> `laravel-doctor` sin argumentos abre la **terminal interactiva** usando el directorio actual como base. Ejecútalo desde la carpeta que contiene tus apps (p. ej. `/var/www/html`) o desde dentro de una app Laravel concreta — el menú la detecta sola.

🚀 Otros usos
------------

[](#-otros-usos)

```
# Auditar una ruta directamente (sin menú)
laravel-doctor inspect /var/www/html/mi-app

# Salida JSON estable (para CI o para tu agente de IA)
laravel-doctor inspect --json

# Análisis en runtime: arranca la app para auditar rutas y config reales
laravel-doctor inspect --boot

# Anotaciones inline para GitHub Actions
laravel-doctor inspect --github

# Solo los archivos cambiados (rápido en CI/PRs)
laravel-doctor inspect --diff              # vs HEAD
laravel-doctor inspect --diff origin/main  # vs una rama base
laravel-doctor inspect --staged            # solo lo que está en git add

# Menú apuntando a otra carpeta de proyectos
laravel-doctor tui --base /ruta/a/proyectos
```

`inspect` devuelve **exit code 1** si hay algún hallazgo de severidad *error* — perfecto para fallar un pipeline de CI.

🔍 Qué detecta
-------------

[](#-qué-detecta)

Dos modos que se complementan:

- **Estático** (por defecto): analiza el AST de PHP (vía `nikic/php-parser`) y las plantillas Blade. Rápido, seguro, **no necesita DB ni `.env`** → ideal para CI.
- **Runtime** (`--boot`): arranca tu app vía un comando artisan propio para auditar **rutas, middleware y config reales**. Si la app no puede arrancar, avisa y cae a estático.

CategoríaReglas🔒 **Seguridad**`no-env-outside-config` · `no-mass-assignment-guarded-empty` · `no-raw-sql-interpolation` · `no-hardcoded-credentials` · `no-unescaped-blade-output` · `no-route-without-auth` ⚡ · `no-debug-in-production` ⚡🚀 **Performance / DB**`prefer-exists-over-count` · `no-query-in-loop` · `no-all-then-filter` · `no-unindexed-foreign-key` ⚡🧬 **Eloquent**`no-save-in-loop-without-transaction` · `no-missing-casts-for-json` ⚡ · `prefer-bigint-foreign-key` ⚡🏗️ **Arquitectura**`no-fat-controller-method` · `prefer-form-request-validation` · `no-business-logic-in-route-closure`🎨 **Blade**`no-unescaped-blade-output` · `no-logic-in-blade`⚡ = requiere `--boot` (datos de runtime).

🛠️ Autofix
----------

[](#️-autofix)

Algunas reglas tienen arreglo automático y seguro (preservando el formato del código):

```
laravel-doctor inspect /ruta/app --fix
```

Hoy arregla `prefer-exists-over-count` (`->count() > 0` → `->exists()`) y `no-unescaped-blade-output` (`{!! $var !!}` → `{{ $var }}`). El resto de reglas se dejan al criterio del dev o de tu agente (que las arregla con la recomendación del hallazgo). Combina con `--diff` para arreglar solo lo que tocas.

🤖 Integración con agentes de IA
-------------------------------

[](#-integración-con-agentes-de-ia)

El diferenciador: laravel-doctor no solo señala los problemas, **se los enseña a tu agente para que los arregle**.

```
laravel-doctor install          # desde el repo clonado: ./bin/laravel-doctor install
```

Instala una *skill* para Claude Code, Cursor, Codex y compañía. El bucle es:

> **laravel-doctor encuentra → tu agente lee el JSON → arregla con la recomendación → re-corres → la nota sube.**

El contrato JSON (`--json`) es estable: `{ score, label, diagnostics: [{ id, category, severity, file, line, message, recommendation }] }`.

🖥️ Terminal interactiva
-----------------------

[](#️-terminal-interactiva)

`laravel-doctor` sin argumentos (o `laravel-doctor tui`) abre un **entorno full-screen** real (construido con [php-tui](https://github.com/php-tui/php-tui)): título a la izquierda y un **electrocardiograma animado** a la derecha (braille), paneles con bordes, navegación por flechas, **búsqueda en vivo** y detalle del hallazgo a color.

```
┌ 🩺 shop · Score 74/100 (Needs work)         ╴╴╴╴╴╴╴╴⡀╱╲⡀╴╴╴╴╴╴╴╴╴╴╴ │
├─────────────────────────────────────────────────────────────────────────┤
│ 🔎 (pulsa s para buscar)                                                  │
├──────────────────────────────────────────┬────────────────────────────────┤
│ SEGURIDAD (2)                            ││ Detalle                        │
│  › ✖ no-env-outside-config app/Pay.php:12││ ✖ no-env-outside-config        │
│    ✖ no-raw-sql-interpolation Repo.php:8 ││ env() fuera de config/…        │
│ PERFORMANCE (1)                          ││ → Mueve el valor a config()    │
│    ⚠ no-query-in-loop      app/List.php:3││                                │
└──────────────────────────────────────────┴────────────────────────────────┘
┌ ↑↓ mover · Tab/c categoría · s buscar · b runtime · Esc volver · q salir ──┐

```

- **↑↓** navega · **Enter** abre el proyecto · **s** (o `/`) activa la **búsqueda en vivo** · **Tab**/**c** cambia de categoría · **b** activa/desactiva el análisis runtime (`--boot`) · **Esc** vuelve · **q** sale.
- Paneles **proyectos** (inicio) y **hallazgos | detalle** (resultados): los hallazgos van **agrupados en bloques por categoría**, con score y badges de severidad a color y rutas relativas.

Requiere una terminal interactiva (TTY); en CI/pipes usa `inspect`.

📋 Línea base (codebases existentes)
-----------------------------------

[](#-línea-base-codebases-existentes)

¿Muchos hallazgos heredados? Congélalos en una **línea base** y a partir de entonces solo se reportan los **nuevos** — ideal para adoptar la herramienta en un proyecto legacy sin ahogarse:

```
laravel-doctor baseline /var/www/html/mi-app   # escribe doctor.baseline.json con lo actual
laravel-doctor inspect  /var/www/html/mi-app   # ahora solo muestra lo nuevo
laravel-doctor inspect  /var/www/html/mi-app --no-baseline   # ver todo, ignorando la base
```

La base se guarda por `(regla, archivo)` con un contador y **sin número de línea**, así que aguanta el desplazamiento del código. Commitea `doctor.baseline.json` en el repo.

⚙️ Configuración
----------------

[](#️-configuración)

Opcional. Crea un `doctor.config.php` (o `doctor.config.json`) en la raíz para desactivar reglas, ajustar severidades o excluir rutas:

```
