Command Reference
The PHPNomad CLI ships five commands. All of them operate on a project directory that you point to with --path. If you omit --path, the CLI defaults to the current working directory.
phpnomad <command> [options]
phpnomad index
Scans a PHPNomad project using AST analysis and builds the full JSONL index inside the .phpnomad/ directory. This is the foundation that the other commands depend on. Running index explicitly is optional because inspect:di, inspect:routes, and context will build the index automatically when one does not already exist.
Syntax
phpnomad index [--path=<dir>]
Options
| Option | Default | Description |
|---|---|---|
--path |
./ |
Path to the target project directory. |
Example
phpnomad index --path=/var/www/my-app
Example output
Index written to /var/www/my-app/.phpnomad/
meta.json, classes.jsonl, initializers.jsonl, applications.jsonl,
controllers.jsonl, commands.jsonl, dependencies.jsonl,
tables.jsonl, events.jsonl, graphql-types.jsonl,
facades.jsonl, task-handlers.jsonl, mutations.jsonl,
dependency-map.jsonl, dependents-map.jsonl, orphans.jsonl,
phpnomad-cli.md
Summary
Applications: 4
Initializers: 74
Bindings: 244
Controllers: 110
Commands: 23
Tables: 39
Events: 82
Listeners: 151
GraphQL types: 0
Facades: 29
Task handlers: 1
Mutations: 0
Dependencies: 186
Dep map: 487
Dependents map: 392
Orphans: 50
Classes: 1019
The command produces 16 JSONL files plus a meta.json and a phpnomad-cli.md context file. See the output format reference for details on each file.
phpnomad inspect:di
Displays the boot sequence and DI bindings in a human-readable tree. The tree walks through each application class, its pre-bootstrap bindings, the numbered boot sequence of initializers, and the post-bootstrap bindings. This is the fastest way to understand how a project wires itself together at startup.
Syntax
phpnomad inspect:di [--path=<dir>] [--format=<format>] [--fresh]
Options
| Option | Default | Description |
|---|---|---|
--path |
./ |
Path to the target project directory. |
--format |
table |
Output format. table renders the human-readable tree. json dumps the raw index as JSON. |
--fresh |
off | Force a re-index instead of reading the cached .phpnomad/ data. |
Examples
# Tree view from the current directory
phpnomad inspect:di
# JSON output for a specific project
phpnomad inspect:di --path=/var/www/my-app --format=json
# Force re-index before displaying
phpnomad inspect:di --path=/var/www/my-app --fresh
Example output (table format)
Application: App\MyApp (/var/www/my-app/lib/MyApp.php)
Pre-bootstrap bindings:
[bind] Strategies\MySqlStrategy -> Interfaces\DatabaseStrategy
[factory] Strategies\RedisCache -> Interfaces\CacheStrategy
Boot sequence (12 initializers, bootstrap()):
#1 CoreInit 3 bindings, 2 listeners
#2 AuthInit 5 bindings
#3 DatabaseInit 4 bindings, 1 listener
#4 RestInit 8 bindings
#5 --- $this->loadModules() (dynamic) ---
#6 EventInit 2 bindings, 6 listeners
#7 CacheInit (vendor) 1 binding
#8 MailInit 2 bindings
#9 TaskInit 1 binding, 1 listener
#10 GraphQLInit 3 bindings
#11 AdminInit 6 bindings, 4 listeners
#12 CronInit 1 binding
Post-bootstrap bindings:
[factory] Factories\AppConfigFactory -> Interfaces\ConfigProvider
Summary
1 application(s)
12 initializers
36 bindings
22 controllers
5 commands
14 listeners
8 tables
12 events
4 facades
1 task handlers
0 mutations
18 dependency trees
Initializers loaded from vendor packages are tagged (vendor). Dynamic boot calls (like iterating over a module list) appear as --- source (dynamic) --- because the CLI cannot statically resolve them.
phpnomad inspect:routes
Lists all REST routes in the project, grouped by HTTP method. Each route shows its endpoint path, the controller FQCN (shortened to the last three namespace segments), and capability badges indicating which cross-cutting concerns are attached.
Syntax
phpnomad inspect:routes [--path=<dir>] [--format=<format>] [--fresh]
Options
| Option | Default | Description |
|---|---|---|
--path |
./ |
Path to the target project directory. |
--format |
table |
Output format. table renders grouped routes. json dumps the raw index as JSON. |
--fresh |
off | Force a re-index instead of reading the cached .phpnomad/ data. |
Examples
# Table view from the current directory
phpnomad inspect:routes
# JSON output for a specific project
phpnomad inspect:routes --path=/var/www/my-app --format=json
Example output (table format)
GET (5)
/api/users Controllers\ListUsersController [middleware, validations]
/api/users/(?P<id>\d+) Controllers\GetUserController [middleware]
{base}/settings Controllers\GetSettingsController [middleware, validations]
{base}/dashboard Controllers\DashboardController
{base}/health Controllers\HealthCheckController
POST (3)
/api/users Controllers\CreateUserController [middleware, validations, interceptors]
/api/auth/login Controllers\LoginController [validations]
{base}/webhooks Controllers\WebhookController [middleware, interceptors]
DELETE (1)
/api/users/(?P<id>\d+) Controllers\DeleteUserController [middleware, validations]
Summary
9 controller(s)
6 with middleware
5 with validations
2 with interceptors
3 using WithEndpointBase
Capability badges
| Badge | Meaning |
|---|---|
middleware |
Controller has middleware attached (auth, pagination, etc.). |
validations |
Controller defines input validation rules. |
interceptors |
Controller has post-response interceptors (events, logging, etc.). |
The {base} prefix
Controllers that use the WithEndpointBase trait show {base} as the first segment of their path. This prefix is resolved at runtime from configuration, so the CLI cannot determine the actual value statically. The summary line reports how many controllers use this pattern.
phpnomad context
Generates a compact project context document as markdown. This is designed for AI agents that need a quick structural overview of a project without reading every source file. The output covers routes, tables, events, facades, commands, task handlers, bindings, GraphQL types, and mutations.
Syntax
phpnomad context [--path=<dir>] [--fresh] [--sections=<list>] [--output=<dest>]
Options
| Option | Default | Description |
|---|---|---|
--path |
./ |
Path to the target project directory. |
--fresh |
off | Force a re-index instead of reading the cached .phpnomad/ data. |
--sections |
all | Comma-separated list of sections to include. Available sections: routes, tables, events, facades, commands, tasks, bindings, graphql, mutations. |
--output |
stdout |
Output destination. stdout prints to the terminal. file writes to .phpnomad/context.md. |
Examples
# Full context to stdout
phpnomad context --path=/var/www/my-app
# Only routes and tables, written to a file
phpnomad context --path=/var/www/my-app --sections=routes,tables --output=file
# Just events and bindings
phpnomad context --path=/var/www/my-app --sections=events,bindings
Example output (partial)
# Project Context
path: /var/www/my-app
indexed: 2026-04-13T10:30:00+00:00
routes: 22 | tables: 8 | events: 12 | commands: 5 | facades: 4 | bindings: 36
## Routes
### GET (5)
/api/users Controllers\ListUsersController [middleware, validations]
/api/users/(?P<id>\d+) Controllers\GetUserController [middleware]
{base}/settings Controllers\GetSettingsController [middleware]
### POST (3)
/api/users Controllers\CreateUserController [middleware, validations, interceptors]
## Tables
users: id(bigint PK), email(varchar[255]), name(varchar[100]), created_at(datetime), updated_at(datetime)
posts: id(bigint PK), user_id(bigint FK), title(varchar[255]), body(text), status(varchar[20])
## Events
user.created (Events\UserCreated): userId(int), email(string)
-> Listeners\SendWelcomeEmail (via AppInit)
-> Listeners\CreateDefaultSettings (via AppInit)
When --output=file is used, the command writes to .phpnomad/context.md and prints a confirmation message instead of the content itself.
phpnomad make
Generates PHP files from a recipe specification and auto-registers the new classes in the appropriate initializer. Recipes define what files to create, what template to use, and where to register the result. The command runs preflight validation before writing anything, so it will catch missing variables and other problems up front.
Syntax
phpnomad make --from=<recipe> [--path=<dir>] [<vars>]
Options
| Option | Default | Description |
|---|---|---|
--from |
required | Recipe name (for built-in recipes) or path to a custom JSON recipe file. |
--path |
./ |
Path to the target project directory. |
The positional <vars> argument is a JSON object containing the variable values that the recipe requires. Each recipe defines its own set of variables.
Built-in recipes
The CLI ships four built-in recipes:
| Recipe | Purpose |
|---|---|
listener |
Creates an event listener class and registers it in an initializer. |
event |
Creates an event class. |
command |
Creates a console command class and registers it. |
controller |
Creates a REST controller class and registers it. |
See the built-in recipes reference for the full variable definitions and templates for each recipe.
Examples
# Create a listener from the built-in recipe
phpnomad make --from=listener '{"name":"SendWelcomeEmail","event":"App\\Events\\UserCreated","initializer":"App\\AppInit"}'
# Create a controller
phpnomad make --from=controller '{"name":"ListPayouts","initializer":"App\\RestInit"}'
# Use a custom recipe file
phpnomad make --from=./recipes/feature.json '{"name":"Payout"}'
Example output (success)
Recipe: listener
Create an event listener class
Created: lib/Listeners/SendWelcomeEmail.php
Registered: registerListeners() in App\AppInit
Done: 1 file(s) created, 1 registration(s) performed.
Example output (validation failure)
If required variables are missing or other preflight checks fail, the command reports the errors and exits without writing any files.
Recipe: listener
Create an event listener class
Preflight validation failed:
- Missing required variable: name (Listener class name)
- Missing required variable: event (FQCN of the event class)
Other validation checks include verifying that target files do not already exist, that the specified initializer file can be found on disk, and that any required DI bindings are present in the project index.
Custom recipes
You can point --from at any JSON file to use a custom recipe. The recipe format defines variables, file templates, and registration instructions. See the scaffolder introduction for the full recipe specification.