PHPackages                             robertogallea/laravel-necromancer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. robertogallea/laravel-necromancer

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

robertogallea/laravel-necromancer
=================================

A Laravel package that generates AI-readable application inventory and context.

1.1.1(1mo ago)11.2k↑1314.3%MITPHPPHP ^8.3CI passing

Since Jun 8Pushed 1w agoCompare

[ Source](https://github.com/robertogallea/laravel-necromancer)[ Packagist](https://packagist.org/packages/robertogallea/laravel-necromancer)[ RSS](/packages/robertogallea-laravel-necromancer/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (16)Versions (4)Used By (0)

 [![Laravel Necromancer](docs/banner.png)](docs/banner.png)

Laravel Necromancer scans your bootstrapped Laravel application and builds a structured, machine-readable inventory called the **manifest**. From that manifest you can display a terminal map of your application, run an AI-readability audit, and generate a Markdown context file that AI coding agents can load as ambient context — so they always have an accurate picture of your routes, models, jobs, events, observers, scheduled tasks, middleware, Livewire components, gates, mailables, validation rules, service providers, and more.

What Necromancer Collects
-------------------------

[](#what-necromancer-collects)

The manifest covers 18 artifact types across the full Laravel application structure:

TypeWhat it surfaces`routes`Name, method, URI, controller, action, middleware, authorization, route metadata (domain, flow, capability, summary, risk, external services, ADR)`models`Table, fillable, casts, appends, relationships, scopes, observers, policy, factory`jobs`Queue, connection, tries, timeout, backoff, max\_exceptions`events`Listeners, broadcastable channels`listeners`Handled events, queued status`commands`Signature, description, aliases`form_requests`Rules, stop\_on\_first\_failure, error\_bag`policies`Model, policy methods`enums`Backing type, cases`tests`File, type (unit/feature), subject class, test methods`observers`Model, lifecycle hooks, queued status`scheduled_tasks`Command, cron expression, human-readable schedule, flags`middleware`Alias, class, scope (global/group/alias), group name`livewire_components`View, public properties with types, action methods, listened events`gates`Ability, kind (closure/class/before\_hook/after\_hook), parameters`mailables`Subject, queued status, queue name, view/markdown template`validation_rules`Implicit flag, docblock description`service_providers`Deferred flag, source locationAll artifact types carry a `source` field with `file`, `line`, `line_end`, and `hash` for precise citations and stale detection.

Requirements
------------

[](#requirements)

VersionPHP≥ 8.3Laravel13.xInstallation
------------

[](#installation)

Install the package as a development dependency:

```
composer require --dev robertogallea/laravel-necromancer
```

The service provider is auto-discovered — no manual registration is needed.

Optionally publish the configuration file:

```
php artisan vendor:publish --tag=necromancer-config
```

Usage
-----

[](#usage)

Necromancer follows a **scan-first** workflow. Every other command reads the manifest produced by `necromancer:scan` rather than re-scanning the application.

### Step 1 — Scan

[](#step-1--scan)

```
php artisan necromancer:scan
```

Inspects the running application and writes `necromancer.json` to the project root. Re-run this command whenever your application changes. Collect only specific artifact types with `--only`:

```
php artisan necromancer:scan --only=routes,models
php artisan necromancer:scan --only=observers,scheduled_tasks,gates
```

Necromancer reads PHP attributes (`#[ObservedBy]`, `#[Queue]`, `#[Aliases]`, `#[Authorize]`, etc.) as primary sources alongside class properties. Codebases using the attribute-based API introduced in Laravel 11+ are fully supported — jobs configured via `#[Queue]`/`#[Tries]`/`#[Timeout]`, models with `#[ObservedBy]`/`#[ScopedBy]`, and commands with `#[Aliases]` all appear correctly in the manifest.

Test files in `tests/Unit/` and `tests/Feature/` are scanned and included as a `tests` artifact type. Both Pest functional-style files (`test()`/`it()` calls) and class-based PHPUnit tests are supported. Subject classes are inferred from `uses()` declarations and filename convention (`OrderTest.php` → `App\Models\Order`).

On Laravel 13.17+, routes using the native [`Route::metadata()`](https://laravel.com/docs/routing#route-metadata) API are scanned too. Necromancer reads a reserved `necromancer` namespace within that metadata as a compact, declared-by-the-developer semantic signal — separate from anything Necromancer infers itself:

```
Route::post('/billing/cancel', [SubscriptionController::class, 'cancel'])
    ->metadata([
        'necromancer' => [
            'domain' => 'billing',
            'flow' => 'subscription-cancellation',
            'capability' => 'subscription.cancel',
            'summary' => 'Cancels an active subscription.',
            'risk' => 'high',
            'external_services' => ['stripe'],
            'adr' => 'docs/adr/004-subscription-cancellation.md',
        ],
    ]);
```

All fields are optional and the feature is entirely opt-in — apps that don't use route metadata, or that run Laravel &lt; 13.17, are unaffected; the `route_metadata` key is simply omitted from the manifest. Keep values compact (labels, identifiers, ADR references) rather than long narrative descriptions — ADRs, domain docs, and the generated context file remain the right place for extended architectural explanations. This declared metadata takes priority over any naming/namespace-based inference Necromancer performs, and is used by `necromancer:doctor` (coverage scoring), `necromancer:audit` (quality checks), `necromancer:generate` (routes table columns), and `necromancer:diff` (flagged high-risk/external-service routes) — see each command's section below.

Check for manifest drift without writing a new file (CI use):

```
php artisan necromancer:scan --diff                         # show added/removed artifacts
php artisan necromancer:scan --diff --fail-on-drift        # exit 1 when drift detected
```

### Step 2 — Explore (optional)

[](#step-2--explore-optional)

Display the full application inventory in the terminal:

```
php artisan necromancer:map
```

Narrow the output to a single artifact type:

```
php artisan necromancer:map --type=routes
php artisan necromancer:map --type=models
```

### Step 3a — Audit AI readability

[](#step-3a--audit-ai-readability)

Check how well your application can be understood by an AI coding agent:

```
php artisan necromancer:audit
```

Each finding is grouped by severity (error / warning / suggestion). The score is a weighted pass-rate across all checks — normalized by the number of applicable artifacts — so an app with 1 unnamed route out of 50 scores far better than one with 1 out of 1. Errors weigh 3×, warnings 2×, and suggestions 1× in the calculation. Routes using `Route::metadata()` are checked for quality too: a `risk: high`/`critical` route with no `adr` reference, an `external_services` route with no matching test subject, a `summary` over 200 characters (narrative content that belongs in an ADR instead), and routes sharing the same `flow` that disagree on `domain` or `risk` (a single business process should agree on both) all produce findings — but only for routes that have actually declared metadata, so adopting the feature is never required to keep a clean audit. Output a shareable or machine-readable report, or enforce a CI gate:

```
php artisan necromancer:audit --format=markdown              # paste into a GitHub issue or PR
php artisan necromancer:audit --format=markdown --output=audit.md
php artisan necromancer:audit --format=json --output=audit.json
php artisan necromancer:audit --fail-on=error    # exit 1 if any errors (CI use)
php artisan necromancer:audit --fail-on=warning  # exit 1 if any warnings or errors
```

### Step 3b — Check the AI readability score

[](#step-3b--check-the-ai-readability-score)

Get a quick percentage score across eight weighted dimensions of AI readability:

```
php artisan necromancer:doctor
```

Each dimension shows a progress bar, a percentage, and a detail line:

```
  Laravel Necromancer — AI Readability Score
  ──────────────────────────────────────────
  Score: 74%

  Route Clarity          ████████░░  82%  (12/15 named · 14/15 controller-backed)
  Model Expressiveness   ██████░░░░  61%  (3/5 casts · 4/5 fillable · 2/5 relationships)
  Authorization Coverage ███████░░░  70%  (2/3 policies · 8/12 write routes with auth)
  Validation Coverage    ████████░░  80%  (8/10 write routes with FormRequest)
  Async Clarity          ████████░░  83%  (4/5 jobs configured · 4/4 events with listeners)
  Codebase Vocabulary    ██████░░░░  63%  (5/8 commands described · 1/1 backed enums)
  Test Presence          ████████░░  80%  (4/5 models · 3/3 jobs)
  Route Metadata Coverage████████░░  83%  (5/6 tagged with domain · 2/2 high-risk with ADR · 1/2 external-service routes tested · 4/4 flow-consistent)

  Tip: run necromancer:audit for a detailed findings list.

```

Route Metadata Coverage scores N/A (and doesn't affect the overall score) until at least one route declares `necromancer` route metadata — adopting the feature is entirely optional.

Output a machine-readable score or enforce a CI gate:

```
php artisan necromancer:doctor --json
php artisan necromancer:doctor --min-score=80        # exit 1 when score < 80 (CI use)
php artisan necromancer:doctor --only=route-clarity  # score a single dimension
```

### Step 3c — Generate AI context

[](#step-3c--generate-ai-context)

Write a Markdown context file your AI tool can load:

```
php artisan necromancer:generate
```

Produces `NECROMANCER.md` at the project root. The generated file includes a `## Tests` table when test artifacts are present:

```
## Tests (12)
| File | Type | Subject | Tests |
|---|---|---|---|
| tests/Unit/Models/OrderTest.php | unit | Order | it creates an order, it calculates total |
| tests/Feature/OrderCheckoutTest.php | feature | | test_it_completes_checkout |
```

Generate only specific sections:

```
php artisan necromancer:generate --only=routes,models
php artisan necromancer:generate --only=observers,scheduled_tasks
php artisan necromancer:generate --only=gates,middleware,mailables
```

Supported types: `routes`, `models`, `form_requests`, `jobs`, `events`, `listeners`, `commands`, `policies`, `enums`, `tests`, `observers`, `scheduled_tasks`, `middleware`, `livewire_components`, `gates`, `mailables`, `validation_rules`, `service_providers`.

Exclude specific sections instead of listing everything you want:

```
php artisan necromancer:generate --except=listeners
php artisan necromancer:generate --except=listeners,validation_rules,service_providers
```

`--only` and `--except` are mutually exclusive.

Filter by source path to generate context for just one slice of the application:

```
php artisan necromancer:generate --paths=app/Models,app/Http/Controllers/Admin
php artisan necromancer:generate --only=models --paths=app/Models
```

`--paths` matches each artifact's `source.file` by path prefix (after normalizing slashes) and is applied on top of `--only`/`--except`, so it can be combined with either. Paths are case-sensitive on Linux and case-insensitive on macOS/Windows, following the filesystem. Artifacts without a source file (closure routes, inline gates) are excluded while `--paths` is active, sections that end up empty are omitted, and a path that matches nothing emits a warning without failing.

Skip the overwrite confirmation when regenerating:

```
php artisan necromancer:generate --force
```

Write to a custom path:

```
php artisan necromancer:generate --output=.ai/context/app.md
```

### Step 3d — Ask a question about your codebase

[](#step-3d--ask-a-question-about-your-codebase)

Ask a natural-language question and get a grounded answer from your manifest:

```
php artisan necromancer:ask "What routes require authentication?"
```

If you omit the question, the command prompts you interactively. The manifest is injected verbatim into the AI's context, so answers are grounded in your actual application — not a model's prior knowledge. A warning is shown if the manifest may be stale.

The full manifest is always included — nothing is discarded — but a "Most Relevant Evidence" section is prepended ahead of it, ranking the artifacts most related to your question so the AI's attention is prioritized rather than left to search the whole payload unguided. Ranking uses the same keyword scoring as `necromancer:prompt`, boosted for declared route metadata: a route's `domain`/`flow`/`capability` count as strongly as its name or class, since that's an intentional signal from the developer rather than something inferred from naming.

```
php artisan necromancer:ask                                        # interactive prompt
php artisan necromancer:ask "..." --provider=anthropic             # provider override
php artisan necromancer:ask "..." --model=claude-sonnet-4-5        # model override
```

> **Requires** `laravel/ai` installed and an AI provider configured in `config/ai.php`.

### Inspect the AI payload

[](#inspect-the-ai-payload)

Before committing to a provider, check exactly what Necromancer sends to the AI and how large the payload is:

```
php artisan necromancer:inspect-payload
```

Prints the full manifest JSON, the estimated token count, and a breakdown of artifact type counts. Pass `--privacy` to see the condensed privacy-safe summary instead (the payload used when a privacy-conscious provider is configured):

```
php artisan necromancer:inspect-payload --privacy
```

---

### Step 3e — Infer Architecture Decision Records

[](#step-3e--infer-architecture-decision-records)

Generate [Architecture Decision Records](https://adr.github.io/) from the manifest using an AI provider:

```
php artisan necromancer:infer
```

> **Requires** `laravel/ai` installed and an AI provider configured in `config/ai.php`.

#### Options

[](#options)

OptionDescription`--locale=it`Translate ADRs into additional locales (comma-separated, e.g. `--locale=it,fr`). The default app locale is always inferred first; extra locales are translated from it.`--temperature=0`LLM temperature (0.0–2.0). Lower values produce more deterministic output. Omit to use the provider default.`--max-critic-rounds=N`Maximum number of critic review rounds (default 1). The loop exits early if the critic is satisfied before reaching N.`--dry-run`Print ADRs to the terminal without writing files.`--force`Overwrite existing ADR files without confirmation.`--fresh`Delete all existing ADR files and the inference cache, then re-infer from scratch.`--refresh`Bypass the cache and re-infer even if the manifest has not changed.#### Output

[](#output)

ADRs are written to `docs/adr/necromancer/` (canonical locale, flat) and `docs/adr/necromancer/{locale}/` for each translated locale. Each file follows the [Nygard ADR format](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions):

```
# ADR 0001: Async Email Delivery via Dedicated Queue

**Status:** Inferred
**Dimension:** Async Processing
**Confidence:** High
**Date:** 2026-05-29

## Context
...

## Decision
...

## Consequences
...

## Counter-Evidence
No contradicting evidence found in the manifest.
```

#### Decision Taxonomy

[](#decision-taxonomy)

The inference agent evaluates nine architectural dimensions and produces at most one ADR per dimension:

DimensionWhat it covers`async-processing`Jobs, queues, workers, retry strategy`authorization`Policies, gates, middleware auth guards`event-driven`Events, listeners, broadcasting`api-design`Route structure, API resources, versioning`data-modeling`Model relationships, casts, soft deletes`command-scheduling`Artisan commands, scheduled tasks`form-validation`Form requests vs inline validation`external-services`Mail, storage, payment, third-party services`architecture-pattern`Service layer, repository, MVC deviations#### Critic Agent

[](#critic-agent)

By default, a second AI pass reviews and filters the initial ADRs, removing generic observations and improving specificity. Configure via `config/necromancer.php`:

```
'inference' => [
    'critic' => [
        'enabled' => true,   // set to false to disable the critic entirely
    ],
],
```

Use `--max-critic-rounds=N` to run up to N review passes. The critic signals when it is satisfied; the loop exits early even if N has not been reached. Each unsatisfied round adds one AI call.

```
# Two critic rounds at most (exits early if satisfied after round 1)
php artisan necromancer:infer --temperature=0 --max-critic-rounds=2
```

#### Caching

[](#caching)

The command caches inference results in `docs/adr/necromancer/.adr-inference-cache.json`. The cache key is derived from `meta.content_hash` (a SHA-256 of the artifact payload written into every manifest by `necromancer:scan`), plus the temperature and critic settings. Because the hash covers only artifact data — not the scan timestamp — the cache survives re-scans that find no structural changes. On subsequent runs:

- **Unchanged codebase** — cached ADRs are used even if `necromancer:scan` was re-run; no AI call.
- **New `--locale` added** — only the translation call is made; inference is skipped.
- **`--refresh`** — forces re-inference with an unchanged manifest.
- **`--fresh`** — clears the cache and all ADR files before re-inferring.

#### Multi-Locale Workflow

[](#multi-locale-workflow)

```
# Generate canonical ADRs in the app locale (config('app.locale'))
php artisan necromancer:infer --temperature=0

# Add Italian translation without re-running inference
php artisan necromancer:infer --temperature=0 --locale=it

# Regenerate everything from scratch
php artisan necromancer:infer --temperature=0 --fresh
```

---

### Step 3f — Generate a source-grounded prompt

[](#step-3f--generate-a-source-grounded-prompt)

Build a ready-to-paste AI prompt grounded in the most relevant manifest entries for your question:

```
php artisan necromancer:prompt "Where is tenant isolation enforced?"
```

Necromancer keyword-searches the manifest, ranks artifacts by relevance, and outputs a formatted prompt block with `file:line` citations that you can paste into any AI tool (Claude, ChatGPT, Cursor, etc.).

```
You are analyzing MyApp, a Laravel 13 application.

Use the following source-grounded manifest entries:
- app/Http/Middleware/SetTenant.php:15-61
- app/Models/Project.php:12-44
- app/Http/Requests/CreateProjectRequest.php:1-38

Question:
Where is tenant isolation enforced?

Rules:
- Only answer from cited sources.
- Mention missing evidence.
- Do not assume runtime behavior not shown in code/tests.

```

If `laravel/ai` is installed, the question is automatically reformulated into a precise, application-aware version before being included in the prompt. Pass `--no-ai` to use the raw question instead.

```
php artisan necromancer:prompt "authentication" --no-ai    # skip AI reformulation
php artisan necromancer:prompt "billing" --top=5           # limit to 5 citations
php artisan necromancer:prompt "auth" --output=prompt.txt  # write to file
php artisan necromancer:prompt                             # interactive question prompt
```

> **AI reformulation** requires `laravel/ai` installed and configured. The command works without it — only the question contextualization step is skipped.

---

### Step 3g — Compare manifests across branches

[](#step-3g--compare-manifests-across-branches)

Review the architectural changes introduced by a branch compared to another:

```
php artisan necromancer:diff main
```

Compares the current manifest against the manifest on the `main` branch. The output shows added, removed, and modified routes, models, jobs, events, listeners, policies, and other artifacts.

When an added or changed route declares `risk: high`/`critical` or a non-empty `external_services` via route metadata, it's called out in a dedicated "Flagged Routes" section before the rest of the diff — this is a deterministic check, so it shows up even without `--review`/`laravel/ai`. Each flagged route also shows its `domain`, `flow`, and `capability` when declared, so reviewers see business context alongside the trigger:

```
FLAGGED ROUTES
⚠  POST /billing/cancel (billing.cancel)  domain: billing · flow: subscription-cancellation · capability: subscription.cancel · risk: high

```

#### Options

[](#options-1)

OptionDescription`--base-manifest=PATH`Use a specific manifest file instead of comparing branches. Useful for comparing against a snapshot.`--review`Enable AI-powered analysis of the changes (requires `laravel/ai`). Produces a narrative summary of the architectural impact, detected risks, and suggested reviewer questions.`--format=markdown`Output in Markdown format (suitable for pasting into PRs or issues).`--output=PATH`Write the report to a file instead of printing to the terminal.#### Example: Basic diff

[](#example-basic-diff)

```
php artisan necromancer:diff main
```

Output:

```
Comparing current manifest to main branch

Added:
  - Route: POST /api/subscriptions (SubscriptionController@store)
  - Model: App\Models\Subscription
  - Event: App\Events\SubscriptionCreated
  - Listener: App\Listeners\SendSubscriptionEmail (queued)
  - Job: App\Jobs\ProcessSubscriptionActivation

Modified:
  - Route: GET /dashboard (Dashboard parameter added)
  - Model: User (new cast: subscription_tier)

Removed:
  - Policy: App\Policies\TrialPolicy

```

#### Example: AI-powered review

[](#example-ai-powered-review)

```
php artisan necromancer:diff main --review --format=markdown
```

Output (when `laravel/ai` is installed):

```
## Architectural Changes

This PR introduces a subscription model with activation workflow.

### Evidence
- New listener: SendSubscriptionEmail (queued)
- New job: ProcessSubscriptionActivation
- New event: SubscriptionCreated
- Modified route: GET /dashboard (dashboard parameter added)

### Risks
- No failed-activation test detected.
- No policy for Subscription model.
- Job retry strategy not configured.

### Suggested Reviewer Questions
1. Should subscription activation be idempotent?
2. What happens if the activation job fails multiple times?
3. Is SendSubscriptionEmail queued appropriately?
```

> **Note:** The `--review` option requires `laravel/ai` to be installed and configured. Without it, only the basic diff is shown. Both branches must have a committed `necromancer.json` manifest.

The AI reviewer's prompt includes the same "Flagged Routes" signal shown in the deterministic diff (high/critical-risk and external-service routes, with `domain`/`flow`/`capability` when declared) — so its risk assessment is grounded in what you actually declared via route metadata, not left to infer risk purely from the raw diff.

---

### Step 3h — Benchmark AI context effectiveness

[](#step-3h--benchmark-ai-context-effectiveness)

Measure how much Necromancer's generated context file improves AI coding-assistant accuracy, hallucination rate, and token cost compared to a hand-written `AGENTS.md` or no context at all:

```
php artisan necromancer:benchmark
```

The command runs a bundled task suite in three conditions — no context, manual `AGENTS.md`, and Necromancer-generated `NECROMANCER.md` — and reports the results side by side. An optional cross-model AI judge scores quality; automated fact-checks always run.

Q&amp;A tasks (which measure context *coverage*) only run under the `none` and `manual` conditions — Necromancer would trivially score 100% since the answers are in the context file it generated. Code generation and mini tasks run across all three conditions and measure actual effectiveness.

```
php artisan necromancer:benchmark --no-judge              # automated checks only (single provider)
php artisan necromancer:benchmark --format=markdown --output=benchmark.md
php artisan necromancer:benchmark --generate-suite        # generate a suite grounded to your app's manifest
```

> See **[BENCHMARK.md](BENCHMARK.md)** for full setup instructions, config reference, and bias mitigations.

---

Commands Reference
------------------

[](#commands-reference)

CommandPurposeKey options`necromancer:scan`Build the application manifest`--output=PATH`, `--diff`, `--fail-on-drift``necromancer:map`Display the manifest in the terminal`--type=TYPE``necromancer:audit`Run the AI-readability audit (violation list)`--format=text|json|markdown`, `--output=PATH`, `--fail-on=SEVERITY``necromancer:doctor`Show the AI readability score (percentage dashboard)`--json`, `--min-score=N`, `--only=KEYS``necromancer:generate`Generate the Markdown context file`--only=TYPE,TYPE`, `--except=TYPE,TYPE` (18 types: routes, models, jobs, events, listeners, commands, form\_requests, policies, enums, tests, observers, scheduled\_tasks, middleware, livewire\_components, gates, mailables, validation\_rules, service\_providers), `--paths=PATH,PATH`, `--output=PATH`, `--force``necromancer:ask`Ask a question about your codebase via AI`--provider=`, `--model=``necromancer:inspect-payload`Show the AI payload size and content for `necromancer:ask``--privacy``necromancer:prompt`Generate a source-grounded prompt for any AI tool`--top=N`, `--no-ai`, `--output=PATH``necromancer:infer`Generate ADRs via AI`--locale=`, `--temperature=`, `--fresh`, `--refresh``necromancer:diff`Compare manifests across branches`--base-manifest=PATH`, `--review`, `--format=markdown`, `--output=PATH``necromancer:benchmark`Benchmark AI context effectiveness (accuracy, hallucination rate, token cost)`--condition=`, `--type=`, `--no-judge`, `--model=`, `--judge=`, `--format=`, `--output=PATH`Configuration
-------------

[](#configuration)

After publishing the config, edit `config/necromancer.php`:

```
return [

    // Artifact exclusions — supports wildcard patterns for routes and glob patterns for tests
    'exclude' => [
        'routes'     => ['horizon.*', 'telescope.*', 'debugbar.*'],  // matched against the route NAME
        'route_uris' => ['up'],                                      // matched against the route URI (works for unnamed routes such as Laravel's /up health check)
        'models'     => [],
        'tests'      => [],   // glob patterns matched against relative file paths, e.g. 'tests/Fixtures/*'
    ],

    // Test discovery roots — override the default tests/Unit and tests/Feature scan paths
    'tests' => [
        'roots' => [
            // ['path' => base_path('tests/Unit'), 'type' => 'unit'],
            // ['path' => base_path('tests/Feature'), 'type' => 'feature'],
        ],
    ],

    // Output paths (defaults shown)
    'output' => [
        'manifest' => base_path('necromancer.json'),
        'context'  => base_path('NECROMANCER.md'),
    ],

    // Laravel Boost integration
    'boost' => [
        'context_path' => base_path('.ai/guidelines/necromancer.md'),
    ],

    // Route metadata (Laravel 13.17+ Route::metadata()) — the namespace key Necromancer reads
    'route_metadata' => [
        'namespace' => 'necromancer',
    ],

];
```

Privacy &amp; Exclusions
------------------------

[](#privacy--exclusions)

Necromancer is designed to be safe to version by default:

- It never reads `.env` or raw configuration values.
- It never collects or stores application secrets.
- Routes registered by Horizon, Telescope, and Debugbar are excluded from scans automatically.
- Laravel's default `/up` health-check endpoint is excluded automatically via `exclude.route_uris`, so it never shows up as an unnamed-route audit finding.

To exclude additional routes or models, add patterns to the `exclude` key in `config/necromancer.php`. The `exclude.routes` patterns match against the route **name** (and therefore never match unnamed routes); use `exclude.route_uris` to exclude routes by **URI** — including unnamed ones such as health checks. Both use `Str::is()` wildcard matching, and route URIs are matched without a leading slash (e.g. `up`, `orders/*`). Exclusions apply to every downstream command — map, audit, doctor, and generate — so excluded artifacts never appear in results.

Laravel Boost Integration
-------------------------

[](#laravel-boost-integration)

When [Laravel Boost](https://github.com/laravel/boost) is installed, `necromancer:generate` automatically writes the context file to `.ai/guidelines/necromancer.md` (configurable via `boost.context_path`) instead of `NECROMANCER.md`. Boost remains responsible for composing the final agent context; Necromancer only contributes its section.

An explicit `--output=PATH` flag always takes precedence over the Boost path.

MCP Tools
---------

[](#mcp-tools)

When [Laravel MCP](https://github.com/laravel/mcp) is installed, Necromancer automatically exposes the manifest as read-only MCP tools via a `laravel-necromancer` server handle:

ToolDescription`query_routes`List routes, optionally filtered by method or name/URI pattern`query_models`List Eloquent models, optionally filtered by class name`query_artifacts`List artifacts of any current type, optionally filtered by JSON substring`search_artifacts`Full-text search across all artifact typesUse `query_artifacts` when you already know the artifact type (`routes`, `models`, `form_requests`, `jobs`, `events`, `listeners`, `commands`, `observers`, `policies`, `enums`, `tests`, `scheduled_tasks`, `middleware`, `livewire_components`, `gates`, `mailables`, `validation_rules`, or `service_providers`). Use `search_artifacts` when you need to search across types.

When `laravel/mcp` is present, Necromancer also writes its entry into `.mcp.json` automatically on the first `php artisan` run after installation — no manual configuration needed. If `.mcp.json` already exists, the entry is merged without touching other servers.

AI agents connected via Claude Code, Cursor, or any MCP client can then call these tools directly rather than reading `necromancer.json` by hand.

> **Requires** `laravel/mcp` installed. Run `php artisan necromancer:scan` to ensure the manifest is current before connecting an agent.

CI Integration
--------------

[](#ci-integration)

Add these steps to your CI pipeline to enforce manifest freshness and AI-readability quality:

```
- name: Check manifest is up to date
  run: php artisan necromancer:scan --diff --fail-on-drift

- name: Fail on AI-readability errors
  run: php artisan necromancer:audit --fail-on=error

- name: Enforce minimum AI readability score
  run: php artisan necromancer:doctor --min-score=80
```

Contributing
------------

[](#contributing)

Bug reports and pull requests are welcome on the [GitHub repository](https://github.com/robertogallea/laravel-necromancer).

License
-------

[](#license)

MIT

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance96

Actively maintained with recent releases

Popularity23

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

3

Last Release

32d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/818f547bcf73a82393d9014c85c90c83d760102a8d4dfe806353afb83848a901?d=identicon)[robertogallea](/maintainers/robertogallea)

---

Top Contributors

[![robertogallea](https://avatars.githubusercontent.com/u/19411470?v=4)](https://github.com/robertogallea "robertogallea (55 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/robertogallea-laravel-necromancer/health.svg)

```
[![Health](https://phpackages.com/badges/robertogallea-laravel-necromancer/health.svg)](https://phpackages.com/packages/robertogallea-laravel-necromancer)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
