Command Line Tools
App Inspection
Six read-only commands cluster on this page. None of them mutate state — they read your project (or, for wheels lookup, the CLI’s own docs index), print what they find, and exit. Reach for them when you’re diagnosing an unfamiliar setup or getting a quick inventory of an app you haven’t touched in a while.
You’ll use this for:
- Seeing every route your application declares without opening
config/routes.cfm. - Checking the installed framework version, datasource name, and server status at a glance.
- Counting models, controllers, views, and tests — and finding outliers with
--verbose. - Sweeping the codebase for
TODO,FIXME, andOPTIMIZEmarkers before a release. - Running a health check when something is misconfigured and you don’t know where to start.
- Looking up a framework function’s parameters, or a guide topic, without a browser or a network connection.
wheels routes
Section titled “wheels routes”Print the dispatch table for the running application — every route declared in config/routes.cfm plus any that framework defaults register at boot.
Synopsis
Section titled “Synopsis”wheels routes [--filter=<text>] [--format=text|json]Description
Section titled “Description”wheels routes HTTP-dispatches to the development server at /wheels/cli?command=routes&format=json and formats the returned route table. That means it requires a running server — start one with wheels start first. If no server is detected on any configured port, the command prints an error and exits without output.
The route table comes from the running application, so it includes the framework’s own /wheels/* routes. The text output is a columnar listing: HTTP method, pattern, and controller#action with the route name in parentheses, followed by a <n> route(s) count.
| Flag | Description |
|---|---|
--filter=<text> | Show only routes whose name, pattern, or controller#action contains this text (case-insensitive). When nothing matches, prints No routes match '<text>'. |
--format=<format> | text (default, aligned table) or json (the route array as JSON). |
Example
Section titled “Example”wheels routesSample output (trimmed):
METHOD PATTERN CONTROLLER#ACTION-----------------------------------------------------------------------------------GET /wheels/info wheels.public#info (wheelsInfo)...GET /posts posts#index (posts)GET /posts/new posts#new (newPost)POST /posts posts#create (posts)GET / main#index (root)
41 route(s)wheels info
Section titled “wheels info”Summarise the project’s environment in a short block — CLI version, installed framework version, engine, datasource, and whether a server is running.
Synopsis
Section titled “Synopsis”wheels infoDescription
Section titled “Description”wheels info reads the project locally (no server required) and emits a human-readable summary. It detects the Wheels version from vendor/wheels/wheels.json, the datasource from config/settings.cfm, the presence of .env and lucee.json, and counts any .resources(…) calls in config/routes.cfm plus the CFC files under app/models/. It also calls detectServerPort() to report whether the dev server is currently up.
When the current directory is not a Wheels project (no vendor/wheels/ present), the command prints a single line saying so and exits.
None. wheels info takes no flags — ignore any reference to --json or --quiet; those were never wired up.
Output stream
Section titled “Output stream”Output is written to stdout. If you’re piping wheels info into another tool, it reads from stdout directly — no 2> redirection needed. The process exits successfully either way; no non-zero exit is raised when the summary is empty.
Example
Section titled “Example”wheels infoSample output (trimmed):
Wheels CLI v4.0.0
Project: /path/to/myblogWheels: v4.0.0Engine: Lucee (LuCLI module)Database: myblogEnv file: .env foundConfig: lucee.json foundRoutes: 3 resource route(s)Models: 5 model(s)Server: not runningThe first line is preceded by a small Wheels banner in some terminals — reproduce it in full only if your docs workflow requires it.
wheels stats
Section titled “wheels stats”Count files, lines of code, comments, and blanks by category (models, controllers, views, tests, and so on), then print a totals row and a code-to-test ratio.
Synopsis
Section titled “Synopsis”wheels stats [--verbose | -v]| Flag | Description |
|---|---|
--verbose, -v | Append a “Top 10 Largest Files” list after the totals row. Useful when hunting for views or controllers that have grown past the point of sanity. |
Example
Section titled “Example”wheels statsSample output (trimmed):
Code Statistics======================================================================Category Files LOC Comments Blanks Total----------------------------------------------------------------------Models 5 142 18 31 191Controllers 6 287 42 68 397Views 24 512 12 94 618Tests 18 634 56 112 802----------------------------------------------------------------------Total 53 1575 128 305 2008
Code-to-test ratio: 1:0.67Average lines/file: 29wheels notes
Section titled “wheels notes”Scan the project for inline annotations (TODO, FIXME, OPTIMIZE by default) and print each hit with its file path, line number, and the text after the marker.
Synopsis
Section titled “Synopsis”wheels notes [--annotations=<list>] [--custom=<tag>]| Flag | Description |
|---|---|
--annotations=<list> | Comma-separated list of markers to search for. Default: TODO,FIXME,OPTIMIZE. Case-insensitive. |
--custom=<tag> | Additional single marker to include alongside the defaults (or the list set with --annotations=). |
Example
Section titled “Example”wheels notesSample output (trimmed):
TODO (2): app/controllers/Posts.cfc:47 -- paginate once we break 100 posts app/models/User.cfc:112 -- extract password policy into a validator
FIXME (1): app/views/posts/show.cfm:23 -- escape HTML in the excerpt
Summary: 3 annotations (2 TODO, 1 FIXME)When nothing matches, the command prints No annotations found. in green and exits.
wheels doctor
Section titled “wheels doctor”Run a battery of health checks against the project — required and recommended directories, required config files, write permissions, whether a datasource is configured, migration and test file counts, framework availability, and mixin collisions — and print a list of passes, warnings, and issues with an overall status. It reads files only; it does not connect to the database.
Synopsis
Section titled “Synopsis”wheels doctor [--verbose | -v]| Flag | Description |
|---|---|
--verbose, -v | Always print the list of passed checks. Without this flag, passes are shown only when the overall status is HEALTHY (i.e., zero issues and zero warnings). |
Example
Section titled “Example”wheels doctorSample output (trimmed):
Wheels Health Check========================================
Warnings (2): ! Missing recommended directory: tests/ ! Missing recommended directory: tests/specs/
Status: WARNING
Recommendations: * Run 'wheels generate test' to add test coverageStatus is one of HEALTHY, WARNING, or CRITICAL. HEALTHY and WARNING exit 0; CRITICAL exits non-zero, so wheels doctor can gate a script. Issues (red) indicate the project cannot run as configured; warnings (yellow) flag things that work but look off; recommendations (cyan) are optional suggestions keyed off what the checks found.
wheels lookup
Section titled “wheels lookup”Look up the Wheels API reference and the guides offline. The CLI ships a docs index for its own framework version: every API function with its parameters and examples, and every guide section. It needs no network, no running server, and no project. AI assistants reach the same lookup through the lookup MCP tool.
Synopsis
Section titled “Synopsis”wheels lookup <query> [--kind=all|api|guides] [--limit=5] [--format=text|json]Arguments and flags
Section titled “Arguments and flags”| Argument / flag | Default | Description |
|---|---|---|
<query> | (required) | A function name (findAll, findAll(), model.findAll), a phrase (nested resources), or an id from an earlier result (api:model.findAll, guides:basics/routing#nested-resources). |
--kind | all | api searches only the API reference, guides only the guides. |
--limit | 5 | The most results to list, from 1 to 20. |
--format | text | json prints the result as JSON. |
What it returns
Section titled “What it returns”- A function name prints the whole API entry: the signature and return type, where it’s available (model, controller, mapper, and so on), the description, every parameter with its type, default and description, the example, and the link to api.wheels.dev. A name that exists in several places (
deleteon a model object and on the route mapper) prints each one;model.deletenarrows it to one. - Anything else lists the best matches, guide sections and API functions together, each with a snippet, its link, and an id. Pass that id back to print the whole entry.
- Nothing matching prints
No matchesand exits 0.
Examples
Section titled “Examples”wheels lookup findAllwheels lookup "nested resources"wheels lookup "background job retry" --kind=guides --limit=3wheels lookup "guides:basics/routing#nested-resources"The index describes the framework version the CLI was built with. When you run the CLI from a source checkout there’s no index until you build one with node tools/build/scripts/build-docs-index.mjs; until then wheels lookup says so and exits non-zero. For the browsable HTML docs offline, use wheels docs fetch.
Common workflows
Section titled “Common workflows”Quick setup verification
Section titled “Quick setup verification”wheels doctorRun this first when a project acts strangely or when you’ve just cloned someone else’s app. If the status is HEALTHY or WARNING, you can usually start the server; CRITICAL means something is structurally wrong.
See what exists
Section titled “See what exists”wheels info && wheels stats && wheels routesThree commands, in order, give you: versions and environment, artifact counts, and the routing table. Run this after inheriting an app to orient yourself in under a minute. (Remember wheels routes needs a running server.)
Find stale work
Section titled “Find stale work”wheels notes --annotations=TODO,FIXME,HACK,XXXSweep before a release. Widen the marker list with --annotations= or tack on a single extra tag with --custom=DEPRECATED.