digitaldev-lx / laravel-process-map
Static-analysis package that maps the business processes inside any Laravel application: models, controllers, actions, jobs, events, listeners, notifications, policies, commands, routes, schedule, and broadcasting.
Package info
github.com/digitaldev-lx/laravel-process-map
pkg:composer/digitaldev-lx/laravel-process-map
Requires
- php: ^8.4
- laravel/framework: ^12.0 || ^13.0
- laravel/mcp: ^0.7
- nikic/php-parser: ^5.0
- symfony/finder: ^7.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/phpstan: ^2.0
README
Static-analysis tool that maps the business processes inside any Laravel application — without ever executing it.
digitaldev-lx/laravel-process-map reads your application's source code and registered Laravel runtime metadata (routes, schedule, broadcast channels) and produces a machine- and human-readable map of the processes it can identify: who calls what, which models are mutated where, which jobs/events/listeners participate in each flow, and which parts of the codebase look fully automated versus manual.
The output is useful for:
- Developers onboarding a new project — get a feel for the architecture in minutes instead of days.
- Tech leads & consultants auditing a codebase — see automation gaps, bottlenecks and risks without instrumenting anything.
- Documentation — generate a versioned snapshot of the application's process map and commit it to the repo.
- AI agents (v0.3+) — expose the process map as an MCP resource so agents can reason about your domain.
Table of contents
- Status
- How it works
- Requirements
- Installation
- Quick start
- Artisan commands
- Output formats
- Designed for LLM consumption
- MCP Support
- Configuration
- Available scanners
- Process detection
- Programmatic API
- Safety guarantees
- Limitations
- Roadmap
- Contributing
- License
Status
Stable (1.0.x). The public Artisan signatures, exporter formats and JSON schema (schema_version: "0.1") are committed to. Breaking JSON changes will bump the schema_version field and be documented in CHANGELOG.md.
How it works
┌────────────────────────────────────────────────────────────────────┐
│ ApplicationScanner │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ AST scan │ │ Router │ │ Schedule │ │
│ │ (php-parser)│ │ (read-only) │ │ (read-only) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └─────────────────┴─────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ ProcessMapResult │ │
│ │ (DTOs, schema-versioned) │ │
│ └────────────┬─────────────┘ │
│ │ │
│ ┌───────────────────┼────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Naming │ │ Automation │ │ Bottleneck/Risk │ │
│ │ cluster │ │ scoring │ │ detectors │ │
│ └────┬────┘ └──────┬───────┘ └────────┬────────┘ │
│ └──────────────────┴─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Json / Markdown / │ │
│ │ Mermaid exporters │ │
│ └─────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘
Source files are parsed via nikic/php-parser into an AST. Class metadata (extends, implements, traits, public methods, calls to dispatch()/event()/Notification::send, etc.) is collected by a single visitor and decorated per scanner type.
Routes, scheduled tasks and broadcast channels come from Laravel's runtime APIs (Router::getRoutes(), Schedule::events(), routes/channels.php) — read-only access only.
A heuristic clustering step then groups classes into business processes by stripping verbs and technical suffixes from class names, and a set of detectors annotates each process with automation level, potential bottlenecks and risks.
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.4 |
| Laravel | ^12.0 || ^13.0 |
nikic/php-parser |
^5.0 |
symfony/finder |
^7.0 |
The package is tested against the matrix above on every push (see .github/workflows/tests.yml).
Installation
Install as a dev dependency — the package is a developer/consulting tool, not a runtime concern:
composer require digitaldev-lx/laravel-process-map --dev
Run the install command to publish the configuration and create the output directory:
php artisan process-map:install
To install and scan in one go:
php artisan process-map:install --scan
The service provider is auto-discovered via extra.laravel.providers, so no manual registration is required.
Quick start
php artisan process-map:scan --all
This produces, in storage/app/process-map/:
process-map.json— full structured data, schema-versioned.process-map.md— human-readable Markdown report.process-map.mmd— Mermaid flowchart of the discovered processes.
A typical terminal summary:
Scanning application...
Scanned:
- Models: 14
- Controllers: 22
- Actions: 31
- Jobs: 9
- Events: 12
- Listeners: 15
- Notifications: 8
- Policies: 6
- Commands: 5
- Routes: 84
Detected processes:
- Booking Management (automation: high)
- Lead Management (automation: high)
- Payment Handling (automation: medium)
- User Onboarding (automation: low)
Outputs:
- storage/app/process-map/process-map.json
- storage/app/process-map/process-map.md
- storage/app/process-map/process-map.mmd
Artisan commands
| Command | What it does |
|---|---|
process-map:install [--scan] |
Publishes the config and creates the output directory. With --scan, runs a full scan immediately. |
process-map:scan [flags] |
Runs every enabled scanner and exporter. See flags below. |
process-map:report [--output=…] |
Generates only the Markdown report. |
process-map:json [--output=…] |
Generates only the JSON artefact. |
process-map:mermaid [--output=…] |
Generates only the Mermaid diagram. |
process-map:scan accepts:
--json,--markdown,--mermaid— generate the corresponding format.--all— generate every default format (JSON + Markdown + Mermaid).--output=path— override the output directory for this run.--no-routes— skip the route scanner.--no-process-detection— skip the heuristic clustering.
If no format flag is passed, the command falls back to config('process-map.exports.*').
Output formats
JSON
Canonical artefact, schema-versioned. Excerpt:
{
"schema_version": "0.1",
"generated_at": "2026-05-04T18:00:00+00:00",
"package": "digitaldev-lx/laravel-process-map",
"version": "0.1.0",
"app": {
"name": "Example App",
"environment": "local",
"laravel_version": "13.0",
"php_version": "8.4.1"
},
"summary": {
"models": 14, "controllers": 22, "actions": 31,
"jobs": 9, "events": 12, "listeners": 15,
"notifications": 8, "policies": 6, "commands": 5,
"routes": 84, "processes": 5
},
"classes": [
{
"type": "action",
"class_name": "App\\Actions\\CreateLeadAction",
"short_name": "CreateLeadAction",
"namespace": "App\\Actions",
"file_path": "app/Actions/CreateLeadAction.php",
"methods": ["__invoke"],
"traits": [],
"interfaces": [],
"references": [
"App\\Jobs\\SendLeadFollowUpJob",
"App\\Events\\LeadCreated",
"App\\Models\\Lead"
],
"metadata": {
"main_method": "__invoke",
"dispatches_jobs": ["App\\Jobs\\SendLeadFollowUpJob"],
"fires_events": ["App\\Events\\LeadCreated"]
}
}
],
"routes": [
{
"methods": ["POST"],
"uri": "leads",
"name": "leads.store",
"action": "App\\Http\\Controllers\\LeadController@store",
"controller_class": "App\\Http\\Controllers\\LeadController",
"controller_method": "store",
"middleware": ["web", "auth"],
"domain": null
}
],
"processes": [
{
"name": "Lead Management",
"entity": "Lead",
"automation_level": "high",
"components": {
"models": ["App\\Models\\Lead"],
"actions": ["App\\Actions\\CreateLeadAction"],
"jobs": ["App\\Jobs\\SendLeadFollowUpJob"],
"events": ["App\\Events\\LeadCreated"],
"listeners": ["App\\Listeners\\SendLeadCreatedNotification"],
"notifications": ["App\\Notifications\\LeadAssignedNotification"]
},
"potential_bottlenecks": [],
"risks": [
"Process 'Lead Management' has no associated policy: authorisation may be missing."
],
"recommendations": [
"Add a policy for the Lead model."
]
}
]
}
Markdown
The Markdown exporter produces a dense, single-pass document built so a
human (or an LLM) can grasp the architecture in one read. Sections produced
in process-map.md:
# Process Map: <App Name>
> header — generated_at · PHP · Laravel · Schema · Package version
## Summary — counts table (models / controllers / … / routes / processes / bottlenecks / risks)
## Processes — one block per detected process
### N. <Process Name>
- Entity / Automation level
#### Members — table: Role · Class (FQCN) · File · Notes
#### Flow — explicit trace: route → controller → action → job/event → listener → notification
#### Findings — ⚠ Bottleneck / 🛡 Risk / 💡 Recommendation lines
## Unattached Components — classes not bound to any process
## Routes Index — Method · URI · Name · Controller@method · Middleware
## Scheduled Tasks — Cron · Command · Description · Flags
## Broadcast Channels — channel name + auth callback presence
A real, fully-rendered example produced from a small fixture app (2 models, 1 controller, 1 action, 2 jobs, 1 event, 1 listener, 1 notification, 1 policy, 1 command, 3 routes):
# Process Map: Demo App > Static analysis snapshot — read-only. > Generated: `2026-05-04T21:49:56+00:00` · PHP `8.4.1` · Laravel `13.7.0` · Schema `0.1` · Package `digitaldev-lx/laravel-process-map@0.1.0` ## Summary | Metric | Count | | --- | ---: | | Models | 2 | | Controllers | 1 | | Actions | 1 | | Jobs | 2 | | Events | 1 | | Listeners | 1 | | Notifications | 1 | | Policies | 1 | | Commands | 1 | | Routes | 3 | | Detected processes | 1 | | Potential bottlenecks | 1 | | Risks flagged | 0 | ## Processes ### 1. Lead Management - **Entity:** `Lead` - **Automation:** high #### Members | Role | Class | File | Notes | | --- | --- | --- | --- | | Model | `App\Models\Lead` | `app/Models/Lead.php` | table=`leads` · softDeletes · factory | | Controller | `App\Http\Controllers\LeadController` | `app/Http/Controllers/LeadController.php` | actions: index/store/destroy · requests: 1 | | Action | `App\Actions\CreateLeadAction` | `app/Actions/CreateLeadAction.php` | entry=`__invoke` · dispatches: 1 · fires: 1 | | Job | `App\Jobs\SendLeadFollowUpJob` | `app/Jobs/SendLeadFollowUpJob.php` | **sync** (no ShouldQueue) | | Event | `App\Events\LeadCreated` | `app/Events/LeadCreated.php` | | | Listener | `App\Listeners\SendLeadCreatedNotification` | `app/Listeners/SendLeadCreatedNotification.php` | listens=`LeadCreated` · queued | | Notification | `App\Notifications\LeadAssignedNotification` | `app/Notifications/LeadAssignedNotification.php` | channels: mail, database · queued | | Policy | `App\Policies\LeadPolicy` | `app/Policies/LeadPolicy.php` | standard: viewAny/update · custom: assignToAgent | #### Flow - `POST /leads` → `LeadController@store` - `GET,HEAD /leads` → `LeadController@index` - `DELETE /leads/{lead}` → `LeadController@destroy` - `LeadController` → invokes `CreateLeadAction` - `CreateLeadAction` → dispatches `SendLeadFollowUpJob` - `CreateLeadAction` → fires `LeadCreated` - `LeadCreated` → handled by `SendLeadCreatedNotification` [queued] - `SendLeadCreatedNotification` → sends `LeadAssignedNotification` #### Findings - ⚠ Bottleneck: Job 'SendLeadFollowUpJob' does not implement ShouldQueue: it may run synchronously. ## Unattached Components | Type | Class | File | Notes | | --- | --- | --- | --- | | Model | `App\Models\Booking` | `app/Models/Booking.php` | | | Job | `App\Jobs\ProcessHeavyReportJob` | `app/Jobs/ProcessHeavyReportJob.php` | queued · queue=`reports` · tries=5 · timeout=120s | | Command | `App\Console\Commands\SyncLeadsCommand` | `app/Console/Commands/SyncLeadsCommand.php` | `leads:sync {--since=}` | ## Routes Index | Method | URI | Name | Controller@method | Middleware | | --- | --- | --- | --- | --- | | POST | /leads | leads.store | `LeadController@store` | web, auth | | GET,HEAD | /leads | leads.index | `LeadController@index` | — | | DELETE | /leads/{lead} | leads.destroy | `LeadController@destroy` | — | ## Broadcast Channels - `App.Models.User.{id}` (with auth callback) - `leads` (with auth callback)
That fixture renders to 85 lines (~2.6 KB). A typical ~150-class Laravel application produces ~600–800 lines (~20 KB) — well inside any modern context window.
Mermaid
Generates one overview flowchart plus one diagram per detected process:
flowchart TD
route_0["POST leads"]
App_Http_Controllers_LeadController["LeadController"]
route_0 --> |HTTP@store| App_Http_Controllers_LeadController
App_Actions_CreateLeadAction --> |dispatches| App_Jobs_SendLeadFollowUpJob
App_Actions_CreateLeadAction --> |fires| App_Events_LeadCreated
App_Events_LeadCreated --> |handled by| App_Listeners_SendLeadCreatedNotification
App_Listeners_SendLeadCreatedNotification --> |sends| App_Notifications_LeadAssignedNotification
Loading
Render with the Mermaid Live Editor, the GitHub-flavoured Markdown viewer, or VS Code's Mermaid Preview extension.
Designed for LLM consumption
The Markdown report is the canonical artefact for AI-assisted development.
Drop process-map.md into Claude Code, ChatGPT, Cursor, Aider or any other
LLM tool and you get an instantly navigable map of the application — without
the LLM having to grep, open dozens of files, or guess how the pieces fit
together.
Concrete advantages when fed to an LLM:
- File path on every row. The Members and Unattached tables include the relative path of each class, so the LLM can open the right file directly instead of running a search.
- One canonical place per class. Every class appears in exactly one spot — either inside the Process block it belongs to or inside Unattached Components. No duplicate listings, no wasted tokens.
- Dense
Notescolumn. Operational facts are inline:queue=reports · tries=5 · timeout=120s,channels: mail, database · queued,**sync** (no ShouldQueue). The LLM skips reading the source for the most common questions. - Explicit
Flowtrace. Theroute → controller → action → job/event → listener → notificationsequence is spelled out as bullet points so the request lifecycle is comprehensible in one read. - Reference-aware clustering. Classes that don't match a naming
convention are still attached to their process via static-call
references (e.g.
CreateLeadAction → dispatches SendLeadFollowUpJobpulls the job into the Lead Management block). Fewer orphans, cleaner reasoning. - Hedge wording on findings. Bottlenecks/risks/recommendations are
prefixed with
⚠ Bottleneck:,🛡 Risk:,💡 Recommendation:— the LLM treats them as investigation hints, not as facts. - Schema-versioned header.
Schema 0.1lets you build reproducible prompts: pin the schema version in your tooling and your prompts keep working when you upgrade the package. - Token-efficient. ~85 lines / ~2.6 KB for a 12-class fixture; ~600–800 lines / ~20 KB for a typical ~150-class Laravel app. Plenty of room left for the LLM's own reasoning and tool calls.
Quick recipe — feed it to Claude Code
php artisan process-map:scan --markdown # then, inside Claude Code: # /add-dir storage/app/process-map # or paste the file: cat storage/app/process-map/process-map.md | pbcopy
A useful starter prompt once the file is in context:
"Use
process-map.mdas the architectural map of this app. Don't grep unless I ask — pull file paths and references from the report. When you see ⚠/🛡/💡 markers, treat them as starting points for deeper review, not as confirmed bugs."
MCP Support
Laravel Process Map ships an optional read-only MCP layer on top of
laravel/mcp. It exposes the same
process map as MCP resources, tools and prompts so Claude
Code (and any other MCP-compatible client) can query your application
architecture interactively, without you having to load a large static
report into the prompt.
The layer is off by default. Activating it does not relax any of
the package's security guarantees: it remains strictly read-only — no
shell, no SQL, no external HTTP, no .env exposure.
When to use which
| Want… | Use |
|---|---|
| Static documentation you commit to the repo, an audit attachment, or a quick LLM context paste | The Markdown / JSON / Mermaid exports |
| An interactive session where the LLM picks the right slice of the map per question; very large apps; reusable prompts; per-process inspection | The MCP layer |
Installation
The dependency ships with the package — there is nothing extra to install. You only have to opt in:
# 1. Show the install instructions php artisan process-map:mcp-install # 2. Switch the flag in your .env PROCESS_MAP_MCP_ENABLED=true # 3. Make sure routes/ai.php exists (laravel/mcp publishes it) php artisan vendor:publish --tag=ai-routes # 4. Register the server in routes/ai.php
use Laravel\Mcp\Facades\Mcp; use DigitaldevLx\LaravelProcessMap\Mcp\Servers\ProcessMapServer; // STDIO (Claude Code's default transport) Mcp::local('process-map', ProcessMapServer::class); // or HTTP (with throttling middleware of your choice) // Mcp::web('/mcp/process-map', ProcessMapServer::class)->middleware('throttle:mcp');
# 5. Produce a process map (the MCP layer reads it) php artisan process-map:scan --all # 6. Verify php artisan process-map:mcp-status
The status command prints the current toggles and the security policy flags so any deviation from the read-only defaults is visible at a glance.
Resources
| URI | Returns |
|---|---|
process-map://summary |
App metadata, totals, schema and package version |
process-map://processes |
Compact list of detected processes with counts |
process-map://process/{slug} |
Full detail of one process (template URI) |
process-map://routes |
All registered routes |
process-map://classes |
Discovered classes grouped by type |
process-map://risks |
Consolidated risks across processes |
process-map://recommendations |
Recommendations + bottleneck hints |
process-map://mermaid |
Raw Mermaid diagram |
Tools (every one read-only)
get_process_map_summary, list_processes,
get_process_details, get_process_components, get_process_risks,
get_process_recommendations, get_related_classes (depth-bounded),
get_route_map, get_mermaid_diagram, refresh_process_map
(re-runs the static scan; gated by
process-map.mcp.tools.allow_refresh_scan),
compare_process_maps (stub; gated by
process-map.mcp.tools.allow_compare_scans, lands in v1.2).
Prompts
audit_process, refactor_process_safely, document_process,
find_automation_opportunities, generate_technical_handover,
prepare_mcp_tools_from_actions. Every prompt accepts the process
slug (or name / entity) where applicable and a small set of tuning
arguments.
Example — talking to Claude Code
Once the server is registered and the scan has been run, you can drop this into Claude Code:
"Use the Laravel Process Map MCP server to inspect the
lead-managementprocess before making any change. List the available processes first, then callget_process_details,get_process_components,get_process_risksandget_mermaid_diagram. Propose a safe refactoring plan via therefactor_process_safelyprompt. Do not modify code until I approve."
Security envelope (always enforced)
- read-only by design — every tool carries
#[IsReadOnly]; - no shell execution, no SQL, no external HTTP;
.envis never read; sensitive metadata keys (password / secret / token / api_key / authorization / bearer / credential / connection / *_password / private_key) are redacted to[REDACTED];- output size is capped per response (
max_response_bytes), processes and classes have explicit ceilings, related-class graph walks have a hard depth limit (max_related_depth ≤ 5).
Configuration
Publish the configuration:
php artisan vendor:publish --tag=process-map-config
The published file lives at config/process-map.php and exposes the following groups:
return [ 'paths' => [ 'app' => app_path(), 'routes' => base_path('routes'), ], 'output_path' => storage_path('app/process-map'), 'scan' => [ 'models' => true, 'controllers' => true, 'actions' => true, 'jobs' => true, 'events' => true, 'listeners' => true, 'notifications' => true, 'policies' => true, 'commands' => true, 'routes' => true, 'schedule' => true, 'broadcasting' => true, ], 'directories' => [ 'models' => ['app/Models'], 'controllers' => ['app/Http/Controllers'], 'actions' => ['app/Actions'], 'jobs' => ['app/Jobs'], 'events' => ['app/Events'], 'listeners' => ['app/Listeners'], 'notifications' => ['app/Notifications'], 'policies' => ['app/Policies'], 'commands' => ['app/Console/Commands'], ], 'process_detection' => [ 'enabled' => true, 'keywords' => ['create', 'update', 'delete', /* … */], 'business_suffixes' => ['Action', 'Job', 'Command', 'Service', 'Workflow', 'Process'], ], 'exports' => [ 'json' => true, 'markdown' => true, 'mermaid' => true, 'html' => false, ], 'privacy' => [ 'include_method_names' => true, 'include_properties' => false, 'include_docblocks' => false, 'include_file_paths' => true, 'redact_env_values' => true, ], ];
For modular layouts (DDD, nwidart/laravel-modules), add additional roots under directories:
'directories' => [ 'actions' => ['app/Actions', 'modules/*/Actions'], 'models' => ['app/Models', 'modules/*/Domain/Models'], ],
Available scanners
| Scanner | What it produces |
|---|---|
ModelScanner |
Eloquent models with table, fillable, casts, traits, soft-delete and factory flags |
ControllerScanner |
Controllers with public actions, form requests, dispatched events |
ActionScanner |
Action classes with main entry method (handle/execute/__invoke/run), dispatched jobs, fired events |
JobScanner |
Jobs with ShouldQueue, $queue, $tries, $timeout, $backoff |
EventScanner |
Events with broadcasting flags and Dispatchable/SerializesModels traits |
ListenerScanner |
Listeners with the event they handle and queue flag |
NotificationScanner |
Notifications with channels (via()) and to* delivery methods |
PolicyScanner |
Policies split into standard abilities (view, create, …) and custom abilities, mapped to a model name |
CommandScanner |
Artisan commands with signature and description |
RouteScanner |
Registered routes with controller, methods, name, middleware, domain |
ScheduleScanner |
Scheduled tasks with cron expression, command, mutex, timezone, withoutOverlapping, onOneServer |
BroadcastScanner |
Channels declared via Broadcast::channel() in routes/channels.php |
Each scanner can be turned off in config('process-map.scan.*').
Process detection
The NamingConventionProcessDetector is intentionally simple:
- Walk every
DiscoveredClassof a participating type. - Strip the business suffix (e.g.
Action,Job). - Strip the leading verb (e.g.
Create,Send). - Strip common participles (e.g.
Created,Updated). - Cluster by what remains. Clusters with at least 2 classes become a process.
Then the detectors annotate:
AutomationDetector— assignsnone/low/medium/highbased on which kinds of components a process ships (jobs and schedule weigh more than plain models).BottleneckDetector— surfaces hedge-worded hints like "Notifications in 'Lead Management' may run synchronously".RiskDetector— flags missing policies, jobs without$tries/$timeout, destructive command signatures.
The output is always best-effort. Hedge wording (Potential…, May indicate…) is intentional and propagated to the Markdown report.
Programmatic API
Resolve the singleton ProcessMap from the container:
use DigitaldevLx\LaravelProcessMap\ProcessMap; $processMap = app(ProcessMap::class); $result = $processMap->scan(); // returns ProcessMapResult $json = $processMap->exportJson($result, storage_path('app/snapshot.json')); $md = $processMap->exportMarkdown($result); // dense, LLM-ready string $mmd = $processMap->exportMermaid($result);
The string returned by exportMarkdown() is identical to the file written
by process-map:report and is safe to drop straight into an LLM prompt
(see Designed for LLM consumption).
ProcessMapResult is a typed, readonly DTO:
$result->summary->models; // int $result->classes; // list<DiscoveredClass> $result->routes; // list<DiscoveredRoute> $result->processes; // list<DiscoveredProcess> $result->toArray(); // recursively-serialised array
Use cases:
- Diff two snapshots in CI to detect architectural drift.
- Pipe the JSON into Backstage / TechDocs / your internal wiki.
- Feed the JSON to an LLM as context for code-review prompts.
Safety guarantees
The package is strictly read-only. It never:
- executes business code, jobs, events or notifications;
- queries the database;
- makes HTTP calls;
- writes anywhere outside the configured
output_path; - exposes the contents of
.envor other secrets.
Analysis is performed via AST parsing. Reflection is opt-in through process-map.safe_reflection.enabled and only used for safe metadata lookups (interfaces, traits, parent class).
A dedicated test (tests/Unit/ReadOnlyInvariantTest.php) scans the package's own src/ directory for forbidden helpers (DB::, dispatch(, event(, Notification::send, Mail::send, Http::*) and fails the build if any are introduced.
Limitations
- Heuristic detection: process clustering uses naming conventions. Apps that don't follow Laravel's standard structure may need custom suffixes/keywords in the config.
- AST scope: only top-level classes are inspected. Anonymous classes, interfaces and traits are skipped (intentional — they're not addressable as process participants).
- Lazy routes: routes registered conditionally at runtime (after
RouteServiceProvider::boot) are detected; routes registered through middleware or rare runtime paths may not be. - Schedule introspection: depends on Laravel's
Schedule::events()API. Closure-based schedules expose only the cron expression and timezone. - HTML exporter: stub in v0.1, scheduled for v0.2.
Roadmap
| Version | Highlights |
|---|---|
| v1.0 | Static scan, JSON/Markdown/Mermaid exporters, heuristic process detection with reference-aware clustering, dense LLM-ready Markdown. |
| v1.1 (current) | Read-only MCP layer (laravel/mcp) — 8 resources, 11 tools, 6 prompts. Process slugs in core. |
| v1.2 | HTML dashboard, snapshot history, compare_process_maps tool. |
| v1.3 | GitHub Action, scan diff between commits, architectural regression detection. |
| v2.0 | Plugin SPI for custom scanners and detectors; potential schema upgrade. |
Contributing
Issues and pull requests are welcome at github.com/digitaldev-lx/laravel-process-map.
Before opening a PR, run the quality checks locally:
composer test # Pest composer analyse # PHPStan level 6 + Larastan composer format # Pint (Laravel preset + strict_types)
Bug reports should include:
- PHP version
- Laravel version
- Package version
- A minimal reproduction (sample app folder structure and the offending output)
See .github/ISSUE_TEMPLATE for the templates.
License
MIT — see LICENSE.md.
Built by DigitalDev.