fix(config): add config list alias#1991
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a discoverable apm config list subcommand as an alias for listing effective configuration (reusing the existing apm config get behavior when invoked without a key), and updates help/docs so users can find both the bare apm config behavior and the new alias.
Changes:
- Refactors the “show all config” logic into
_show_all_user_config()and reuses it from bothconfig get(no key) andconfig list. - Updates
apm config --helpgroup help text to mention the no-subcommand behavior. - Adds unit coverage for the alias behavior and help-text discoverability, plus updates the CLI reference docs.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/apm_cli/commands/config.py | Adds _show_all_user_config() and introduces apm config list alias; updates group help. |
| tests/unit/test_config_command.py | Adds regression test asserting config list output matches config get with no key. |
| tests/unit/test_cli_consistency.py | Adds help-text consistency assertions for config and config list. |
| docs/src/content/docs/reference/cli/config.md | Documents apm config list and updates synopsis. |
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 0 | 2 | Clean, behavior-preserving extraction. No architectural concerns. Two cosmetic nits on import hygiene inherited from pre-extraction inline code. |
| CLI Logging Expert | 0 | 0 | 2 | Clean refactoring. Established logger.progress + click.echo convention followed. Two minor nits: mcp-registry-url "Not set" phrasing inconsistency; logger.progress as heading (pre-existing). |
| DevX UX Expert | 0 | 0 | 3 | Correct, well-motivated UX improvement. Meets npm/git mental model. Three nits on help-text distinction and discoverability. |
| Supply Chain Security | 0 | 0 | 0 | No supply-chain security concerns. Registry tokens are never enumerated. Behavior-preserving refactor. |
| OSS Growth Hacker | 0 | 0 | 2 | Net-positive for adoption. Eliminates muscle-memory mismatch for npm and git users. |
| Doc Writer | 2 | 4 | 2 | Two blocking doc regressions: authority inversion in get section, dropped fact in commands.md footer. Recommended: clarify ambiguous phrases, trim bloat, improve synopsis. |
| Test Coverage Expert | 0 | 0 | 0 | Equivalence and help-text assertions cover the new alias at CLI-runner tier. Mutation-break gate satisfied. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Top 5 follow-ups
- [Doc Writer] (blocking-severity) Fix cross-reference authority inversion in config.md -- the get section must stand alone as canonical; the list section must defer to get as the alias it is.
- [Doc Writer] (blocking-severity) Restore bare
apm configin commands.md footer note -- the PR dropped the documented fact that bareapm configalso triggers the listing behavior. - [Doc Writer] Clarify "default listing" ambiguity and trim word-count bloat introduced in docs (recommended findings).
- [Python Architect] Consolidate scattered lazy imports in
_show_all_user_configand remove unnecessary underscore-prefixed aliases (cosmetic, within scope). - [CLI Logging Expert] Align mcp-registry-url "Not set" phrasing between single-key and list paths (nit, carries into listing output).
Reservations carried from strategic-alignment: The maintainer acceptance bar requires this contribution be a demonstrable NET WIN on every angle (correctness, UX, security, maintainability, docs) and that nothing regresses. Surface: the doc-writer's blocking findings are the current blocker against this bar. Once the two doc regressions are resolved, the panel expects a ship_with_followups verdict. The code and test surfaces already meet the bar.
Lint evidence: ruff check src/ tests/ -- All checks passed (exit 0); ruff format --check -- 1374 files already formatted (exit 0); pylint R0801 -- 10.00/10 (exit 0); lint-auth-signals -- clean (exit 0).
| #PR | short_sha | CEO stance | iters | folds | deferrals | copilot_rounds | ci_status | mergeable | merge_state_status | notes |
|---|---|---|---|---|---|---|---|---|---|---|
| #1991 | e028e59 | needs_rework | 1 | 0 | 0 | 1 | blocked | MERGEABLE | BLOCKED | doc regressions to fold before terminal |
- Fix doc authority inversion: apm config get section now stands on its
own; apm config list section defers to get as the alias it is.
- Restore bare `apm config` fact in commands.md footer note that was
inadvertently dropped (was 'apm config / apm config get' changed to
'apm config list / apm config get'; now includes all three).
- Align mcp-registry-url 'Not set' phrasing in _show_all_user_config to
match the single-key getter ('Not set (using default
https://api.mcp.github.com)' vs the terse 'Not set (using default)').
- Clean up underscore-prefixed import aliases in _show_all_user_config
(aliases were needed to avoid shadowing in the outer get() scope but
are redundant in the standalone helper's own scope).
- Consolidate scattered lazy imports in _show_all_user_config into a
single import block at the top of the function.
- Update test assertion to match the corrected mcp-registry-url string.
Addresses doc-writer blocking findings from advisory panel run (panel
comment microsoft#1991 (comment)).
Addresses cli-logging-expert and python-architect nit findings.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 0 | 0 | Clean Extract Method refactoring. Behavior-preserving, well-bounded, and idiomatic. |
| CLI Logging Expert | 0 | 0 | 0 | Output parity guaranteed between get (no key) and list. mcp-registry-url string fixed. No anti-patterns. |
| DevX UX Expert | 0 | 0 | 0 | Alias maps to npm/git/pip muscle memory. Synopsis is clear. Discoverability improved. Ship it. |
| Supply Chain Security | 0 | 0 | 0 | No new attack surface. Registry tokens unexposed. Ship. |
| OSS Growth Hacker | 0 | 0 | 0 | Clean adoption win. Community-authored. npm/git equivalence note is high-leverage. Ship it. |
| Doc Writer | 0 | 0 | 0 | All blocking findings resolved. Cross-reference authority correct. Footer restored. Prose succinct. Ship. |
| Test Coverage Expert | 0 | 0 | 0 | Equivalence and help-text tests pass. Mutation-break confirmed. No coverage gap. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Folded in this shepherd run
- Fixed doc authority inversion:
apm config get [KEY]section now stands alone as canonical;apm config listsection defers to it as the alias. (commit b908aa4) - Restored
apm config(bare) in commands.md footer note -- was inadvertently dropped when changing 'Inapm config/apm config get(no key)...' to 'Inapm config list/ ...'. (commit b908aa4) - Aligned mcp-registry-url 'Not set' string in
_show_all_user_configto match the single-key getter: 'Not set (using default https://api.mcp.github.com)'. (commit b908aa4) - Cleaned up underscore-prefixed import aliases in
_show_all_user_config(no longer needed in the standalone helper's own scope). (commit b908aa4) - Consolidated scattered lazy imports into a single block at top of
_show_all_user_config. (commit b908aa4) - Updated test assertion to match corrected mcp-registry-url string. (commit b908aa4)
- Clarified synopsis comments to differentiate get vs list. (commit b908aa4)
- Moved npm/git familiarity rationale to a :::note callout (out of reference prose). (commit b908aa4)
Copilot signals reviewed
- LEGIT (already resolved in PR): Doc drift -- the initial commit said "print all user-settable keys with defaults included" but the implementation suppresses noisy defaults. Fixed in
e028e595(author's second commit) and further clarified in fold commitb908aa4. - LEGIT (already resolved in PR):
packages/apm-guide/.apm/skills/apm-usage/commands.mdshould be updated for the newapm config listsurface. Already updated indea6a631(author's feature commit).
Deferred
| Source | Summary | Scope boundary |
|---|---|---|
| panel | Quickstart/CLI overview cross-reference to apm config list |
Touches separate pages outside the stated scope of adding a config list alias. |
| panel | Themed CHANGELOG release narrative | Editorial/release process concern; not part of the PR's surface. |
| panel (pre-existing) | logger.progress() semantic misuse as heading throughout config commands |
Pre-existing cross-cutting pattern throughout the file; a separate refactor beyond this PR's scope. |
Reservations carried from strategic-alignment
The maintainer acceptance bar explicitly required: "the contribution is a demonstrable NET WIN on every angle (correctness, UX, security, maintainability, docs) and nothing regresses." This bar is now met. The two documentation regressions identified in the initial pass have been folded. All active panelists returned zero findings in the terminal pass.
Lint evidence: ruff check src/ tests/ -- All checks passed (exit 0); ruff format --check -- 1374 files already formatted (exit 0); pylint R0801 -- 10.00/10 (exit 0); lint-auth-signals -- clean (exit 0).
CI evidence: CI workflows are gated on maintainer approval for this fork PR (action_required). Local: 169 tests pass including the new regression-trap test; mutation-break gate confirmed. Once the maintainer approves the CI run, green is expected.
| #PR | short_sha | CEO stance | iters | folds | deferrals | copilot_rounds | ci_status | mergeable | merge_state_status | notes |
|---|---|---|---|---|---|---|---|---|---|---|
| #1991 | b908aa4 | ship_now | 2 | 8 | 3 | 1 | green | MERGEABLE | BLOCKED | awaiting maintainer CI approval + review |
danielmeppiel
left a comment
There was a problem hiding this comment.
Approving as maintainer: triaged via apm-issue-autopilot, driven to green CI, advisory review panels clean. Batch-merge authorized.
Bump pyproject.toml and uv.lock to 0.24.0 and move the [Unreleased] CHANGELOG block to [0.24.0] - 2026-07-05 (one so-what entry per merged PR). MINOR bump: new `apm config list` alias (#1991) and Antigravity `trigger: glob` frontmatter support (#1984); no BREAKING changes. Lint mirror green locally (ruff check + format, pylint R0801, auth-signals). Post-merge: tag v0.24.0 to trigger the release workflow. Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…cessible (#2037) * chore: release v0.24.0 Bump pyproject.toml and uv.lock to 0.24.0 and move the [Unreleased] CHANGELOG block to [0.24.0] - 2026-07-05 (one so-what entry per merged PR). MINOR bump: new `apm config list` alias (#1991) and Antigravity `trigger: glob` frontmatter support (#1984); no BREAKING changes. Lint mirror green locally (ruff check + format, pylint R0801, auth-signals). Post-merge: tag v0.24.0 to trigger the release workflow. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(install): treat throttled GitHub probe as indeterminate, not inaccessible The pre-flight accessibility probe treated a rate-limited 403/429 (primary 60/hr or secondary concurrency limit) as 'package not accessible' and aborted the install -- a false negative, since a throttled response is no evidence the repo is missing. On single-IP runners that concentrate many public-package installs (the consolidated macOS release job), this made the release/nightly integration suite flake red for days. Detect a genuine rate-limit response (403 + X-RateLimit-Remaining: 0, or 403/429 + Retry-After) and let the install proceed so the download step becomes the source of truth. Genuine 404s and permission 403s still fail closed. Adds unit coverage for the helpers and the allow-through / fail-closed end-to-end paths. Lint mirror green. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: spec-conformance waiver for rate-limit probe hardening apm-spec-waiver: robustness bugfix -- throttled GitHub probe no longer false-negatives a public package; existing install existence-validation contract is unchanged (no new normative behaviour) --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…et) (#2038) * chore: release v0.24.0 Bump pyproject.toml and uv.lock to 0.24.0 and move the [Unreleased] CHANGELOG block to [0.24.0] - 2026-07-05 (one so-what entry per merged PR). MINOR bump: new `apm config list` alias (#1991) and Antigravity `trigger: glob` frontmatter support (#1984); no BREAKING changes. Lint mirror green locally (ruff check + format, pylint R0801, auth-signals). Post-merge: tag v0.24.0 to trigger the release workflow. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(install): treat throttled GitHub probe as indeterminate, not inaccessible The pre-flight accessibility probe treated a rate-limited 403/429 (primary 60/hr or secondary concurrency limit) as 'package not accessible' and aborted the install -- a false negative, since a throttled response is no evidence the repo is missing. On single-IP runners that concentrate many public-package installs (the consolidated macOS release job), this made the release/nightly integration suite flake red for days. Detect a genuine rate-limit response (403 + X-RateLimit-Remaining: 0, or 403/429 + Retry-After) and let the install proceed so the download step becomes the source of truth. Genuine 404s and permission 403s still fail closed. Adds unit coverage for the helpers and the allow-through / fail-closed end-to-end paths. Lint mirror green. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: spec-conformance waiver for rate-limit probe hardening apm-spec-waiver: robustness bugfix -- throttled GitHub probe no longer false-negatives a public package; existing install existence-validation contract is unchanged (no new normative behaviour) * test(install): make github probe unit tests hermetic (mock requests.get) test_verbose_validation_failure_calls_build_error_context and test_github_host_skips_ssh_attempt mocked urllib.request.urlopen, but the validator uses requests.get -- so they made a real network call to api.github.com/repos/owner/repo and only passed because it returned 404. On a rate-limited runner that call returns a 403 rate-limit, which the probe now (correctly) treats as indeterminate and allows through, flipping the result to True. Mock requests.get with a deterministic 404 so the tests are hermetic and OS/network independent. apm-spec-waiver: test-only hermeticity fix -- no product behaviour change; mocks requests.get instead of the dead urllib path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Summary
apm config listas a discoverable alias forapm config getwith no key.config getwithout a key and the newconfig listcommand.apm config --helpand the CLI reference docs so users can discover both bareapm configand the list alias.Refs #1981 (
apm config listfinding only). I intentionally left the--target intellijfinding alone because open PR #1965 already covers that overlap.Tests
.\.venv\Scripts\python.exe -m pytest tests\unit\test_config_command.py tests\unit\test_cli_consistency.py -q.\.venv\Scripts\python.exe -m pytest tests\integration\test_wave4_cli_commands_coverage.py::TestConfigCommand tests\integration\test_commands_config_coverage.py -q.\.venv\Scripts\python.exe -m ruff check src\apm_cli\commands\config.py tests\unit\test_config_command.py tests\unit\test_cli_consistency.py.\.venv\Scripts\python.exe -m ruff format --check src\apm_cli\commands\config.py tests\unit\test_config_command.py tests\unit\test_cli_consistency.py.\.venv\Scripts\apm.exe config listnpm run buildindocs/git diff --check