Skip to content

fix(cli): implement routes --filter and --format - #3613

Merged
bpamiri merged 2 commits into
developfrom
feat/routes-filter-format
Sep 14, 2026
Merged

bpamiri merged 2 commits into
developfrom
feat/routes-filter-format

Conversation

@bpamiri

@bpamiri bpamiri commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Both flags were advertised in the command's help for as long as it has existed:

Usage: wheels routes [--filter=<pattern>] [--format=<text|json>]

and neither was ever read. routes() took no arguments — it fetched every route and printed the table unconditionally. Found rehearsing wheels routes --filter=posts as a before/after for the scaffold beat: it returned all 57 routes, which on stage reads as a bug in front of the audience.

What works now

routes() parses an ArgSpec — the same builder now registered in mcpToolSpecs(), so the CLI surface and the MCP advertisement can't drift. This is the migration the mcpToolSpecs comment listed routes as still needing; an assistant can now call routes(filter="posts").

--filter — case-insensitive substring over name, pattern and controller#action (the three fields the help names). Substring, not regex: [key] in a pattern must match literally, and a presenter shouldn't have to think about escaping. No match prints No routes match 'x'. rather than the misleading No routes configured.

--format=json — the filtered array and nothing else on stdout, with lower-case quoted keys. A CFML struct serializes keys UPPER-CASE, so jq .pattern on the raw shape silently yields null.

The demo moment it enables

routes
fresh app 41 — all /wheels/… tooling, plus /up, wildcards, /
after scaffold Post 57
--filter=posts exactly the 16 that changed

Sixteen routes from one .resources("posts") line. The runbook card now frames both ends.

Tests

7 specs on the pure $filterRoutes() (case, name/pattern/controller matching, literal brackets, empty, no mutation), 2 on the ArgSpec defaults, 1 asserting the MCP schema advertises both params.

CLI suite: 1377 pass, 0 fail, 0 error.

Worth noting: the four DbCommandSpec failures carried as "pre-existing baseline" all day were an artefact of a server always occupying 8080 during my runs — they expect Wheels.ServerNotRunning. Run on a clean port, they pass. The baseline was never actually red.

Both flags were advertised in the wrapper's help text for as long as the
command has existed:

  Usage: wheels routes [--filter=<pattern>] [--format=<text|json>]

and neither was ever read. routes() took no arguments at all — it fetched
every route and printed the table unconditionally. Found rehearsing
`wheels routes --filter=posts` as a before/after for the scaffold beat:
it returned all 57 routes, which on stage reads as a bug.

routes() now parses an ArgSpec (the same builder registered in
mcpToolSpecs, so the CLI surface and the MCP advertisement cannot drift
— this is the migration the mcpToolSpecs comment listed routes as still
needing).

--filter: case-insensitive substring over name, pattern and
controller#action — the three fields the help names. Substring, not
regex: `[key]` in a pattern must match literally, and a presenter should
not have to think about escaping. A no-match prints "No routes match
'<text>'." instead of the misleading "No routes configured."

--format=json: emits the filtered array and nothing else on stdout, with
lower-case quoted keys. A CFML struct serializes its keys UPPER-CASE, so
`jq .pattern` on the raw shape silently yields null.

On a fresh app scaffolded with Post: 41 routes before, 57 after,
`--filter=posts` shows exactly the 16 that changed.

CLI suite: 1377 pass, 0 fail, 0 error. The four DbCommandSpec failures
carried as "pre-existing" all day were an artefact of a server always
occupying 8080 during my runs — they expect Wheels.ServerNotRunning. On a
clean port they pass.

Signed-off-by: Peter Amiri <peter@alurium.com>
The presenter added a routes call before the Post scaffold to show the
delta. The card now frames both ends: 41 framework routes before (name
them, or the audience reads noise), and --filter=posts after so exactly
the 16 new routes are on the projector rather than 57 lines to hunt
through. Points at the one .resources("posts") line that produced them.

Signed-off-by: Peter Amiri <peter@alurium.com>
@github-actions github-actions Bot added the docs label Sep 13, 2026
@bpamiri
bpamiri merged commit e4002bd into develop Sep 14, 2026
13 checks passed
@bpamiri
bpamiri deleted the feat/routes-filter-format branch September 14, 2026 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant