CLI Consistency Report
Date: 2026-04-24
APM Version: 0.9.2 (c74444c)
Commands Inspected: 48 (22 top-level + 26 subcommands across config, deps, mcp, marketplace, runtime, policy, experimental)
Summary
| Severity |
Count |
| High |
1 |
| Medium |
4 |
| Low |
2 |
High Severity
apm experimental subcommand --help is broken for all subcommands
- Commands:
apm experimental list --help, apm experimental enable --help, apm experimental disable --help, apm experimental reset --help
- Problem: All four subcommands display the parent group help instead of their own specific help text. Users cannot discover subcommand-specific options via
--help. Hidden options include --enabled, --disabled, --json for list; the required NAME argument for enable and disable; and --yes for reset.
- Evidence:
$ apm experimental list --help
Usage: apm experimental [OPTIONS] COMMAND [ARGS]...
Manage experimental feature flags
Options:
-v, --verbose Show verbose output
--help Show this message and exit.
Commands:
disable Disable an experimental feature
enable Enable an experimental feature
list List all experimental features
reset Reset experimental features to defaults
```
Expected: subcommand-specific help showing `--enabled`, `--disabled`, `--json`, `-v` options.
- Root Cause:
context_settings={"allow_interspersed_args": True, "ignore_unknown_options": True} in src/apm_cli/commands/experimental.py:143 causes --help to be intercepted and processed at the group level before routing to the subcommand.
- Suggested Fix: Remove the
context_settings dict from the @click.group(...) decorator on experimental in src/apm_cli/commands/experimental.py. These settings are not needed on the group itself; they were likely intended to allow the apm experimental group to forward unknown tokens to subcommands, but they have the side effect of eating --help.
Medium Severity
apm mcp install --help shows no options or usage synopsis
- Command:
apm mcp install --help
- Problem: The help output shows only a one-line description and hardcoded examples, but no
Usage: line, no argument documentation, and no list of accepted options. Users cannot determine what arguments or flags the command accepts from --help alone.
- Evidence:
$ apm mcp install --help
Usage: apm mcp install [OPTIONS]
Add an MCP server to apm.yml. Alias for 'apm install --mcp'.
Examples:
apm mcp install fetch -- npx -y `@modelcontextprotocol/server-filesystem`
apm mcp install api --transport http --url (example.com/redacted)
Options:
--help Show this message and exit.
The Usage line says [OPTIONS] only, hiding the NAME argument and --transport, --url, --env, --header, --mcp-version, --registry flags that are available via apm install --mcp.
- Suggested Fix: Expose the same options as
apm install --mcp on apm mcp install, or at minimum add a NAME argument and a --help note pointing to apm install --mcp --help for full option documentation.
apm run output uses a bare leading space instead of a status symbol
- Command:
apm run
- Problem: When a script is run, the first output line is
" Running script: (name)" (leading space only). The project's ASCII status symbol convention specifies [>] for running/progress output. This is the only user-visible progress output in run that lacks a bracket symbol.
- Evidence (
hexdump -C confirms byte 0x20 space, not a status symbol):
$ apm run nonexistent-script 2>&1 | hexdump -C | head -1
00000000 20 52 75 6e 6e 69 6e 67 20 73 63 72 69 70 74 3a | Running script:|
Source: src/apm_cli/output/script_formatters.py:43-45
lines.append(self._styled(f" Running script: {script_name}", "cyan bold"))
# fallback:
lines.append(f" Running script: {script_name}")
```
- Suggested Fix: Change to
f"[>] Running script: {script_name}" to match the STATUS_SYMBOLS convention ([>] = running/progress), consistent with how other commands indicate ongoing operations.
--dry-run flag description has trailing periods in pack and unpack but not elsewhere
- Commands:
apm pack --help, apm unpack --help
- Problem: The
--dry-run flag descriptions in pack and unpack end with a period, while all other commands with --dry-run do not use trailing punctuation.
- Evidence:
# apm pack:
--dry-run Show what would be packed without writing. <-- trailing period
# apm unpack:
--dry-run Show what would be unpacked without writing. <-- trailing period
# All other commands (no trailing period):
# apm install: "Show what would be installed without installing"
# apm uninstall: "Show what would be removed without removing"
# apm prune: "Show what would be removed without removing"
# apm compile: "Preview compilation without writing files"
Source: src/apm_cli/commands/pack.py:37 and :110.
- Suggested Fix: Remove trailing period from both
--dry-run help strings in pack.py.
apm runtime remove --yes is missing the short -y flag
- Command:
apm runtime remove --help
- Problem:
runtime remove uses --yes without the -y short alias. Every other command that has --yes also provides -y: deps clean uses -y, --yes and marketplace remove uses -y, --yes. The inconsistency means muscle memory for -y does not work with runtime remove.
- Evidence:
# apm runtime remove:
--yes Confirm the action without prompting <-- no -y alias
# apm deps clean:
-y, --yes Skip confirmation prompt <-- has -y
# apm marketplace remove:
-y, --yes Skip confirmation <-- has -y
- Suggested Fix: Add
-y as a short flag alias to --yes in apm runtime remove.
Low Severity
outdated command description has a trailing period in the top-level help
- Command:
apm --help listing
- Problem:
outdated is the only top-level command whose one-line description ends with a period.
- Evidence:
$ apm --help (excerpt)
mcp Discover, inspect, and install MCP servers
outdated Show outdated locked dependencies. <-- trailing period
pack Create a self-contained bundle from installed dependencies
Source: src/apm_cli/commands/outdated.py:228 (the docstring for the command).
- Suggested Fix: Remove the trailing period from the
outdated command description.
apm experimental is absent from the main CLI reference page
- File:
docs/src/content/docs/reference/cli-commands.md
- Problem:
apm experimental appears as a full top-level command in the CLI (apm --help) but has no dedicated section in cli-commands.md. It is only referenced in a one-line aside at the bottom of the page and its documentation lives in a separate experimental.md page. Every other top-level command (including apm runtime, which is also experimental) has a full section with usage, options, and examples in cli-commands.md.
- Evidence:
grep -n "^### \apm experimental" docs/src/content/docs/reference/cli-commands.mdreturns no matches. The only mention is line 1719: ``apm experimental` manages opt-in flags that gate new or changing behaviour. ... See the full reference in Experimental Flags. ``
- Suggested Fix: Add a
### apm experimental section to cli-commands.md that mirrors the structure of other commands: usage synopsis, subcommand table, and a cross-reference link to the full experimental.md page for the complete flag registry.
Clean Areas
- All 22 top-level commands respond to
--help and exit cleanly.
- Error handling on invalid inputs is consistent and clean: invalid flags produce
Error: No such option, missing required args produce Error: Missing argument, no stack traces observed.
--verbose / -v short flag is consistent across all commands that support it.
--dry-run naming is consistent (never --dryrun).
--global / -g short flag is consistent across install, uninstall, deps list, deps tree, deps update, view, outdated.
--force naming is consistent across install, deps update, pack, unpack.
- All documented commands in
cli-commands.md exist in the actual CLI (no phantom commands found).
- No stack traces or Python tracebacks observed on any tested invalid input.
- All ASCII status symbols in error output (
[x], [i]) conform to the project's encoding convention.
apm config (no subcommand) shows a well-formatted table as documented.
apm deps, apm mcp, apm marketplace, apm runtime, apm policy all route subcommands correctly and display proper help.
Generated by CLI Consistency Checker · ◷
CLI Consistency Report
Date: 2026-04-24
APM Version: 0.9.2 (c74444c)
Commands Inspected: 48 (22 top-level + 26 subcommands across
config,deps,mcp,marketplace,runtime,policy,experimental)Summary
High Severity
apm experimentalsubcommand--helpis broken for all subcommandsapm experimental list --help,apm experimental enable --help,apm experimental disable --help,apm experimental reset --help--help. Hidden options include--enabled,--disabled,--jsonforlist; the requiredNAMEargument forenableanddisable; and--yesforreset.context_settings={"allow_interspersed_args": True, "ignore_unknown_options": True}insrc/apm_cli/commands/experimental.py:143causes--helpto be intercepted and processed at the group level before routing to the subcommand.context_settingsdict from the@click.group(...)decorator onexperimentalinsrc/apm_cli/commands/experimental.py. These settings are not needed on the group itself; they were likely intended to allow theapm experimentalgroup to forward unknown tokens to subcommands, but they have the side effect of eating--help.Medium Severity
apm mcp install --helpshows no options or usage synopsisapm mcp install --helpUsage:line, no argument documentation, and no list of accepted options. Users cannot determine what arguments or flags the command accepts from--helpalone.Usageline says[OPTIONS]only, hiding theNAMEargument and--transport,--url,--env,--header,--mcp-version,--registryflags that are available viaapm install --mcp.apm install --mcponapm mcp install, or at minimum add aNAMEargument and a--helpnote pointing toapm install --mcp --helpfor full option documentation.apm runoutput uses a bare leading space instead of a status symbolapm run" Running script: (name)"(leading space only). The project's ASCII status symbol convention specifies[>]for running/progress output. This is the only user-visible progress output inrunthat lacks a bracket symbol.hexdump -Cconfirms byte0x20space, not a status symbol):src/apm_cli/output/script_formatters.py:43-45f"[>] Running script: {script_name}"to match the STATUS_SYMBOLS convention ([>]= running/progress), consistent with how other commands indicate ongoing operations.--dry-runflag description has trailing periods inpackandunpackbut not elsewhereapm pack --help,apm unpack --help--dry-runflag descriptions inpackandunpackend with a period, while all other commands with--dry-rundo not use trailing punctuation.src/apm_cli/commands/pack.py:37and:110.--dry-runhelp strings inpack.py.apm runtime remove --yesis missing the short-yflagapm runtime remove --helpruntime removeuses--yeswithout the-yshort alias. Every other command that has--yesalso provides-y:deps cleanuses-y, --yesandmarketplace removeuses-y, --yes. The inconsistency means muscle memory for-ydoes not work withruntime remove.-yas a short flag alias to--yesinapm runtime remove.Low Severity
outdatedcommand description has a trailing period in the top-level helpapm --helplistingoutdatedis the only top-level command whose one-line description ends with a period.src/apm_cli/commands/outdated.py:228(the docstring for the command).outdatedcommand description.apm experimentalis absent from the main CLI reference pagedocs/src/content/docs/reference/cli-commands.mdapm experimentalappears as a full top-level command in the CLI (apm --help) but has no dedicated section incli-commands.md. It is only referenced in a one-line aside at the bottom of the page and its documentation lives in a separateexperimental.mdpage. Every other top-level command (includingapm runtime, which is also experimental) has a full section with usage, options, and examples incli-commands.md.grep -n "^### \apm experimental" docs/src/content/docs/reference/cli-commands.mdreturns no matches. The only mention is line 1719: ``apm experimental` manages opt-in flags that gate new or changing behaviour. ... See the full reference in Experimental Flags. ``### apm experimentalsection tocli-commands.mdthat mirrors the structure of other commands: usage synopsis, subcommand table, and a cross-reference link to the fullexperimental.mdpage for the complete flag registry.Clean Areas
--helpand exit cleanly.Error: No such option, missing required args produceError: Missing argument, no stack traces observed.--verbose/-vshort flag is consistent across all commands that support it.--dry-runnaming is consistent (never--dryrun).--global/-gshort flag is consistent acrossinstall,uninstall,deps list,deps tree,deps update,view,outdated.--forcenaming is consistent acrossinstall,deps update,pack,unpack.cli-commands.mdexist in the actual CLI (no phantom commands found).[x],[i]) conform to the project's encoding convention.apm config(no subcommand) shows a well-formatted table as documented.apm deps,apm mcp,apm marketplace,apm runtime,apm policyall route subcommands correctly and display proper help.