Skip to content

Commit 3a0f90a

Browse files
bpamiriclaude
andauthored
docs: align CLI core guides with 4.0.3 behavior — MCP tool names, version output, inert flags (#3124)
* docs: align CLI core guides with 4.0.3 behavior — MCP tool names, version output, inert test flags Guide behavioral audit (P2), manifest group 4 — 7 findings across the four command-line-tools core pages, all live-verified against the released 4.0.3 CLI: - installation.mdx: replace the fictional 3-line 'Wheels/LuCLI/Java' version sample with the real shapes ('wheels --version' prints 'Wheels Version: 4.0.3' + banner; 'wheels version' prints 'Wheels 4.0.3 (stable)' + Java line); channel marker comes from 'wheels version', not 'wheels --version'; 'wheels system env' does not exist — point at 'wheels system paths' (installation-01/-04). - quick-start.mdx: scaffold writes PostSpec.cfc + PostsControllerSpec.cfc (no PostsSpec.cfc), and the 'posts' positional is a directory scope (tests.specs.posts) that matches nothing on a fresh scaffold; generated specs are empty stubs so runs report 0 passed (quickstart-04/-05). - mcp-integration.mdx: tool names are unprefixed in tools/list (18 bare names: analyze..validate), not wheels_*; bare 'wheels mcp' is intercepted by the LuCLI launcher ('mcp: missing module name') and never prints the snippet — document the --once smoke test instead (mcp-02/-04). Same prefix fix applied to the Module.cfc mcp() help text and the root CLAUDE.md CLI/MCP section. - wheels-commands/testing.mdx: 'wheels test --verbose' and '--ci' are accepted but currently inert (output byte-identical to a plain run; exit codes already non-zero on failure) — describe current behavior and cite #3113 for the wiring fix (testing-05). Signed-off-by: Peter Amiri <peter@alurium.com> * docs: fix malformed code fence info string in installation verify section Backticks inside a backtick-fence info string are forbidden by CommonMark, so the opening line rendered as a literal paragraph and the intended closing fence opened a runaway code block that swallowed the troubleshooting heading. Drop the backticks from the title, matching the sibling fence above. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Peter Amiri <peter@alurium.com> --------- Signed-off-by: Peter Amiri <peter@alurium.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent b7e49f7 commit 3a0f90a

6 files changed

Lines changed: 49 additions & 42 deletions

File tree

CLAUDE.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ User-facing `fix`/`feat` PRs add a **fragment file**, never a direct `CHANGELOG.
716716

717717
There is no `wheels mcp setup` command — copy the JSON above into `.mcp.json` manually (see the MCP integration guide for OpenCode/Cursor variants).
718718

719-
Tools are auto-discovered from `cli/lucli/Module.cfc` public functions, prefixed with the module name (`wheels_generate`, `wheels_migrate`, `wheels_test`, `wheels_reload`, `wheels_seed`, `wheels_analyze`, `wheels_validate`, `wheels_routes`, `wheels_info`, `wheels_destroy`, `wheels_doctor`, `wheels_stats`, `wheels_notes`, `wheels_db`, `wheels_upgrade`, `wheels_create`, `wheels_deploy`, `wheels_packages`). CLI-only tools (`main`, `mcp`, `d`, `g`, `new`, `console`, `start`, `stop`, `browser`) are hidden via `mcpHiddenTools()`.
719+
Tools are auto-discovered from `cli/lucli/Module.cfc` public functions. Names in `tools/list` are the bare function names — NOT `wheels_*`-prefixed (live-verified on the released 4.0.3 CLI): `analyze`, `create`, `db`, `deploy`, `destroy`, `doctor`, `generate`, `info`, `migrate`, `notes`, `packages`, `reload`, `routes`, `seed`, `stats`, `test`, `upgrade`, `validate` (18 tools; the `wheels` server entry in `.mcp.json` namespaces them per client). CLI-only tools (`main`, `mcp`, `d`, `g`, `new`, `console`, `start`, `stop`, `browser`) are hidden via `mcpHiddenTools()`.
720720

721721
**Deprecated:** the in-dev-server HTTP endpoint at `/wheels/mcp`. Emits a deprecation notice on first request. Migrate to the stdio surface.
722722

@@ -728,13 +728,13 @@ Prefer MCP tools when the Wheels MCP server is available. Fall back to CLI other
728728

729729
| Task | MCP | CLI |
730730
|------|-----|-----|
731-
| Generate | `wheels_generate(type, name, attributes)` | `wheels g model/controller/scaffold Name attrs` |
732-
| Migrate | `wheels_migrate(action="latest\|up\|down\|info\|doctor")` | `wheels migrate latest\|up\|down\|info\|doctor` |
731+
| Generate | `generate(type, name, attributes)` | `wheels g model/controller/scaffold Name attrs` |
732+
| Migrate | `migrate(action="latest\|up\|down\|info\|doctor")` | `wheels migrate latest\|up\|down\|info\|doctor` |
733733
| Migrator reconciliation || `wheels migrate forget\|pretend <version> --yes` (shared dev DB orphan cleanup; see #2780) |
734-
| Test | `wheels_test()` | `wheels test` |
735-
| Reload | `wheels_reload()` | `?reload=true&password=...` |
734+
| Test | `test()` | `wheels test` |
735+
| Reload | `reload()` | `?reload=true&password=...` |
736736
| Server || `wheels start\|stop` |
737-
| Analyze | `wheels_analyze(target="all")` ||
737+
| Analyze | `analyze(target="all")` ||
738738
| Admin || `wheels g admin ModelName` |
739739
| Seed || `wheels seed` |
740740

cli/lucli/Module.cfc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,8 @@ component extends="modules.BaseModule" {
13841384
out(" https://guides.wheels.dev/v4-0-0/command-line-tools/mcp-integration");
13851385
out("");
13861386
out("All public commands in this module are auto-discovered as MCP tools.");
1387-
out("Tools are prefixed with the module name: wheels_generate, wheels_migrate, etc.");
1387+
out("Tool names match the command names: generate, migrate, etc. (unprefixed");
1388+
out("in tools/list — the server entry in .mcp.json namespaces them per client).");
13881389
out("Stateful/interactive commands (start, stop, new, console, ...) are hidden");
13891390
out("from MCP tools/list via mcpHiddenTools() — they remain CLI-only.");
13901391
return "";

web/sites/guides/src/content/docs/v4-0-0/command-line-tools/installation.mdx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ The package-manager installs do extra work on your behalf that this path skips.
191191
- **`LUCLI_HOME` isolation.** Package installs export `LUCLI_HOME=$HOME/.wheels` so installed modules live in `~/.wheels/modules/wheels/` and stay out of the way of any other LuCLI work. Standalone LuCLI uses `~/.lucli/modules/wheels/` — fine on its own, but a previously installed `wheels` module (e.g. v3.1.0 from the older registry entry) will shadow your new install unless you pass `--force`.
192192
- **JDK resolution.** Package installs probe for a Java 21 install and export `JAVA_HOME` inside their `wheels` wrapper. Standalone LuCLI uses whatever `java` is on your `PATH` — if that's a different major version, the runtime will refuse to start. Make sure `java -version` reports 21.x before installing.
193193
- **First-run SQLite shim.** The package wrappers auto-stage `sqlite-jdbc-*.jar` into Lucee Express's `lib/ext/` so `wheels start` against a SQLite datasource works out of the box. With a bare LuCLI install you'll need to drop the JAR there yourself the first time you create a SQLite-backed app.
194-
- **Channel awareness.** `wheels --version` from a packaged install reports `(stable)` or `(bleeding-edge)`. From a bare LuCLI install, the module reports its own version but there's no channel marker — you have to remember which tarball URL you installed from.
194+
- **Channel awareness.** `wheels version` from a packaged install reports `(stable)` or `(bleeding-edge)`. From a bare LuCLI install, the module reports its own version but there's no channel marker — you have to remember which tarball URL you installed from.
195195
- **No `scoop update` / `brew upgrade` story.** Upgrades are manual: re-run `lucli modules install wheels --force --url=…` with a newer release URL.
196196

197197
This path exists for people who already run LuCLI for other modules and don't want a second binary on `PATH`. For everyone else, the Scoop / Homebrew / Linux package paths are the better default.
@@ -208,12 +208,17 @@ wheels --version
208208
You should see something like:
209209

210210
``` title="illustrative — example version output"
211-
Wheels 4.0.0-SNAPSHOT+1523 (snapshot)
212-
LuCLI 0.3.7
213-
Java 21.0.8
211+
Wheels Version: 4.0.3
214212
```
215213

216-
The three-line format tells you the Wheels Module version, the underlying LuCLI version, and the JVM the wrapper picked up. If any of those lines is missing or reports an unexpected value, jump to troubleshooting below.
214+
followed by the Wheels ASCII-art banner. The richer check is `wheels version` (no dashes), which reports the release channel and the JVM the wrapper picked up:
215+
216+
``` title="illustrative — example wheels version output"
217+
Wheels 4.0.3 (stable)
218+
Java 21.0.11
219+
```
220+
221+
If either line is missing or reports an unexpected value — say a Java major version other than 21 — jump to troubleshooting below.
217222

218223
Running `wheels` with no arguments is also a quick sanity check — it prints the same Wheels help banner as `wheels --help`. (`wheels help` falls through to LuCLI's own generic help rather than the Wheels banner, so prefer `wheels --help`.) If you see a `Component [modules.wheels.Module] has no function with name [main]` error instead, you are running a build that predates this fix — upgrade to the latest 4.0.x release to restore the expected behavior.
219224

@@ -233,7 +238,7 @@ On Linux, the `.deb`/`.rpm` package installs `/usr/bin/wheels`, which should be
233238

234239
### Conflict with a standalone LuCLI install sharing `~/.lucli/`
235240

236-
The wheels formula deliberately isolates runtime state under `~/.wheels/` (via `LUCLI_HOME`) so a standalone `lucli` install — which uses `~/.lucli/` — stays out of the way. If you previously had LuCLI installed directly and see odd module-resolution errors, check that the wrapper set `LUCLI_HOME` correctly (`wheels system env` will dump the resolved environment) and that `~/.wheels/modules/wheels/` contains a current `Module.cfc` and `.module-version` file.
241+
The wheels formula deliberately isolates runtime state under `~/.wheels/` (via `LUCLI_HOME`) so a standalone `lucli` install — which uses `~/.lucli/` — stays out of the way. If you previously had LuCLI installed directly and see odd module-resolution errors, check that the wrapper set `LUCLI_HOME` correctly (`wheels system paths` prints the resolved home directory and where it came from) and that `~/.wheels/modules/wheels/` contains a current `Module.cfc` and `.module-version` file.
237242

238243
### Windows: `there is no Resource provider available with the name [c]`
239244

web/sites/guides/src/content/docs/v4-0-0/command-line-tools/mcp-integration.mdx

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The `wheels` binary can run as a Model Context Protocol (MCP) server over stdio,
1818

1919
## How it works
2020

21-
LuCLI ships a generic `mcp` subcommand that wraps any installed module's public functions as MCP tools over stdio JSON-RPC. Running `wheels mcp wheels` starts that server bound to the Wheels Module — every public function in `cli/lucli/Module.cfc` becomes a tool named `wheels_<function>` (for example, `wheels_generate`, `wheels_migrate`). The AI IDE spawns `wheels` as a subprocess, speaks newline-delimited JSON-RPC over stdin/stdout, and receives tool results the same way. No network listener is involved.
21+
LuCLI ships a generic `mcp` subcommand that wraps any installed module's public functions as MCP tools over stdio JSON-RPC. Running `wheels mcp wheels` starts that server bound to the Wheels Module — every public function in `cli/lucli/Module.cfc` becomes a tool named after the function itself (for example, `generate`, `migrate`). Tool names appear unprefixed in `tools/list`; the `wheels` server entry in your MCP config is what namespaces them per client. The AI IDE spawns `wheels` as a subprocess, speaks newline-delimited JSON-RPC over stdin/stdout, and receives tool results the same way. No network listener is involved.
2222

2323
## Setup
2424

@@ -37,7 +37,7 @@ Add an `.mcp.json` file to your project root (or wherever your IDE expects it).
3737

3838
That's the whole configuration. The first `wheels` is the binary name; the second is the module name to expose. The IDE launches the subprocess on demand — you don't need to keep `wheels mcp wheels` running yourself, and the server exits when the IDE disconnects.
3939

40-
Running `wheels mcp` on its own (no module name) prints the same snippet and a short pointer to configuration docs. It is a help command, not a setup wizard — there is no generated file today.
40+
Don't try `wheels mcp` on its own to see this snippet: on the released launcher, LuCLI reserves the `mcp` verb and a bare invocation exits with `mcp: missing module name` instead of reaching the Wheels Module's help text. To check the server from a shell, use the `--once` smoke test below. There is no setup wizard and no generated file — add the `.mcp.json` snippet manually.
4141

4242
<Aside type="note" title="IDE-specific paths">
4343
Claude Code reads `.mcp.json` from the project root. OpenCode uses `.opencode.json` with the same `mcpServers` shape. Cursor reads from its settings UI. Check your IDE's MCP documentation for the exact location; the server definition itself is identical across clients.
@@ -55,28 +55,28 @@ That runs a single MCP method and exits — useful for smoke-testing without ope
5555

5656
## Tools exposed
5757

58-
Every public function in the Wheels Module is auto-discovered as an MCP tool, prefixed with the module name:
58+
Every public function in the Wheels Module is auto-discovered as an MCP tool. Names in `tools/list` are the bare function names — 18 tools on a 4.0.3 install:
5959

6060
| Tool | Purpose |
6161
|---|---|
62-
| `wheels_generate` | Scaffold a model, controller, view, migration, scaffold, route, test, property, or helper. |
63-
| `wheels_destroy` | Remove a previously generated component. The default `resource` type cascades (model + controller + views + tests + route + drop-table migration); `model`, `controller`, and `view` are scoped to that artefact only. |
64-
| `wheels_migrate` | Run, roll back, or inspect database migrations. |
65-
| `wheels_seed` | Run convention-based seeds against the configured environment. |
66-
| `wheels_db` | Database utility operations (schema, reset, status). |
67-
| `wheels_test` | Run the app or core test suite and return results. |
68-
| `wheels_reload` | Reload the app via the running dev server. |
69-
| `wheels_routes` | List registered routes. |
70-
| `wheels_info` | Print project, framework, and environment info. |
71-
| `wheels_analyze` | Run the codebase analyzer (conventions, anti-patterns, drift). |
72-
| `wheels_validate` | Run configuration and schema validation checks. |
73-
| `wheels_doctor` | Diagnose install, project, and runtime issues. |
74-
| `wheels_stats` | Count models, controllers, routes, tests, migrations. |
75-
| `wheels_notes` | Surface `TODO`, `FIXME`, `HACK`, `OPTIMIZE` annotations from the codebase. |
76-
| `wheels_create` | Create an application (currently only `wheels create app <name>`; forwards to `wheels new`). |
77-
| `wheels_upgrade` | Scan the project for breaking changes against a target framework version (read-only). |
78-
| `wheels_deploy` | Kamal-style production deploys (full deploy, rollback, config, setup, bootstrap, exec). |
79-
| `wheels_packages` | Search, show, add, update, and remove Wheels packages; manage the registry cache. |
62+
| `generate` | Scaffold a model, controller, view, migration, scaffold, route, test, property, or helper. |
63+
| `destroy` | Remove a previously generated component. The default `resource` type cascades (model + controller + views + tests + route + drop-table migration); `model`, `controller`, and `view` are scoped to that artefact only. |
64+
| `migrate` | Run, roll back, or inspect database migrations. |
65+
| `seed` | Run convention-based seeds against the configured environment. |
66+
| `db` | Database utility operations (schema, reset, status). |
67+
| `test` | Run the app or core test suite and return results. |
68+
| `reload` | Reload the app via the running dev server. |
69+
| `routes` | List registered routes. |
70+
| `info` | Print project, framework, and environment info. |
71+
| `analyze` | Run the codebase analyzer (conventions, anti-patterns, drift). |
72+
| `validate` | Run configuration and schema validation checks. |
73+
| `doctor` | Diagnose install, project, and runtime issues. |
74+
| `stats` | Count models, controllers, routes, tests, migrations. |
75+
| `notes` | Surface `TODO`, `FIXME`, `HACK`, `OPTIMIZE` annotations from the codebase. |
76+
| `create` | Create an application (currently only `wheels create app <name>`; forwards to `wheels new`). |
77+
| `upgrade` | Scan the project for breaking changes against a target framework version (read-only). |
78+
| `deploy` | Kamal-style production deploys (full deploy, rollback, config, setup, bootstrap, exec). |
79+
| `packages` | Search, show, add, update, and remove Wheels packages; manage the registry cache. |
8080

8181
### Tools deliberately hidden
8282

@@ -87,7 +87,7 @@ A handful of public CLI commands are excluded from MCP discovery via `mcpHiddenT
8787
- `new` — scaffolds an entire new project. Destructive and requires interactive prompts for project context.
8888
- `browser` — multi-step browser testing flow with its own subcommand tree.
8989
- `mcp` — the meta command itself; exposing it would let an agent recursively launch MCP servers.
90-
- `d` — short alias for `destroy`, excluded to avoid a duplicate tool entry (the canonical `wheels_destroy` is exposed).
90+
- `d` — short alias for `destroy`, excluded to avoid a duplicate tool entry (the canonical `destroy` is exposed).
9191
- `g` — short alias for `generate`, excluded for the same duplicate-entry reason as `d`.
9292
- `main` — the bare `wheels` no-args dispatch target; it is not a subcommand.
9393
- Any function whose name begins with `$` — internal helpers kept `public` only so unit tests can reach them (a CFML testing carve-out). `mcpHiddenTools()` discovers these structurally via `getMetaData(this)`, so a future `$helper` added to the module cannot accidentally surface as a callable MCP tool without a manual denylist update.

web/sites/guides/src/content/docs/v4-0-0/command-line-tools/quick-start.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ With the server still running in the background:
7373
wheels test posts
7474
```
7575

76-
The trailing positional scopes the test run to specs whose path matches the filter string. The scaffold generated a `PostsSpec.cfc` under `tests/specs/`, so the filter narrows the run to just that file's specs. Omit it to run everything. A run with failing or erroring specs exits non-zero; a fully-passing run exits `0`.
76+
The trailing positional is a directory scope, not a filename match — `posts` expands to `tests.specs.posts`. The scaffold generated `PostSpec.cfc` under `tests/specs/models/` and `PostsControllerSpec.cfc` under `tests/specs/controllers/`, so on a fresh scaffold the `posts` scope matches neither directory and the run reports `0 passed`. Use `wheels test models` or `wheels test controllers` to scope to the generated specs — though note that plain `wheels test` also reports `0 passed` here, because the generated specs are empty `describe` stubs until you write expectations into them. A run with failing or erroring specs exits non-zero; a run with no failures exits `0`.
7777

7878
## 7. What's next
7979

web/sites/guides/src/content/docs/v4-0-0/command-line-tools/wheels-commands/testing.mdx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ A bare positional argument is treated as the filter directory — `wheels test m
5858
| `--directory=<dir>` | Alias for `--filter` (tutorial chapter 7). When both are supplied, `--directory` wins. |
5959
| `--db=<engine>` | Database engine for `--core` matrix runs only. Ignored for app tests (with a warning) — see [below](#testing-against-different-engines). |
6060
| `--reporter=<name>` | `simple` (default, colourful), `json` (raw runner JSON), `tap` (TAP v13 for CI consumers). |
61-
| `--verbose`, `-v` | Print per-spec output instead of the summary line. |
62-
| `--ci` | CI mode: tightens exit codes and output for GitHub Actions and similar runners. |
61+
| `--verbose`, `-v` | Accepted but currently inert — output is identical to a plain run; no per-spec output is printed for passing specs. Wiring tracked in [#3113](https://github.com/wheels-dev/wheels/issues/3113). |
62+
| `--ci` | Accepted but currently inert — output is byte-identical to a plain run, and exit codes are already non-zero on failure without it. Intended to tighten output for GitHub Actions and similar runners; tracked in [#3113](https://github.com/wheels-dev/wheels/issues/3113). |
6363
| `--core` | Run framework self-tests (`vendor/wheels/tests/specs/`) instead of your app suite. App tests are the default; `--core` is the explicit opt-in. |
6464
| `--no-test-db` | Disable the auto-swap to `<datasource>_test`. App tests run against your dev datasource, with whatever data is already in it. |
6565
| `--base-path=<path>` | URL prefix the app is mounted under (e.g. `/myapp`). Auto-derived from `WHEELS_SUBPATH` or `set(subpath=...)` in `config/settings.cfm` when omitted. Leave unset for root-mounted apps (the default). |
@@ -87,10 +87,10 @@ The engine identifiers are `postgres` (not `postgresql`) and `sqlserver` (not `m
8787
#### Example
8888

8989
```bash title="example"
90-
wheels test --filter=models --verbose
90+
wheels test --filter=models
9191
```
9292

93-
Runs every spec under `tests/specs/models/` with per-spec output. Exit code is non-zero if any spec fails or errors.
93+
Runs every spec under `tests/specs/models/`. Exit code is non-zero if any spec fails or errors.
9494

9595
#### Testing against different engines
9696

@@ -155,8 +155,9 @@ wheels test
155155
# Narrow to one area while iterating
156156
wheels test --filter=models
157157

158-
# CI-shaped run — tight output, firm exit codes
159-
wheels test --ci --db=sqlite
158+
# CI run — exit codes are already firm without extra flags; for machine-readable
159+
# output use a reporter (--ci itself is inert today, #3113)
160+
wheels test --reporter=tap
160161

161162
# First-time browser setup, then exercise the browser specs
162163
wheels browser setup

0 commit comments

Comments
 (0)