Lens for Laravel is a local-first accessibility auditing package for Laravel applications. It renders application pages in Chromium, runs axe-core, maps violations back to Blade/React/Vue source files, and exposes the results through a dashboard and the lens:audit Artisan command.
php artisan boost:add-skill webcrafts-studio/lens-for-laravel
Save this content to: AGENTS.md
# Lens for Laravel - Contributor Guide
## Project Scope
Lens for Laravel is a local-first accessibility auditing package for Laravel applications. It renders application pages in Chromium, runs axe-core, maps violations back to Blade/React/Vue source files, and exposes the results through a dashboard and the `lens:audit` Artisan command.
The current release is v3.6.0. It adds optional Lens MCP integration, tracked long scans, a first-install welcome, and compatibility with supported 0.x and stable 1.x Laravel AI/MCP SDK releases. v3.5 introduced the optional explicit AI model override, dashboard model information, bulk application, and provider-default temperature. v3.4 added authenticated scans and the OpenRouter, xAI, DeepSeek, and Mistral providers. New compatibility, WCAG selection, reliability, localization, source-mapping, and documentation work in this branch must otherwise be described as v3 functionality. Keep v2.0/v2.1 and incremental v3.0/v3.1/v3.2/v3.3/v3.4/v3.5 upgrade notes as historical documentation.
The package supports PHP 8.2+ and Laravel 10-13 for its core, non-AI features.
AI Fix is an optional integration with a narrower compatibility range:
- PHP 8.3+
- Laravel 12+
- optional `laravel/ai` Composer package
Do not add `laravel/ai` back to production `require`. Core installation on PHP 8.2 and Laravel 10/11 must remain possible. Code that touches the AI SDK must be guarded through `AiFixAvailability`.
## Main Components
- `src/Services/AxeScanner.php` - browser-based axe-core scans, including interactive states
- `src/Services/SiteCrawler.php` - sitemap and internal-link discovery
- `src/Services/HttpsClientConfiguration.php` - shared TLS behavior for HTTP and Chromium clients
- `src/Services/FileLocator.php` - heuristic Blade/React/Vue source mapping
- `src/Services/InteractionScriptParser.php` - state script validation and parsing
- `src/Services/BaselineManager.php` - stable CI baseline fingerprints
- `src/Services/ScanComparator.php` - URL- and state-aware history comparison
- `src/Support/UrlNormalizer.php` - host-independent URL path/query identity
- `src/Http/Middleware/SetLensLocale.php` - configured and session-selected package locale
- `src/Services/AiFixAvailability.php` - runtime and optional-SDK capability checks
- `src/Ai/AccessibilityFixAgent.php` - structured v3 AI agent options and provider-specific controls
- `src/Services/AiFixContextExtractor.php` - bounded semantic element/component extraction
- `src/Services/AiFixPromptRunner.php` - optional Laravel AI SDK boundary and response metadata
- `src/Services/AiFixer.php` - prompt orchestration, controlled retry, safe errors, and diagnostics
- `src/DTOs/AuthenticatedScanContext.php` - server-issued session cookies for authenticated scans
- `src/Services/AuthenticatedScanResolver.php` - guard login, allowlist, and auth-state restore
- `src/Support/Wcag.php` - supported WCAG versions, cumulative axe-core tags, and result-level classification
- `src/Console/Commands/LensAuditCommand.php` - CLI audit workflow
- `src/Console/Commands/LensInstallCommand.php` - first-install welcome
- `src/Mcp/` - optional local MCP tools, tracked runs, source context, history, and verification
- `src/Services/McpAvailability.php` - optional MCP SDK, runtime, and environment checks
- `routes/web.php` - dashboard JSON endpoints
- `resources/views/dashboard.blade.php` - dashboard interface
- `resources/views/state-recorder.blade.php` - visual interaction recorder
- `resources/views/report.blade.php` - PDF report
## Compatibility Rules
- Keep core code syntactically compatible with PHP 8.2.
- Keep core dependencies compatible with Laravel 10, 11, 12, and 13.
- Treat AI Fix as unavailable when the runtime or optional SDK is unsupported.
- Never let a missing AI SDK break scanning, crawling, history, PDF reports, previews, interactive states, or the CLI.
- Keep WCAG 2.0 as the default unless a breaking release explicitly changes it. WCAG 2.1 and 2.2 scans must include the earlier cumulative rule tags.
- Treat the WCAG version and conformance level as separate controls: `--wcag` selects 2.0/2.1/2.2, while `--a`, `--aa`, and `--all` filter result levels.
- Preserve URL path and query in history/baseline identity while ignoring scheme and host, and preserve interactive state labels as a separate identity dimension.
- Keep the default CLI `--threshold` at `0` and the default crawler limit at `50` unless a breaking release explicitly changes them.
- Keep every compatibility surface, including the dashboard footer, aligned with core Laravel 10, 11, 12, and 13 support.
- When compatibility changes, update `composer.json`, `README.md`, `CONTEXT.md`, tests, and the separate `lens-for-laravel-website` documentation together.
## Composer Metadata
- The package root is a Composer `library` named `webcrafts-studio/lens-for-laravel`; never describe it as a Laravel skeleton application.
- Do not add a hard-coded package version to `composer.json`; releases are determined from Git tags.
- Keep `laravel/ai` optional under `suggest`, never under production `require`.
- Keep the package description, keywords, homepage, support URLs, PHP/Laravel constraints, README, and public website consistent.
- The separate website is a Laravel `project` named `webcrafts-studio/laravel-lens-website`; its Composer metadata must describe the documentation website rather than the Laravel skeleton.
## Development Workflow
Run the full test suite:
```bash
composer test
```
Format PHP changes:
```bash
vendor/bin/pint --dirty
```
Validate Composer metadata:
```bash
composer validate --no-check-publish
```
The optional AI SDK is not part of the default development dependency graph. Install it temporarily when testing real provider integration on PHP 8.3+ and Laravel 12+:
```bash
composer require laravel/ai --dev
```
Do not commit that temporary dependency as a mandatory production requirement.
## Testing Expectations
- Every behavior change requires a focused Pest test.
- Capability tests must cover supported runtime, old PHP, old Laravel, missing SDK, and explicit disablement.
- Route tests must verify that unavailable AI Fix endpoints return a clear `503` without exposing provider internals.
- AI Fix tests must cover semantic context boundaries, malformed structured output, token-limit finish reasons, one retry only, non-retryable provider errors, safe user messages, and provider/model/token logging.
- Applied AI fixes must be marked as pending verification in the current dashboard results, remain in violation counts, and return to ordinary axe-derived state when a new scan replaces the results.
- Keep the AI model implicit by default for Gemini, OpenAI, Anthropic, OpenRouter, xAI, DeepSeek, and Mistral so `laravel/ai` resolves the configured provider default. Lens may pass an explicit model only when `ai_model` is set (at the user's own responsibility). For Ollama, `ai_model` takes precedence and the `ai_ollama_model` tag introduced in v3.3 stays as fallback, otherwise the SDK default is used.
- New AI providers must be added to the `AiFixer` allowlist and the `AiFixPromptRunner` `Lab` mapping together, with passthrough tests that keep model and timeout implicit by default.
- Dashboard tests must verify that unavailable features are explained and their actions are hidden.
- Preserve existing tests for Blade, React, Vue, crawler, state scripts, history, baseline, PDF, preview, and CLI behavior.
- Keep dashboard and CLI state scripts on the same `InteractionScriptParser` grammar and limits. CLI state mode must remain single-URL and incompatible with crawl mode.
- Keep `ignore_https_errors` consistent across axe scans, sitemap/page HTTP crawling, browser-rendered crawling, and element previews.
- Keep `resources/lang/{en,pl,es,fr,de}/messages.php` on the same key and placeholder contract. Package-owned dashboard, history, comparison, modal, PDF, recorder, and error text must use translation keys rather than hard-coded English.
- Add or update `TranslationCatalogTest` whenever the catalog contract changes; PDF and JavaScript-rendered dashboard strings must be covered by feature tests as well.
## Documentation Contract
The package README is the concise installation and feature reference. The website contains the full documentation. Keep these claims exact:
- core: PHP 8.2+, Laravel 10-13
- Lens MCP: PHP 8.2+, Laravel 10.49+, optional `laravel/mcp` >=0.5.3 <0.10 or 1.x; the connected assistant uses its own model and does not require `laravel/ai`
- v3.6 adds Lens MCP, tracked asynchronous scans, and the explicit `lens:install` first-run welcome; do not print welcome output during Composer updates or MCP stdio
- AI Fix supports `laravel/ai` >=0.3.2 <0.12 or 1.x, with SDK-specific Gemini options and token metadata; Composer chooses a compatible supported SDK
- AI Fix: PHP 8.3+, Laravel 12+, optional `laravel/ai`
- AI Fix sends a bounded semantic element/component and issue metadata to the configured provider; default localhost Ollama processing stays on the application host, while cloud and remote Ollama endpoints receive the context over the network
- v3 AI Fix uses a minimal replacement and one controlled retry for truncated/invalid structured output; cloud providers use their default `laravel/ai` model and timeout behavior unless the optional `ai_model` override is set, while v3.3 can select a local Ollama model tag explicitly and defaults its timeout to 120 seconds
- v3.4 adds OpenRouter, xAI, DeepSeek, and Mistral as implicit-model cloud providers alongside Gemini, OpenAI, and Anthropic
- v3.5 adds an optional `LENS_FOR_LARAVEL_AI_MODEL` override for any provider and a dashboard note that reports the SDK default or the manually configured model name
- v3.5 removes the pinned temperature of `0` so models without temperature support stop failing with a provider error; generation uses the provider default temperature
- v3.5 Fix All queues apply every ready suggestion with one bulk action using each item's reviewed or edited code, with per-item failures reported and rate limiting retried once
- applying an AI fix marks the current issue as pending re-scan but does not present it as axe-verified or remove it from counts
- all non-AI features remain available when AI Fix is unsupported or disabled
- dashboard and CLI support WCAG 2.0, 2.1, and 2.2, with WCAG 2.0 as the backward-compatible default
- v3 includes complete English, Polish, Spanish, French, and German catalogs for package-owned dashboard, history, comparison, modal, PDF, recorder, and error text; axe-core and framework-supplied messages remain upstream content
- default CLI threshold is `0`, default crawl limit is `50`, and the dashboard compatibility footer lists Laravel 10/11/12/13
- axe-core provides automated checks but neither axe-core nor Lens proves full WCAG conformance; documentation must require complementary manual testing and must not claim a fixed detection percentage
Avoid describing optional or partial functionality as universally available.
Lens for Laravel is a local-first accessibility auditing package for Laravel applications. It renders application pages in Chromium, runs axe-core, maps violations back to Blade/React/Vue source files, and exposes the results through a dashboard and the lens:audit Artisan command.
The current release is v3.6.0. It adds optional Lens MCP integration, tracked long scans, a first-install welcome, and compatibility with supported 0.x and stable 1.x Laravel AI/MCP SDK releases. v3.5 introduced the optional explicit AI model override, dashboard model information, bulk application, and provider-default temperature. v3.4 added authenticated scans and the OpenRouter, xAI, DeepSeek, and Mistral providers. New compatibility, WCAG selection, reliability, localization, source-mapping, and documentation work in this branch must otherwise be described as v3 functionality. Keep v2.0/v2.1 and incremental v3.0/v3.1/v3.2/v3.3/v3.4/v3.5 upgrade notes as historical documentation.
The package supports PHP 8.2+ and Laravel 10-13 for its core, non-AI features.
AI Fix is an optional integration with a narrower compatibility range:
laravel/ai Composer packageDo not add laravel/ai back to production require. Core installation on PHP 8.2 and Laravel 10/11 must remain possible. Code that touches the AI SDK must be guarded through AiFixAvailability.
src/Services/AxeScanner.php - browser-based axe-core scans, including interactive statessrc/Services/SiteCrawler.php - sitemap and internal-link discoverysrc/Services/HttpsClientConfiguration.php - shared TLS behavior for HTTP and Chromium clientssrc/Services/FileLocator.php - heuristic Blade/React/Vue source mappingsrc/Services/InteractionScriptParser.php - state script validation and parsingsrc/Services/BaselineManager.php - stable CI baseline fingerprintssrc/Services/ScanComparator.php - URL- and state-aware history comparisonsrc/Support/UrlNormalizer.php - host-independent URL path/query identitysrc/Http/Middleware/SetLensLocale.php - configured and session-selected package localesrc/Services/AiFixAvailability.php - runtime and optional-SDK capability checkssrc/Ai/AccessibilityFixAgent.php - structured v3 AI agent options and provider-specific controlssrc/Services/AiFixContextExtractor.php - bounded semantic element/component extractionsrc/Services/AiFixPromptRunner.php - optional Laravel AI SDK boundary and response metadatasrc/Services/AiFixer.php - prompt orchestration, controlled retry, safe errors, and diagnosticssrc/DTOs/AuthenticatedScanContext.php - server-issued session cookies for authenticated scanssrc/Services/AuthenticatedScanResolver.php - guard login, allowlist, and auth-state restoresrc/Support/Wcag.php - supported WCAG versions, cumulative axe-core tags, and result-level classificationsrc/Console/Commands/LensAuditCommand.php - CLI audit workflowsrc/Console/Commands/LensInstallCommand.php - first-install welcomesrc/Mcp/ - optional local MCP tools, tracked runs, source context, history, and verificationsrc/Services/McpAvailability.php - optional MCP SDK, runtime, and environment checksroutes/web.php - dashboard JSON endpointsresources/views/dashboard.blade.php - dashboard interfaceresources/views/state-recorder.blade.php - visual interaction recorderresources/views/report.blade.php - PDF report--wcag selects 2.0/2.1/2.2, while --a, --aa, and --all filter result levels.--threshold at 0 and the default crawler limit at 50 unless a breaking release explicitly changes them.composer.json, README.md, CONTEXT.md, tests, and the separate lens-for-laravel-website documentation together.library named webcrafts-studio/lens-for-laravel; never describe it as a Laravel skeleton application.composer.json; releases are determined from Git tags.laravel/ai optional under suggest, never under production require.project named webcrafts-studio/laravel-lens-website; its Composer metadata must describe the documentation website rather than the Laravel skeleton.Run the full test suite:
composer test
Format PHP changes:
vendor/bin/pint --dirty
Validate Composer metadata:
composer validate --no-check-publish
The optional AI SDK is not part of the default development dependency graph. Install it temporarily when testing real provider integration on PHP 8.3+ and Laravel 12+:
composer require laravel/ai --dev
Do not commit that temporary dependency as a mandatory production requirement.
503 without exposing provider internals.laravel/ai resolves the configured provider default. Lens may pass an explicit model only when ai_model is set (at the user's own responsibility). For Ollama, ai_model takes precedence and the ai_ollama_model tag introduced in v3.3 stays as fallback, otherwise the SDK default is used.AiFixer allowlist and the AiFixPromptRunner Lab mapping together, with passthrough tests that keep model and timeout implicit by default.InteractionScriptParser grammar and limits. CLI state mode must remain single-URL and incompatible with crawl mode.ignore_https_errors consistent across axe scans, sitemap/page HTTP crawling, browser-rendered crawling, and element previews.resources/lang/{en,pl,es,fr,de}/messages.php on the same key and placeholder contract. Package-owned dashboard, history, comparison, modal, PDF, recorder, and error text must use translation keys rather than hard-coded English.TranslationCatalogTest whenever the catalog contract changes; PDF and JavaScript-rendered dashboard strings must be covered by feature tests as well.The package README is the concise installation and feature reference. The website contains the full documentation. Keep these claims exact:
laravel/mcp >=0.5.3 <0.10 or 1.x; the connected assistant uses its own model and does not require laravel/ailens:install first-run welcome; do not print welcome output during Composer updates or MCP stdiolaravel/ai >=0.3.2 <0.12 or 1.x, with SDK-specific Gemini options and token metadata; Composer chooses a compatible supported SDKlaravel/ailaravel/ai model and timeout behavior unless the optional ai_model override is set, while v3.3 can select a local Ollama model tag explicitly and defaults its timeout to 120 secondsLENS_FOR_LARAVEL_AI_MODEL override for any provider and a dashboard note that reports the SDK default or the manually configured model name0 so models without temperature support stop failing with a provider error; generation uses the provider default temperature0, default crawl limit is 50, and the dashboard compatibility footer lists Laravel 10/11/12/13Avoid describing optional or partial functionality as universally available.
How can I help you explore Laravel packages today?