Skip to content

Architecture

ADP follows a strict layered architecture where each layer has clear responsibilities and dependencies flow in one direction.

Layers

1. Kernel

The core engine. Framework-independent — depends only on PSR interfaces and generic PHP libraries. Manages:

2. API

HTTP layer built on PSR-7/15. Provides:

  • REST endpoints — Fetch debug entries, collector data
  • SSE — Real-time notifications for new entries
  • Inspector — Runtime inspection endpoints (config, routes, database schema, etc.)
  • MCP — AI assistant integration via Model Context Protocol
  • Ingestion — Accept debug data from external (non-PHP) applications

3. Adapters

Framework bridges. Each adapter:

  • Registers proxy services in the framework's DI container
  • Maps framework lifecycle events to DebuggerAppDevPanel\Kernel\DebuggerClass Debugger.final Kernel · class::startup() / ::shutdown()
  • Configures collectors and storage with framework-appropriate settings
  • Registers API routes (/debug/api/*, /inspect/api/*)
  • Serves the debug panel frontend at /debug
  • Implements framework-specific inspector providers (config, routes, database schema)

4. Frontend

React 19 SPA with:

  • Material-UI 5 design system
  • Redux Toolkit for state management
  • Module system (Debug, Inspector, LLM, MCP, OpenAPI, Frames)

Dependency Graph

┌────────────────────────────────────────────────────────┐
│                  Dependency Direction                    │
│                                                         │
│   Adapter ──▶ API ──▶ Kernel                            │
│      │                   ▲                              │
│      └───────────────────┘                              │
│                                                         │
│   Cli ──▶ API ──▶ Kernel                                │
│                                                         │
│   Frontend ──▶ API (via HTTP only)                      │
└────────────────────────────────────────────────────────┘
  • Kernel depends on nothing (PSR interfaces only)
  • API depends only on Kernel
  • Cli depends on Kernel and API
  • Adapter depends on Kernel, API, and the target framework
  • Frontend communicates via HTTP — no PHP dependencies

Dependency Rules

The core principle: common modules must never depend on framework-specific code.

ModuleCan depend onCannot depend on
KernelPSR interfaces onlyAPI, Cli, Adapter, any framework
APIKernel, PSR interfacesAdapter, any framework
CliKernel, API, Symfony ConsoleAdapter, any framework
AdapterKernel, API, Cli, framework packagesOther adapters
FrontendNothing (HTTP only)Any PHP package

WARNING

Adapters must not depend on other adapters. Each adapter is an independent bridge between the Kernel and a specific framework.

Abstractions

Storage and serialization remain behind interfaces to ensure pluggability:

ConcernAbstractionImplementations
Debug data storageStorageInterfaceAppDevPanel\Kernel\Storage\StorageInterfaceDebug data storage responsibility is to store debug data from collectors addedKernel · interfaceFileStorageAppDevPanel\Kernel\Storage\FileStorageClass FileStorage.final Kernel · class · implements StorageInterface, MemoryStorageAppDevPanel\Kernel\Storage\MemoryStorageClass MemoryStorage.final Kernel · class · implements StorageInterface
Object serializationDumperAppDevPanel\Kernel\DumperClass Dumper.final Kernel · classJSON-based (built-in)
Database inspectionSchemaProviderInterfaceAppDevPanel\Api\Inspector\Database\SchemaProviderInterfaceSchema Provider contract.API · interfacePer-adapter: DbSchemaProviderAppDevPanel\Adapter\Yii3\Inspector\DbSchemaProviderProvides Db Schema data.Adapter/Yii3 · class · implements SchemaProviderInterface, DoctrineSchemaProviderAppDevPanel\Adapter\Symfony\Inspector\DoctrineSchemaProviderProvides database schema inspection via Doctrine DBAL.final Adapter/Symfony · class · implements SchemaProviderInterface, LaravelSchemaProviderAppDevPanel\Adapter\Laravel\Inspector\LaravelSchemaProviderProvides database schema inspection via Laravel's Illuminate\Database\Connection.final Adapter/Laravel · class · implements SchemaProviderInterface, NullSchemaProviderAppDevPanel\Adapter\Yii2\Inspector\NullSchemaProviderNo-op schema provider for when no database is configured. Returns empty results instead of causing a 500 error.final Adapter/Yii2 · class · implements SchemaProviderInterface, CycleSchemaProviderAppDevPanel\Adapter\Cycle\Inspector\CycleSchemaProviderProvides Cycle Schema data.Adapter/Cycle · class · implements SchemaProviderInterface

Data Flow

  1. Target app runs with an Adapter installed
  2. Adapter registers proxies that intercept PSR interfaces
  3. Proxies feed data to Collectors
  4. On request completion, Debugger flushes collector data to Storage
  5. API serves stored data; SSE notifies the frontend
  6. Frontend renders the data

See Data Flow for the full lifecycle details.

Frontend Module System

The frontend uses a module system where each module implements ModuleInterface:

typescript
interface ModuleInterface {
    routes: RouteObject[];
    reducers: Record<string, Reducer>;
    middlewares: Middleware[];
    standalone: boolean;
}

Current modules: Debug, Inspector, LLM, MCP, OpenAPI, Frames.

Creating a New Adapter

When creating an adapter for a new framework:

  1. Create libs/Adapter/<FrameworkName>/
  2. The adapter must depend on app-dev-panel/kernelversiondownloadsapp-dev-panel/kernelView on Packagistversiondownloadslicensephp version
  3. The adapter may depend on app-dev-panel/apiversiondownloadsapp-dev-panel/apiView on Packagistversiondownloadslicensephp version (for route and inspector registration)
  4. The adapter may depend on app-dev-panel/cliversiondownloadsapp-dev-panel/cliView on Packagistversiondownloadslicensephp version (for CLI commands)
  5. The adapter must not depend on other adapters
  6. The adapter must not modify Kernel or API code — only wire into them via configuration

Adapter Responsibilities

ResponsibilityDescription
Lifecycle mappingMap framework events → DebuggerAppDevPanel\Kernel\DebuggerClass Debugger.final Kernel · class::startup() / ::shutdown()
Proxy wiringRegister Kernel PSR proxies as service decorators in the framework's DI
Framework-specific proxiesCreate proxies for non-PSR APIs (e.g., SymfonyEventDispatcherProxyAppDevPanel\Adapter\Symfony\Proxy\SymfonyEventDispatcherProxyWraps Symfony's event dispatcher to intercept dispatched events.final Adapter/Symfony · class · implements EventDispatcherInterface)
Collector configurationConfigure active collectors and pass framework-specific settings
Storage setupWire StorageInterfaceAppDevPanel\Kernel\Storage\StorageInterfaceDebug data storage responsibility is to store debug data from collectors addedKernel · interface with framework-appropriate paths
Route registrationRegister API routes for /debug/api/*, /inspect/api/* and serve the frontend at /debug
Inspector providersImplement SchemaProviderInterfaceAppDevPanel\Api\Inspector\Database\SchemaProviderInterfaceSchema Provider contract.API · interface, ElasticsearchProviderInterfaceAppDevPanel\Api\Inspector\Elasticsearch\ElasticsearchProviderInterfaceElasticsearch Provider contract.API · interface, etc.

Reference Implementations

AdapterFrameworkPattern
SymfonySymfony 6.4–8.xBundle + Extension + CompilerPass
Yii2Yii 2Module + BootstrapInterface
Yii 3Yii 3Config plugin + ServiceProvider
LaravelLaravel 11.x–12.xServiceProvider (register + boot)

Minimal Checklist

  1. composer.json with app-dev-panel/kernelversiondownloadsapp-dev-panel/kernelView on Packagistversiondownloadslicensephp version + app-dev-panel/apiversiondownloadsapp-dev-panel/apiView on Packagistversiondownloadslicensephp version dependencies
  2. Lifecycle event mapping → DebuggerAppDevPanel\Kernel\DebuggerClass Debugger.final Kernel · class::startup() / ::shutdown()
  3. Register Kernel PSR proxies as service decorators (logger, events, HTTP client)
  4. Wire FileStorageAppDevPanel\Kernel\Storage\FileStorageClass FileStorage.final Kernel · class · implements StorageInterface with a framework-appropriate path
  5. Register API controller routes
  6. Create a playground for testing and demo

Released under the MIT License.