nadeemkhan / atlas-self-scan
Install AtlasScope into a Laravel application and it maps that application: its own routes, controllers, models and tables, in 3D, at /atlas. No upload, no configuration.
Requires
- php: ^8.1
- laravel/framework: ^10.50 || ^11.0 || ^12.0 || ^13.0
- nadeemkhan/atlas-scope: ^1.0
Requires (Dev)
- orchestra/testbench: ^8.39 || ^9.0 || ^10.0 || ^11.0
- phpunit/phpunit: ^10.1 || ^11.5 || ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Install AtlasScope into a Laravel
application and it maps that application: its own routes, controllers, models,
tables and jobs, drawn as a 3D map at /atlas.
composer require atlas/self-scan php artisan migrate
Open /atlas in a browser. That is the whole install. There is nothing to
upload, no project to add, no scan command to remember and no worker to start:
- the first request registers the application as a project,
- scans it (inline, in that request),
- and opens the finished map.
/atlas ──▶ /atlas/projects/9f2c…/atlas "Harbour Desk — 3D atlas"
Your application's code is what you are looking at: App\Models\User,
route:GET /tasks, the tasks table, with their relationships. Nothing about
a sample project, nothing copied out of the repository.
What it adds to AtlasScope
AtlasScope on its own knows how to map a codebase it is handed — an uploaded archive, or a directory someone points it at — and it knows nothing about the application it happens to be installed in. This package is the small piece that closes that gap:
| AtlasScope alone | With atlas/self-scan | |
|---|---|---|
| What is mapped | projects you add yourself | the application you installed it into |
/atlas opens |
the project list | this application's map |
| Kept updated | when you press re-scan | when the code has changed |
| Extra routes | — | none added |
It is a companion, not a fork. AtlasScope still serves the UI, the scanner, the API and the 3D renderer; this package requires it and adds a middleware plus one command.
Configuration
Everything is optional and overridable from .env. Publish the file to edit it:
php artisan vendor:publish --tag=self-scan-config
| Setting | .env |
Default | Purpose |
|---|---|---|---|
enabled |
ATLAS_SELF_SCAN |
true |
Off leaves a plain AtlasScope install |
path |
ATLAS_SELF_PATH |
base_path() |
Which directory to map — pointing it elsewhere moves the map rather than adding a second project |
name |
ATLAS_SELF_NAME |
config('app.name') |
Name shown in the UI |
landing |
ATLAS_SELF_LANDING |
project |
project opens the map, projects opens the list |
refresh |
ATLAS_SELF_REFRESH |
true |
Re-scan when watched files change |
min_interval |
ATLAS_SELF_MIN_INTERVAL |
60 |
Shortest gap between automatic scans |
budget |
ATLAS_SELF_BUDGET |
4000 |
Files stat-ed per staleness check |
sync |
ATLAS_SELF_SYNC |
true |
Scan inline instead of dispatching a job |
watch (which directories count as "the application changed") is a plain array
in the config file: app, routes, config, database/migrations,
resources/views, composer.json, composer.lock.
Keeping the map current
Opening any atlas page compares the modified time of the watched files against
the last scan, and re-scans if something is newer. The walk skips vendor/,
node_modules/, storage/ and the rest of the same list the scanner skips, and
stops after budget files — a large application is treated as changed, which is
the safe direction to fail in. The polling endpoints (/atlas/api/atlas/…) are
exempt, so a page left open does not scan in a loop.
Set ATLAS_SELF_MIN_INTERVAL=0 to re-scan on any visit where something changed.
The command
php artisan atlas:self-scan # register + scan, for CI or a shell php artisan atlas:self-scan --force # scan even if nothing changed php artisan atlas:self-scan --reset # forget the row, then scan afresh php artisan atlas:self-scan --queue # dispatch instead of running inline
INFO Scanning Harbour Desk at /var/www/app.
Project ............................................... #1 · Harbour Desk
Scan .............................. completed · 76 nodes · 25 relationships
Atlas .................. http://localhost/atlas/projects/50938b38…/atlas
Nothing else changes in the host application: no config file to publish, no service provider to register, no routes of its own, no published views. Remove the package and what is left is a plain AtlasScope installation.
How it works
A middleware joins AtlasScope's route group (atlas.routes.middleware) rather
than registering routes of its own, so there is one set of routes, one prefix and
one UI. On an atlas page it asks SelfProject to ensure the row exists, then
gets out of the way:
SelfProjectdecides which directory represents this application, keeps a single project row pointing at it (ProjectManager::adopt(), the same call the upload path uses), marks itmeta.self = true, and starts scans.Freshnessanswers "has anything watched changed since the last scan?" — a bounded, skip-aware walk.- Nothing is fatal. No atlas tables yet (
migratenot run), a missing path, a database that cannot be asked — each is a quiet no-op with a log line, never a broken page.
That last point is deliberate: a package that can break the host application on its first request is worse than no package.
Requirements
| PHP | 8.1 or newer (8.1 – 8.4 verified) |
| Laravel | 10.50+ , 11, 12, 13 |
| AtlasScope | atlas/scope ^1.0 (required automatically) |
Laravel 10 sets the floor at PHP 8.1 and Laravel 13 raises it to PHP 8.3; the package itself needs no more than 8.1.
Tests
composer test # the suite on this installation composer test:matrix # the suite against Laravel 10, 11, 12 and 13
The matrix uses orchestra/testbench 8/9/10/11 and skips a cell whose Laravel
major needs a newer PHP than the one running. Each cell installs atlas/scope
from, in order: ATLAS_SCOPE_PATH, the sibling directory
(../atlas-scope-package), or the copy composer installed here.
Verified: 19 tests, 65 assertions, all green on Laravel 10.50.3 → 13.34.0 (testbench 8.39 → 11.3) on PHP 8.4, and on PHP 8.1 for the Laravel 10 cell.
Acceptance on a real host
A stock laravel/laravel:^10.0 application, composer require atlas/self-scan,
php artisan migrate, then a browser opens /atlas for the first time — with an
empty database and no visit to any other page:
first visit → /atlas/projects/b934e445-…/atlas (2761 ms, scan included)
project: Harbour Desk · Laravel 10.50.3 · 827 KB
graph: 76 nodes, 25 relationships, 9 layers (App\Models\User, route:GET /)
scene: 76 nodes drawn, canvas 916×942
requests: none failed · console: no errors
second visit: same page, no re-scan (1 project, 1 scan in the database)
Then an edit to app/Http/Controllers/Controller.php and one reload: the next
scan picks it up, and a reload with nothing changed does not add another.
Evidence: docs/screenshots/laravel-10-host.png.
Installing the package before migrate is fine — the middleware sees there
are no atlas tables and stays out of the way — but the atlas pages themselves
need the tables, so /atlas will show the usual "no such table" error until
php artisan migrate has run. That is the same as any Laravel package with a
migration.
Licence
MIT.