@ingin97/pi-laravel
v0.1.0
Published
A Laravel runtime evaluation tool for Pi.
Downloads
15
Maintainers
Readme

pi-laravel
pi-laravel gives Pi bounded, structured access to a Laravel application's runtime without parsing artisan tinker output.
Installation
Install the published package from a Laravel project's directory:
pi install npm:@ingin97/[email protected]During local development, load it directly instead:
pi -e /path/to/pi-laravel/src/index.tsThe Laravel project needs PHP and Composer dependencies installed. pi-laravel makes no changes to that project.
Usage
Pi can call laravel_eval with one PHP expression:
{
"code": "App\\Models\\User::latest()->take(5)->get()",
"capture_queries": true
}It also provides named, read-oriented helpers when an expression is unnecessary:
{ "helper": "routes" }
{ "helper": "config", "key": "app.name" }
{ "helper": "cache", "key": "feature.enabled" }
{ "helper": "event_listeners", "event": "App\\Events\\OrderPlaced" }
{ "helper": "model", "model": "App\\Models\\User", "id": 1 }
{ "helper": "relations", "model": "App\\Models\\User" }For sequential setup work, select statement mode. It runs the supplied PHP block; use an explicit return as the final statement to return a value:
{
"mode": "statements",
"code": "App\\Models\\Task::create(['project_id' => 1, 'title' => 'Demo task']);\nreturn App\\Models\\Task::where('title', 'Demo task')->count();"
}Available helpers are environment, config, cache, routes, failed_jobs, event_listeners, model, and relations. The relations helper returns metadata only—it does not load related records.
Useful expressions include:
config('app.name')
App\Models\User::count()
App\Models\User::first()
App\Models\User::take(5)->get()
collect([1, 2, 3])->map(fn ($x) => $x * 2)Eloquent models and collections render compactly in Pi while the complete structured bridge response is retained in the tool result details.
Bundled workflow guidance
The package includes a laravel-runtime-inspection skill. When a request needs focused Laravel state inspection, it guides Pi to select the tool without the user needing to name it, while routing interactive Tinker work, Artisan operations, raw SQL analysis, and log-based diagnostics to their better-suited tools.
How it works
Each call starts a PHP process, bootstraps Laravel through its console kernel, evaluates an expression, statement block, or helper, and writes one JSON response to stdout. Input is sent through stdin, so expressions do not need shell quoting and artisan tinker is never invoked. Set capture_queries to include bounded SQL text, bindings, connection name, timing, totals, duplicate-query groups, and likely N+1 findings. Captured queries remain available when evaluation throws. Set explain_queries with capture_queries to attach plans for captured SELECT statements on SQLite, MySQL, and PostgreSQL.
Supported result types
- null, booleans, integers, floats, and strings
- arrays
- Laravel collections
- Eloquent models and Eloquent collections
- generic objects (public properties only)
- structured exceptions
Results are bounded to a maximum depth of 4, 50 collection/array items, 4,000 bytes per string, and 4,000 bytes of captured output. Eloquent serialization uses visible attributes and includes bounded data only for relationships that were already loaded; it never triggers lazy loading.
Security
laravel_eval is blocked when Laravel reports the production environment. To run there, the caller must explicitly set allow_production: true.
Outside production, PHP expressions execute with the Laravel application's normal permissions. They can access or modify the application's database, filesystem, services, and external APIs. Named helpers are read-oriented, but this is not a PHP sandbox; use the extension only in projects you trust.
Limitations
codedefaults to exactly one PHP expression; multiple top-level statements are rejected with guidance to usemode: "statements". Statement mode runs a sequential PHP block and returnsnullunless the block explicitly returns a value.- Calls are stateless: each evaluation boots a new PHP process.
- Production execution requires a per-call explicit override; non-production PHP expressions remain unrestricted.
- Serialization intentionally omits Eloquent internals and non-public generic-object state.
- Query capture observes queries run after Laravel boots, is capped at 50 entries, may expose query bindings in the tool result, and includes structured count, elapsed-time, duplicate, and likely-N+1 analysis.
- Query plans are opt-in, only run for captured
SELECTstatements, and only support SQLite, MySQL, and PostgreSQL.
Development
Requirements: Node.js, PHP, Composer, and a Laravel project with dependencies installed.
npm install
npm run check
npm testTo run the Laravel bridge integration test, point the test runner at a PHP executable and Laravel fixture:
PHP_BINARY=/path/to/php LARAVEL_FIXTURE=/path/to/laravel-app npm test