Skip to content

fix(cli,protocols): registry⇄MATRIX drift guard (#130) + roll out "did you mean?" flag errors (#111) - #157

Merged
mobileskyfi merged 2 commits into
mainfrom
dry-july-cli-registry-hygiene
Jul 3, 2026
Merged

fix(cli,protocols): registry⇄MATRIX drift guard (#130) + roll out "did you mean?" flag errors (#111)#157
mobileskyfi merged 2 commits into
mainfrom
dry-july-cli-registry-hygiene

Conversation

@mobileskyfi

@mobileskyfi mobileskyfi commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Pull Request

Two mechanical, no-CHR Dry July items (#152) bundled per the umbrella's sanctioned micro-item PR-bundling rule. Both touch the same src/cli + src/protocols self-consistency seam and are unit-tier only.

Links

Change type

  • Behavior change — CLI unknown-flag error output; protocol-registry capability/implemented metadata
  • Docs/spec-only change
  • Tooling/workflow change
  • Security-sensitive change

What changed

#130 — protocol registry ⇄ MATRIX drift (bug)

src/protocols/index.ts had drifted from docs/MATRIX.md:

Protocol Was Now MATRIX evidence
native-api capabilities missing transfer transfer added transfer / native-api = CHR-passed
ssh implemented: false implemented: true execute/terminal/transfer all CHR-passed
mndp implemented: false implemented: true discover / mndp = CHR-passed

Recurrence guard: test/unit/protocol-registry.test.ts parses the MATRIX grid and asserts every CHR-passed cell implies its protocol is implemented: true and lists the mapped capability — the registry can never silently under-claim against MATRIX again (MATRIX stays the only status surface; the test derives from it). The module header states the contract.

#111 — roll out shared unknownFlagError ("did you mean?")

PR #110 added unknownFlagError and wired it into api. retrieve and execute were already converted before this PR (src/cli/retrieve.ts:376, src/cli/execute.ts:257); this PR finishes the remaining six parsers — transfer, terminal, btest (client + server), devices, discover, mcp — so all parsers give the same Levenshtein closest-match + alias guidance with structured context: { flag, suggestions }. btest's hints are scoped to the active client/server subcommand (review follow-up). Per-parser near-miss coverage added in cli-errors.test.ts via in-process runCli.

Notes

  • Validation run: bun run lint && bun run test && bun run build965 unit tests pass, build clean, cspell/typecheck green. All CI checks (incl. CodeQL, CHR smoke, CodeRabbit) green.
  • RouterOS/protocol assumptions: no runtime path change. The only runtime consumer of .implemented (resolveVia in retrieve.ts) is reached only after a retrieve-capability check that ssh/mndp never pass; snmp (the sole retrieve-capable unimplemented protocol) is untouched. native-api transfer is descriptive (transfer/native-api is already CHR-passed, so no capability gate enforced it). Unit-tier only; no CHR integration run required (both issues' Verification sections specify unit-tier).

🤖 Generated with Claude Code

…d you mean?" flag errors (#111)

Two mechanical, no-CHR Dry July items bundled per the umbrella's micro-item
PR-bundling rule (#152).

#130 protocols/index.ts registry drift (bug):
- native-api: add missing `transfer` capability (transfer/native-api is CHR-passed)
- ssh: implemented false -> true (execute/terminal/transfer all CHR-passed)
- mndp: implemented false -> true (discover/mndp is CHR-passed)
- add test/unit/protocol-registry.test.ts: derives the expectation from the
  docs/MATRIX.md grid (every CHR-passed cell implies implemented:true + the
  matching capability), so it fails if the registry under-claims again. MATRIX
  stays the only status surface. Module header states the contract.
- Grounded: the only runtime `.implemented` consumer (retrieve) is gated behind
  a retrieve-capability check ssh/mndp never pass, so these are descriptive-only
  corrections with no runtime path change.

#111 roll shared unknownFlagError("did you mean?") into the parsers still
throwing bare errors — transfer, terminal, btest (client+server), devices,
discover, mcp — matching the api parser wired in PR #110. Adds per-parser
near-miss coverage in cli-errors.test.ts via in-process runCli.

Verification: bun run lint && bun run test && bun run build (unit-tier; no CHR).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 3, 2026 00:38
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR standardizes unknown-flag error handling across six CLI parsers (btest, devices, discover, mcp, terminal, transfer) by using a shared unknownFlagError helper, and fixes protocol registry drift by correcting implemented status and capabilities for ssh, mndp, and native-api, with new tests for both.

Changes

Shared unknownFlagError rollout across CLI parsers

Layer / File(s) Summary
btest unknown-flag handling
src/cli/btest.ts
Client and server parsers now throw unknownFlagError("btest", arg, btestCommand.options) instead of generic Error messages.
devices and discover unknown-flag handling
src/cli/devices.ts, src/cli/discover.ts
Both parsers replace generic Error throws with unknownFlagError(...) using their respective command options.
mcp unknown-flag handling
src/cli/mcp.ts
Adds an undefined-arg skip in the parse loop and replaces the generic unknown-flag Error with unknownFlagError(...).
terminal and transfer unknown-flag handling
src/cli/terminal.ts, src/cli/transfer.ts
Replaces custom asCentrsError/CentrsError constructions with unknownFlagError(...).
Unknown-flag suggestion tests
test/unit/cli-errors.test.ts
Adds near-miss scenarios verifying exit code, command-specific message, "Did you mean" suggestion, and absence of stack traces across all parsers.

Protocol registry drift fix against MATRIX

Layer / File(s) Summary
Protocol registry corrections
src/protocols/index.ts
Documents the MATRIX contract, adds transfer capability to native-api, and flips ssh/mndp to implemented: true with updated notes.
MATRIX drift-guard and regression tests
test/unit/protocol-registry.test.ts
Parses docs/MATRIX.md grid, dynamically asserts CHR-passed protocols are implemented with expected capabilities, and adds anchor/uniqueness tests.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related PRs

  • tikoci/centrs#111: The originating issue for rolling out the shared unknownFlagError helper to remaining CLI parsers.
  • tikoci/centrs#117: Modifies the same parseTransferCliArgs logic in src/cli/transfer.ts that this PR updates for unknown-flag handling.
  • tikoci/centrs#153: Updates docs/MATRIX.md formatting that the new protocol-registry drift-guard test directly parses.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The registry drift fix and guard satisfy #130, but #111 is only partially met because retrieve and execute were not updated. Add unknownFlagError rollout and tests for src/cli/retrieve.ts and src/cli/execute.ts, then rerun the unit coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The changes stay within the two stated scopes: protocol registry drift/guarding and shared unknown-flag handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately summarizes both the protocol drift guard and the shared unknown-flag error rollout.
Description check ✅ Passed The description matches the required template and fills the links, change type, validation, and protocol-assumption notes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dry-july-cli-registry-hygiene

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens centrs’ internal consistency by (1) preventing protocol registry drift from the MATRIX status grid and (2) standardizing CLI unknown-flag UX across commands via the shared unknownFlagError helper.

Changes:

  • Added a unit drift-guard that parses docs/MATRIX.md and asserts the protocol registry never under-claims vs CHR-passed cells.
  • Aligned src/protocols/index.ts with MATRIX reality (native-api transfer, ssh implemented, mndp implemented) and documented the contract.
  • Rolled out shared “Did you mean …?” unknown-flag errors across remaining CLI parsers and added near-miss coverage.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/unit/protocol-registry.test.ts New MATRIX→registry drift guard + regression anchors for the #130 fixes.
test/unit/cli-errors.test.ts Adds coverage asserting “Did you mean?” suggestions and non-stack error output for unknown flags.
src/protocols/index.ts Updates registry capabilities/implemented flags to match MATRIX; documents asserted contract.
src/cli/transfer.ts Uses shared unknownFlagError for unknown flags.
src/cli/terminal.ts Uses shared unknownFlagError for unknown flags.
src/cli/mcp.ts Uses shared unknownFlagError for unknown flags.
src/cli/discover.ts Uses shared unknownFlagError for unknown flags.
src/cli/devices.ts Uses shared unknownFlagError for unknown flags.
src/cli/btest.ts Uses shared unknownFlagError for unknown flags (client + server).

Comment thread src/cli/mcp.ts
Comment on lines 58 to +61
const arg = args[index];
if (arg === undefined) {
continue;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the if (arg === undefined) continue; guard: it exists to satisfy TypeScript noUncheckedIndexedAccess (indexed access on args[index] is string | undefined) and it intentionally mirrors the identical idiom already used by the sibling parsers — discover.ts:91, devices.ts:193, transfer.ts:334. args is never sparse here, so the branch is inert in practice; if it ever did fire it skips one stray token rather than dereferencing undefined. Making mcp fail-loud while the other three continue would be a one-off inconsistency, so I'm leaving it consistent with the established pattern.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli/btest.ts`:
- Line 280: The unknown-flag handling in btest is using shared
btestCommand.options, which can produce suggestions from the wrong mode. Update
the unknownFlagError calls in the btest command flow to pass only the active
mode’s options (client vs server), using the existing btest mode handling around
btestCommand and the relevant client/server option lists so suggestions stay
actionable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 462652fd-34c2-4e45-b1f7-3db55fbd8f8d

📥 Commits

Reviewing files that changed from the base of the PR and between 3cffe16 and c7728e3.

📒 Files selected for processing (9)
  • src/cli/btest.ts
  • src/cli/devices.ts
  • src/cli/discover.ts
  • src/cli/mcp.ts
  • src/cli/terminal.ts
  • src/cli/transfer.ts
  • src/protocols/index.ts
  • test/unit/cli-errors.test.ts
  • test/unit/protocol-registry.test.ts

Comment thread src/cli/btest.ts Outdated
…ver mode

CodeRabbit review on #157: btest's single `btestCommand.options` list documents
both subcommands, so a typo in one mode could suggest a flag that only exists in
the other (e.g. `btest server --protcol` hinting the client-only `--protocol`).
Add `btestOptionsFor(mode)` to filter by the `(client)`/`(server)` marker
(shared flags carry no marker → kept for both; a dropped marker degrades to the
old behavior, never a crash) and pass the scoped list to unknownFlagError at
both throw sites. Adds a regression test asserting cross-mode isolation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mobileskyfi
mobileskyfi merged commit 123a1b9 into main Jul 3, 2026
10 checks passed
@mobileskyfi
mobileskyfi deleted the dry-july-cli-registry-hygiene branch July 3, 2026 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants