AGENTS.md — capas 1–4, config, atajos, helpers y comandos DXPanelConsultas — eager load automático desde BelongsToColumn, caché de opciones relationship() y auditoría N+1/índicesResource::eagerLoadsForIndex() — fusiona with() manual y relaciones detectadas en la tablaSelectFilter/MultiSelectFilter y BelongsToField (filter_options_cache, TTL configurable)cursor_pagination, desactivada por defecto)panel:audit-rendimiento — informe de N+1 e índices sugeridos por resourceResourceQuery — contar/ids sin eager load; paginate soporta cursorpanel:doctor — aviso si hay resources con posibles N+1PanelListado — texto de rango adaptado a paginación cursorforms.validate_inline), borrador en localStorage (forms.draft_autosave), foco automático al abrir (forms.focus_on_open)import.guided_summary)index.bulk_preview)ManagesResourceFormModal — updatedForm, descartarBorradorFormulario, evento panel-borrador-limpiadoPanelLayout — helpers para forms, import guiada y bulk previewlocalStorage (column-toggle, panelColumnas)quick-view-drawer, abrirVistaRapida)localStorage (filter-presets, panelPresetsFiltros)seleccionGlobal, bulk_select_all_max)ResourceQuery::contar() / ids() — totales e IDs para selección masiva globalPanelLayout — flags column_toggle, quick_view, filter_presets, select_all_matchingbulk-bar, limpiarSeleccion)copy-list-link)↑/↓ navegan filas, Enter abre editarPanelListado — helper de rango de resultados y objetivos de cargaconfig/performance — debounces, skeleton, loader SPA y animaciones ajustables (PanelRendimiento)busy inmediato; skeleton a 50ms (antes 150ms sin feedback)layout.table_sticky_header (scroll interno con thead sticky)layout.index.clickable_rows, abrirRegistro)md (layout.index.mobile_cards)quitarCriterio)/ o Ctrl+F enfoca el buscador del listadoCriteriosActivosIndex — helper para etiquetas y valores de chipsperPage, cabecera y pie de paginaciónwire:model.live en selectsbody para no recortarse por el overflow: hidden de la animación del panelgrid (sin saltos bruscos)wire:ignore en panel y selects, debounce 300ms, sin skeleton al filtrar--panel-form-radiusbody con posición fija (no se recorta dentro del panel de filtros)<x-panel::searchable-select> con búsqueda, teclado y opciones con padding/espaciado mejoradoinput[type="date"]date_from / date_to (ES/EN)layout.filters.mode (collapsible | inline), default_open, remember_state (localStorage)inline conserva el diseño anteriorPanelLayout::modoFiltros(), filtrosAbiertosPorDefecto(), recordarEstadoFiltros()filter-fields.blade.php y filters-panel.blade.php; icono sliders-horizontalborder-collapse: separate + esquinas superiores en th y overflow: hidden en el wrap; elimina el efecto de columnas cuadradas dentro de un contenedor redondeadopartials/table-footer.blade.php: «Por página» + selector y controles de página en fila única (flex-wrap: nowrap); resumen «Mostrando…» oculto en el pie de tabla--panel-input-radius y --panel-form-radius; radio por defecto 1rem en theme.radiuspanel-form-card) y secciones con sombra suave y más espaciopanel-rich-text-*, panel-repeater-item, panel-file-input)Escapepartials/empty-table.blade.php: mensajes distintos para papelera, búsqueda sin resultados, filtros activos o lista vacía; CTA para crear o limpiar búsqueda/filtrospanel-search-clear)position: sticky al hacer scroll; contenedor panel-table-scroll sin overflow: hidden en el wrapfocus-visible en botones, inputs, navegación y acciones de filaEscape--panel-font se emitía con entidades HTML (') porque Blade escapa {{ }} dentro de <style>; la fuente del panel nunca cargaba. Cambiado a {!! $font !!} (valor de config de servidor, sin riesgo XSS). Ahora font-family: var(--panel-font) resuelve correctamente a la fuente configuradalayouts/error.blade.php simplificado al máximo: sin cabecera de marca (icono/nombre de la app), sin tarjeta, sin badge de icono y sin fondo decorativo. Solo código del error, título, descripción y botones, centrados sobre el fondo del panel, con la misma fuente del panel (--panel-font vía ThemeResolver)x-panel::icon — el layout no usa SVGs sueltos: el toggle de tema usa sun/moon y los botones de acción llevan icono (arrow-left, layout-dashboard, rotate-ccw)errors/500.blade.php usaba panel::panel.errors.500.action pero las traducciones definían action_retry; se mostraba la clave cruda al usuario. Renombrada la clave a action en lang/es y lang/en, coherente con 419/429/503tests/Feature/ErrorPagesTest.php cubre el render de las 7 vistas (403, 404, 419, 422, 429, 500, 503), que no queden claves sin traducir, que la 503 muestre el mensaje de mantenimiento y que la 500 no filtre el mensaje interno de la excepciónx-panel::icon — eliminados los SVG inline de las 7 vistas de error; ahora usan <x-panel::icon name="..."> igual que el resto del panel. Añadidos al componente icon.blade.php los iconos Lucide clock, alert-circle, alert-triangle, zap y wrench que faltabanstroke-width="2" con paths Lucide (igual que el componente x-panel::icon); normalización tipográfica en html (line-height, font-feature-settings, -moz-osx-font-smoothing); @[@media](https://github.com/media) escapado en Blade; fuente aplicada a html además de body[@include](https://github.com/include)('panel::partials.brand-mark') usaba panel-brand-mark (CSS compilado) y h-4 w-4 (Tailwind); sustituido por SVG inline propio; el layout ya no depende de ningún asset externo403, 404, 419, 422, 429, 500, 503) con el tema del panellayouts/error.blade.php — layout auto-contenido (sin Vite/Livewire), aplica CSS variables del tema y dark/light modeerrors.* en ES y EN con títulos, descripciones y acciones por códigopanel-errors → php artisan vendor:publish --tag=panel-errors copia las vistas a resources/views/errors/livewire:navigate falla o tarda (red, 500, sesión/BD), el overlay ya no queda bloqueado: watchdog configurable, Escape para cerrar y API window.panelSpaLoader.ocultar()defaultPrevented) ya no muestra el loaderlayout.spa_loader (bool), layout.spa_loader_timeout_ms (default 20000), layout.spa_loader_escape (default true)scripts/verificar-release.php + composer release:check.github/workflows/release.yml en tags v*panel-demo/DEPLOY.md + render.yaml (Render.com)PUBLISHING.md actualizado a v0.36+ (checklist, upgrade-config, demo online)PanelRelacionesGuia) con preview de pestañasPanelMultiPanelGuia) con diagrama y código copiablemulti_panel en PanelDocumentacionPanelRelacionesGuiaTest, PanelMultiPanelGuiaTest, playground relations/multiImpersonationController / LogoutController — Redirect:: en lugar de redirect() (conflicto con Livewire Redirector)/admin/*); smoke import CSV y suplantaciónpanel:doctor — avisa si faltan claves en config (panel:upgrade-config --dry-run)InstallPanelStarterTest, InstallPanelMultiTestpanel-demo: playground en /playground + smoke testpanel-demo en PHP 8.2, 8.3 y 8.4composer updatepanel:upgrade-config — fusiona config/panel.php con claves nuevas del paquete (--dry-run, backup .bak)PanelConfigUpgrader — fusión recursiva y listado de claves añadidaspanel:doctor — comprueba que panel_route() esté cargada y operativapanel-demo ampliado: import, página custom, permisos editor/admin, upgrade-configPanelConfigUpgraderTest, UpgradeConfigCommandTest, NavigationBuilderTestpanel:install --saas — Tenant, TenantResource, vistas panel/saas/*, extensiones saas-plan, slot y widgetPanelSaasGuia — guía CLI en playground Avanzado → Extensionesstubs/saas/InstallPanelSaasTestpanel_route() — definición correcta en helpers.php y prefijo \ en llamadas desde namespaces PHPPanelExtensionesGuia — receta end-to-end campo → columna → widget (tipo «rating») en playground Avanzadopanel-demo — PanelSmokeTest (login, dashboard, productos, panel:doctor)smoke-panel-demo en .github/workflows/panel-tests.ymllayout.modeimport y permisos en resaltado del playgroundPlaygroundDemo — datos demo para import y permisosseleccionarSeccionTecnica() resalta la zona al abrir import o permissionspanel:install --multi — genera panel-admin.php, panel-cliente.php y raíz panels en config/panel.phppanel:doctor — comprueba multi-panel (paths únicos, recuento de paneles)sidebar.after, main.before, topbar.end en el escenario demostubs/multi/panel-admin.stub.phppanel:install --multi migra la config actual a panel-admin.php si aún no existeconfig/panel.php → panels + defaultPanelManager — contexto por panel (config, resources, widgets, slots)panel_route() — helper de rutas consciente del panel actual (panel.* o panel.{id}.*)SetCurrentPanel — aplica config del panel en cada requeststubs/multi/panel-cliente.stub.phppanel.admin.dashboard, panel.cliente.login, etc.panels o vacío): rutas legacy panel.* sin cambiosResourceRegistry y PageRegistry con caché por panelpanel:scaffold — resource + policy opcional + widget opcional en un comando (--policy, --widget=stat|chart|resource-count)panel:install --starter — kit completo: navigation, PostResource, modelo Post, migración, PostCountWidget y parche automático de config/panel.phpsidebar.before y main.afterpanel:install --demo sigue disponible; --starter lo amplía con modelo, migración y widgetsidebar | topbar | dual + sidebar_position left/rightsidebar.before, main.after, topbar.end, etc.import.upsert, import.upsert_key, Resource::importUpsertKey()table_striped, table_compact, selector per_page en listadosnavigationBadge(), hiddenFromNavigation(), perPageOptions()theme.presets_file para presets propios en la apppanel:install --demo — navigation stub + PostResource ejemplotitle_prefix / title_suffixglobal_search)PanelLayout — densidad, ancho contenido, sidebar colapsable, breadcrumbs, enlaces footerauth_ui — layout centered|split, fondo, imagen lateral, tagline de marcacustomization — CSS inline y vista Blade en <head>favicon, logo_height, taglineRepeaterField — filas repetibles con columnas configurables (JSON)PanelLayoutTestlocalStoragePanelExtensions facade: registrar vistas de campos/columnas y widgets desde código o config/panel.php → extensionstheme.preset: minimal, corporate, contrast, ocean (config/panel-theme-presets.php)ColorField, DateTimeField, KeyValueField, CustomFieldColorColumnpanel:upgrade-views — detecta vistas publicadas desactualizadas (--dry-run, --force)ExtensibilityTestThemeResolver resuelve tema vía ThemePresets (preset + overrides)WidgetRegistry fusiona widgets de config y extensiones registradasPanelImpersonation, config impersonation, RowAction «Entrar como», widget en sidebar, ruta panel.impersonation.leavePanelImpersonationTestmylaraveltools/minimalist → mylaraveltools/panel (composer replace para migración)Package::DISPLAY_NAME → Panel; README reescrito como guía para usuario finalTextField ya no es final — EmailField puede extenderlaauth-loading-text — texto de carga en botones auth con puntos animados (Entrando / Registrando)registering (ES/EN)navigate: false) — sin loader SPA ni porcentaje tras el POSTPackage::VERSION alineado con el changelog (sidebar muestra v0.20.0)wire:loading solo durante la petición)mobile-bar — barra sticky con hamburguesa en modo sidebar (móvil)sidebar, topbar y dual: columna flex, menú off-canvas; grid de dual solo en desktopdual/topbar (eliminada del page-header)footer_links del sidebar ocultos en móvil; sin enlace automático al playground en el footerGET /playground (panel.playground): personalización en vivo de config/panel.php y ChartWidget sin login->options()panel:doctor — valida config, ruta playground, Livewire navigate, Tailwind, Spatie, vistas publicadaspanel:make-widget — stubs chart|stat|resource-count|view en app/Panel/Widgets/documentation.enabledconfig/panel.php → widgetsPanelDoctor, footer playgroundpanelPlaygroundSincronizarGraficos)[@json](https://github.com/json) + getAttribute)wire:mouseleave y optional chaining en handlers Livewire del playgroundResourceImporter::analyzePath(), modal en dos pasos, config import.previewResourceImporterTesthasOne (ficha técnica) y morphMany (reseñas polimórficas)reviewable_id / reviewable_typeViewWidget — widgets Blade custom en dashboard (->columnSpan())ChartWidget::themeColors() — colores desde config('panel.theme.colors') vía ThemeResolver::chartColors()progression — línea con puntos pulsantes (plugin panelPulse)doughnut y runtime centralizado de gráficospanel-theme-changed) y en navegación SPA"progression" is not a registered controller (tipo resuelto a line)--force)ResourceImporter, modal en listados, config panel.import.enabledLocaleSwitcher, panel.locales, sesión panel.localehasOne(), morphMany(), morphToMany()ChartWidget — gráficos bar/line/pie en dashboard (Chart.js CDN)panel.auth.email_verification, middleware EnsurePanelEmailVerified, rutas /email/verifyEnsurePanelEmailVerifiedPanelLocale::resolve() prioriza sesión del usuariomylaraveltools/minimalist (antes gallardev/minimalist)Panel\Minimalist → MyLaravelTools\Panel (alineado con MyLaravelTools\Alertas)navigate: true + loader en layout guest); Livewire Auth\Login; guest sin Alpine en body/admin/login parpadeo / formulario invisible — spa-navigation ya no elimina .panel-auth-shell al llegar a rutas auth; loader SPA omitido en destinos auth; brand link sin wire:navigatepanel-spa-loader--fullscreen en layout guest; CSS dentro del breakpoint desktop; lock JS durante transición post-loginmylaraveltools/alertas está instalado; si no, error en campo email (eliminado resumen duplicado en la vista)return tras fallo de auth; locale en requests Livewire; mensajes ES en PanelValidation; tema auth reaplicado tras morph LivewireRoleResource y PermissionResource integrados (Spatie) — /admin/resources/roles y /admin/resources/permissionsPermissionsField / PermissionsColumn — asignación de permisos en roles (syncPermissions)SpatiePermissions, SpatieResourceRegistrarpanel.permissions.resources (default true) y panel.permissions.manage_permission (default manage users)PermissionsFieldTest, SpatieResourceRegistrarTest, ResourceRegistrySpatieTestResourceRegistry — registra built-ins solo si el host no define el mismo slugSpaLoaderTest — comprueba markup del loader con %, script de progreso y page-header en el layout<x-panel::page-header> (título + miga de pan)sidebar | main (sin fila de header)0%–100%) en el anillo; cubre desde top: 0panel:install — publica config/livewire.php si falta y desactiva navigate.show_progress_barpanel.version (null = versión del paquete con prefijo v)<x-panel::page-header>; show_progress_bar => falsepartials/header.blade.php.panel-modal-*) — no dependen solo de Tailwindpanel-scroll-lock) y resetea posición al navegar/admin/profile para editar nombre, email y contraseñapanel.profile.enabled (default true)PanelAuth::user() y PanelAuth::profileEnabled()-webkit-autofill y color de icono --panel-textpanel.auth.passwords.*) con panel.locale (default es)/admin/forgot-password y /reset-password/{token} con layout guestRolesField — asignación de roles Spatie en formularios (syncRoles tras guardar)RolesColumn — badges de roles en listadosField::afterSave() + FieldPayload::persistAfterSave() para campos relacionalespanel.auth.password_reset (default true)config/panel.php usa valores directos en lugar de env('PANEL_*'). Edita el archivo tras panel:install; compatible con config:cache. Opcional: envolver valores con env() en el config publicado del host.panel/minimalist → gallardev/minimalist (el vendor panel ya estaba reclamado en Packagist)MyLaravelTools\Panel{panel.path}/login y /registerPanelAuth — resolución de modelo User, rutas y redireccionesAuth\Login y Auth\Register con layout guest del panelRedirectIfPanelAuthenticated — invitados autenticados redirigen al dashboardpanel.auth — enabled, register, register_role, redireccionespanel.auth.* (es/en)AuthTest — feature tests de login, registro y logoutlogin_route / logout_route por defecto apuntan a panel.login / panel.logoutEnsurePanelAccess usa PanelAuth::loginRouteName()Page — páginas custom (informes, ajustes) fuera del patrón ResourcePageRegistry + PageDiscovery — auto-discovery en app/Panel/PagesPanelPage Livewire — renderiza vista Blade con data() y layout del panelpanel:make-page — genera Page + vista stubPanelPermission — integración opcional Spatie Laravel Permission o Gatepanel.pages, panel.permissionsEnsurePanelAccess — comprueba permiso panel_access cuando permisos están activospage en ítems; filtrado por permiso y canAccess/viewAnypanel.pages.showAlberto\Panel renombrado a MyLaravelTools\Panel (alineado con el paquete gallardev/minimalist)ResourcePolicy — base policy con deny-by-default para abilities del panelPolicyRegistrar — auto-registro Gate::policy() por Resource al bootPolicyResolver — detecta policy explícita ($policy) o convención {Model}Policypanel:make-policy — genera policy y enlaza el Resource si existepanel.policies — auto_register, namespaceResourceAuthorizerTest — tests de autorización con GateUserPolicy (solo admin), ProductPolicy (usuarios autenticados)ResourceAuthorizer — si hay policy registrada, usuario guest siempre denegadoUserResource demo migrado de hooks can*() inline a UserPolicy.panel-search).panel-filter-field)config('panel.forms_in_modal'), default true)Tab::make() to organize form sections into tabbed panels (Alpine.js)PdfExporter with list and bulk selection export (dompdf/dompdf)FormSchema tabs, PdfExporterTestforms_in_modal is enabledProductResource demo uses tabs for General / Precio y publicaciónview, edit, delete, restore, forceDelete, custom)wire:confirm)from / to)whereIn)Resource::recordTitle() — human-readable breadcrumb labels on show pagesResourceIndexTest (search, delete, confirm flow)Resource::rowActions() instead of hardcoded Blade#idExcelExporter, PhpSpreadsheet)DateField, FileField, RichTextFieldSection::make())lang/es, lang/en)How can I help you explore Laravel packages today?