romegasoftware / laravel-autopilot
Semi-autonomous error resolution for local development
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/romegasoftware/laravel-autopilot
Requires
- php: ^8.4
- illuminate/support: ^12.0
- symfony/process: ^7.0
This package is auto-updated.
Last update: 2026-02-04 19:04:57 UTC
README
Semi-autonomous error resolution for local development. Autopilot monitors Laravel logs and frontend errors, then dispatches Claude CLI agents to fix issues while you keep testing.
Requirements
- PHP 8.4+
- Laravel 12+
- Claude CLI available in
PATH
Installation
composer require romegasoftware/laravel-autopilot --dev
Enable in your .env:
AUTOPILOT_ENABLED=true
VITE_AUTOPILOT_ENABLED=true
Publish the config (optional):
php artisan vendor:publish --tag=autopilot-config
Usage
Run the watcher standalone:
php artisan autopilot:watch
Or integrate into your dev script:
{
"scripts": {
"dev": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"npm run dev\" \"php artisan autopilot:watch\" --names=server,vite,autopilot"
]
}
}
Frontend Integration
Autopilot captures frontend errors via a small client library. The package provides TypeScript modules you import directly.
1. Initialize the Client
In your main entry file (e.g., resources/js/app.tsx):
const shouldEnableAutopilot = import.meta.env.DEV && import.meta.env.VITE_AUTOPILOT_ENABLED === 'true'; if (shouldEnableAutopilot) { import('laravel-autopilot/autopilot-client').then(({ initAutopilot }) => { initAutopilot(); }); }
2. React Error Boundary
Wrap your app in the error boundary to capture React component errors:
import { AutopilotErrorBoundary } from 'laravel-autopilot/AutopilotErrorBoundary'; const shouldEnableAutopilot = import.meta.env.DEV && import.meta.env.VITE_AUTOPILOT_ENABLED === 'true'; // Passthrough component when autopilot is disabled const Passthrough = ({ children }: { children: ReactNode }) => <>{children}</>; const AutopilotBoundary = shouldEnableAutopilot ? AutopilotErrorBoundary : Passthrough; createInertiaApp({ setup({ el, App, props }) { createRoot(el).render( <AutopilotBoundary> <App {...props} /> </AutopilotBoundary> ); }, });
Custom fallback UI:
<AutopilotErrorBoundary fallback={<div className="p-4 bg-red-100">Something broke!</div>} > <App {...props} /> </AutopilotErrorBoundary>
3. Axios Interceptor (422 Validation Errors)
Install the interceptor on your Axios instance to capture validation errors:
// resources/js/bootstrap.js import axios from 'axios'; window.axios = axios; window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; if (import.meta.env.DEV && import.meta.env.VITE_AUTOPILOT_ENABLED === 'true') { import('laravel-autopilot/axios-interceptor').then(({ installAutopilotInterceptor }) => { installAutopilotInterceptor(window.axios); }); }
4. Manual Error Reporting
Report errors manually when needed:
import { reportError } from 'laravel-autopilot/autopilot-client'; try { await riskyOperation(); } catch (error) { reportError('Custom operation failed', { stack: error.stack, url: window.location.href, }); }
5. Vite Configuration
Add the package alias to your vite.config.ts:
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; export default defineConfig({ plugins: [ laravel({ input: ['resources/js/app.tsx'], refresh: true, }), ], resolve: { alias: { 'laravel-autopilot': '/vendor/romegasoftware/laravel-autopilot/resources/js', }, }, });
Configuration
Full configuration options in config/autopilot.php:
<?php return [ // Master toggle 'enabled' => env('AUTOPILOT_ENABLED', false), // Claude CLI settings 'claude' => [ 'binary' => env('AUTOPILOT_CLAUDE_BINARY', 'claude'), 'model' => env('AUTOPILOT_CLAUDE_MODEL'), 'timeout' => env('AUTOPILOT_TIMEOUT', 300), 'max_parallel_agents' => env('AUTOPILOT_MAX_AGENTS', 3), 'path' => env('AUTOPILOT_CLAUDE_PATH'), ], // Log monitoring 'logs' => [ 'path' => storage_path('logs/laravel.log'), 'levels' => ['error', 'critical', 'alert', 'emergency'], 'poll_interval_ms' => 500, ], // Frontend error capture 'frontend' => [ 'enabled' => true, 'capture_react_errors' => true, 'capture_console_errors' => true, 'capture_unhandled_rejections' => true, ], // 422 validation error handling 'validation_errors' => [ 'enabled' => env('AUTOPILOT_CAPTURE_422', true), 'include_request_data' => true, 'ignore_fields' => ['password', 'password_confirmation', 'credit_card', 'cvv'], ], // Error filtering 'ignore' => [ 'patterns' => [ '/Undefined array key.*session/', '/CSRF token mismatch/', ], 'exceptions' => [ Illuminate\Auth\AuthenticationException::class, Illuminate\Session\TokenMismatchException::class, Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class, ], 'paths' => [ 'vendor/', 'node_modules/', ], ], // Deduplication 'deduplication' => [ 'ttl' => 3600, 'store_path' => storage_path('logs/autopilot_seen_errors.json'), 'include_stack_trace' => false, ], // Cooldown to prevent agent spam 'cooldown' => [ 'after_dispatch' => 5, 'after_completion' => 30, 'max_attempts' => 3, ], // HMR protection (prevents errors during Vite hot reload) 'hmr_protection' => [ 'cooldown_after_file_change' => 5, 'frontend_cooldown_after_completion' => 10, 'ignore_patterns' => [ '/\[vite\].*hot update/', '/\[HMR\]/', '/ChunkLoadError/', '/Loading chunk.*failed/', '/Failed to fetch dynamically imported module/', ], 'lock_modified_files' => true, ], // Context included with errors 'context' => [ 'include_route_name' => true, 'include_controller' => true, 'max_stack_frames' => 10, ], // Output settings 'output' => [ 'stream_agent_output' => true, 'agent_output_prefix' => '[agent-%d] ', ], // Customize agent prompts 'prompts' => [ 'prefix' => <<<'PROMPT' You are fixing an error in a Laravel application during local development. IMPORTANT CONTEXT: - This is a Laravel 12 / Inertia v2 / React 19 application - Follow existing code patterns in the codebase - Run tests after making changes to verify the fix - Keep changes minimal and focused on the error PROMPT, 'suffix' => <<<'PROMPT' After fixing, verify your changes work by: 1. Running relevant tests if they exist 2. Checking for TypeScript errors with `npm run typecheck` if you modified frontend code PROMPT, ], ];
How It Works
-
Backend errors: The watcher tails
storage/logs/laravel.logand detects new errors based on configured severity levels. -
Frontend errors: The client captures:
- React component errors (via error boundary)
- Console errors (
console.error) - Unhandled promise rejections
- 422 validation errors (via Axios interceptor)
-
Dispatching agents: When an error is detected, Autopilot:
- Checks deduplication cache to avoid re-processing
- Applies ignore patterns and exception filters
- Respects cooldown periods
- Spawns a Claude CLI agent with error context
-
HMR protection: The client ignores errors that occur during Vite hot module replacement to prevent false positives when agents modify files.
Environment Variables
| Variable | Default | Description |
|---|---|---|
AUTOPILOT_ENABLED |
false |
Master toggle for backend |
VITE_AUTOPILOT_ENABLED |
false |
Master toggle for frontend |
AUTOPILOT_CLAUDE_BINARY |
claude |
Path to Claude CLI |
AUTOPILOT_CLAUDE_MODEL |
(default) | Override Claude model |
AUTOPILOT_TIMEOUT |
300 |
Agent timeout in seconds |
AUTOPILOT_MAX_AGENTS |
3 |
Max parallel agents |
AUTOPILOT_CLAUDE_PATH |
- | Prepend to PATH for node/claude resolution |
AUTOPILOT_CAPTURE_422 |
true |
Capture validation errors |
Logs & Deduplication
Autopilot stores its logs and error tracking in storage/logs/:
| File | Purpose |
|---|---|
storage/logs/autopilot.log |
Autopilot activity log (agent dispatches, completions, errors) |
storage/logs/autopilot_seen_errors.json |
Tracks error signatures to prevent duplicate agent dispatches |
Retriggering Failed Fixes
If an agent failed to fix an error and you want to retry, clear the error from the seen errors cache:
# Clear all seen errors (retrigger everything) rm storage/logs/autopilot_seen_errors.json # Or edit the JSON to remove specific entries cat storage/logs/autopilot_seen_errors.json
The JSON file uses hashed error signatures:
{
"seen": {
"e5be2f2968f8b135": 1770226514,
"745eee2a90c95b32": 1770226536
},
"attempts": {
"e5be2f2968f8b135": 1,
"745eee2a90c95b32": 2
},
"last_updated": "2026-02-04T18:46:38+00:00"
}
seen: Hash → Unix timestamp of first occurrenceattempts: Hash → Number of agent dispatch attempts
Remove a hash from both seen and attempts to allow that error to trigger a new agent.
Notes
- Autopilot only registers when
APP_ENV=localandAUTOPILOT_ENABLED=true - Frontend client only activates when
import.meta.env.DEVis true - Errors are deduplicated within a session to prevent agent spam
- The watcher gracefully handles log rotation