[CFX-4730] feat(plugin): wire CLI version constraint checks into discovery - #815
[CFX-4730] feat(plugin): wire CLI version constraint checks into discovery#815ajalon1 wants to merge 1 commit into
Conversation
…iscovery Wire the inert compatibleCLIVersion/cliVersionSkip predicate (added in a prior commit) into actual plugin discovery behavior: - internal/plugin/discover.go: call cliVersionSkip in loadManagedPlugin and in getManifestsParallel's merge/dedup loop, both strictly before the seen[...] name reservation, so an incompatible plugin never blocks a compatible, identically-named plugin and is reported as an incompatibility rather than a name conflict. - internal/plugin/discover.go: add ConflictsForReason and switch LogConflicts on PluginConflict.Reason — WARN for name conflicts (unchanged wording), INFO for version incompatibility. - cmd/plugin/discovery.go: extract reportDiscoveryConflicts so routine command registration only warns about name conflicts and stays silent about version-incompatibility skips; those surface only via `dr plugin list` / `dr plugin version <name>`, which already pass the full conflict set through LogConflicts unfiltered. - docs: document maxCLIVersion/minCLIVersion semantics in docs/development/plugins.md and docs/development/remote-plugins.md. Verified via a real built binary that `dr plugin list`/`dr plugin version` surface the skip with upgrade guidance while ordinary command discovery (`dr --help`) stays silent. Refs: CFX-4730. Stacks on #814.
|
🎫 Jira: |
There was a problem hiding this comment.
again, will be deleted, just wanted to leave it here for reference
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5bbf0ab. Configure here.
| // would otherwise take. | ||
| if conflict := cliVersionSkip(&manifest, pluginDir); conflict != nil { | ||
| return nil, conflict, nil | ||
| } |
There was a problem hiding this comment.
Version skip misclassified as conflict
Medium Severity
cliVersionSkip runs only after the seen name check, so when a higher-priority compatible plugin already claimed the name, an incompatible peer is recorded as SkipReasonNameConflict instead of SkipReasonVersionIncompatible. That turns a routine version skip into a WARN on every dr invocation (via reportDiscoveryConflicts), violating the silence rule for version-incompatible plugins. A common case is a managed compatible install plus an older same-named PATH binary.
| } | |
| if conflict := cliVersionSkip(&manifest, pluginDir); conflict != nil { | |
| return nil, conflict, nil | |
| } | |
| if seen[manifest.Name] { | |
| return nil, &PluginConflict{Name: manifest.Name, Path: pluginDir}, nil | |
| } |
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5bbf0ab. Configure here.


What
PR 2 of 2 (stacks on #814). Wires the inert
compatibleCLIVersion/cliVersionSkippredicate from #814 into actual plugin discovery behavior.Why
CFX-4730: plugin manifests can declare
minCLIVersion/maxCLIVersionbounds, but until now those bounds were parsed and validated (#814) without being enforced. This PR makes the CLI actually skip incompatible plugins at discovery time.Changes
internal/plugin/discover.go: callcliVersionSkipinsideloadManagedPluginand insidegetManifestsParallel's merge/dedup loop, both strictly before theseen[...]name reservation — an incompatible plugin never blocks a compatible, identically-named plugin, and is reported as a version incompatibility, never a name conflict.internal/plugin/discover.go: addedConflictsForReason;LogConflictsnow switches onPluginConflict.Reason— WARN for name conflicts (byte-identical wording to before), INFO for version incompatibility (includes the violated bound + running CLI version + upgrade guidance).cmd/plugin/discovery.go: extractedreportDiscoveryConflictsso routine command registration (RegisterPluginCommands, which runs on everydrinvocation) only warns about name conflicts and stays silent about version-incompatibility skips. Those surface only viadr plugin list/dr plugin version <name>, which already pass the full, unfiltered conflict set throughLogConflicts— verified this needs no code changes there via a real binary harness run (see Testing).maxCLIVersion/minCLIVersionsemantics indocs/development/plugins.mdanddocs/development/remote-plugins.md.Testing
task lint— clean, 0 issues on all 3 GOOS targets.task test— full repo suite green (race + coverage);internal/pluginpackage coverage 80.9%.minCLIVersionis skipped and not loaded; two PATH dirs sharing a manifest name where the lexicographically-first violatesmaxCLIVersion— the second still registers under that name, and the skip is reported asSkipReasonVersionIncompatible, neverSkipReasonNameConflict;LogConflictslevel-switch behavior;ConflictsForReasonfiltering;reportDiscoveryConflictssilence on routine discovery.-ldflags "-X .../version.Version=1.0.0", created a fakedr-oldwidgetPATH plugin declaringmaxCLIVersion: 0.9.0. Confirmeddr plugin listexcludes it from the table and prints the INFO skip line;dr plugin version oldwidgetprints the same line then reports the plugin as not found; plaindr --helpprints neither the plugin name nor "version incompatible" (silent on ordinary discovery, per spec).Refs CFX-4730. Stacks on #814.
Note
Medium Risk
Changes which plugins are loaded and registered on every CLI invocation. Incorrect skip ordering or logging could hide valid plugins or spam every
drcommand, but this is not auth, secrets, or data-handling.Overview
Enforces plugin
minCLIVersion/maxCLIVersionat discovery so incompatible plugins never load. This is the second slice of CFX-4730: it wires the previously inertcliVersionSkipcheck into managed and PATH discovery before name reservation, so a version-skipped plugin cannot block a compatible plugin with the same name.LogConflictsnow Warns only for name collisions and Infos version skips (with bound + upgrade guidance). Routine command registration stays silent on version skips; they appear only viadr plugin list/dr plugin version. Docs cover inclusive bounds, thedev/unparseable-CLI bypass, and malformed-bound skips.Reviewed by Cursor Bugbot for commit 5bbf0ab. Configure here.