Skip to content

feat(tools): get_version_range — affected version range resolver + CLI subcommand (+79 tests) - #130

Open
manus-use wants to merge 1 commit into
mainfrom
feat/cli-version-range
Open

feat(tools): get_version_range — affected version range resolver + CLI subcommand (+79 tests)#130
manus-use wants to merge 1 commit into
mainfrom
feat/cli-version-range

Conversation

@manus-use

@manus-use manus-use commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the manus-agent version-range CLI subcommand and get_version_range tool — a README-documented-but-completely-unimplemented feature gap.

Resolves a CVE to its affected version ranges by combining:

  1. NVD CPE configurations — walks versionStartIncluding/Excluding and versionEndIncluding/Excluding match criteria
  2. OSV.dev ecosystem data — fetches per-package introduced/fixed version events from PyPI, npm, Maven, Go, RustSec, etc.

Outputs structured vulnerable ranges, affected ecosystems, and the first-patched version.

Usage

manus-agent version-range CVE-2021-44228
manus-agent version-range CVE-2021-44228 --ecosystem pypi
manus-agent version-range CVE-2021-44228 --output json | jq .first_patched

Features

  • Dual-source resolution: NVD CPE ranges + OSV.dev ecosystem packages merged into one view
  • Ecosystem filtering: --ecosystem {auto,pypi,npm,maven,go,crates.io,rubygems,nuget,packagist}
  • CPE-to-ecosystem inference: Maps CPE vendor/product names to known ecosystems (13 mappings)
  • GHSA alias following: When CVE record lacks package data, follows GHSA aliases to recover version ranges
  • Retry/back-off: Exponential back-off on 429/5xx for both NVD and OSV APIs
  • NVD_API_KEY support: Optional higher rate limit when key is set
  • Graceful degradation: Reports partial data when one source fails
  • Strands @tool pattern: Full TOOL_SPEC + handler for agent integration

Test Coverage

79 fully-mocked tests covering:

  • TOOL_SPEC contract validation (5)
  • Input validation and edge cases (6)
  • CPE URI parsing (4)
  • NVD CPE range extraction (8)
  • NVD fetch with mocked HTTP (5)
  • OSV affected parsing (7)
  • OSV fetch and alias following (4)
  • Ecosystem inference (9)
  • Core integration (fetch_version_range) (7)
  • Strands tool entry point (5)
  • CLI subcommand dispatch (8)
  • Retry/back-off behaviour (4)
  • OSV record fetch helper (3)
  • Edge cases and boundaries (4)

Full suite: 1237 passed, 0 failures (baseline 1158 + 79 new)

Files Changed

  • src/manus_agent/tools/get_version_range.py — new tool module
  • src/manus_agent/cli.py — CLI dispatch + parser + _SUBCOMMANDS entry
  • tests/test_version_range.py — 79 tests

Duplicate Check

Checked all 50 open PRs (#134#183) and 30 merged PRs — no overlap. Closest PRs:

Design Decisions

  • Zero new dependencies (uses requests already in the project)
  • Follows existing patterns: retry/back-off, TOOL_SPEC, log_tool_output_size, CLI parser structure
  • 100% mocked tests — no real HTTP calls
  • Output capped (20 affected versions per package) to bound response size

@manus-use
manus-use force-pushed the feat/cli-version-range branch from cb4ce91 to 5484c26 Compare July 18, 2026 00:18
@manus-use
manus-use force-pushed the feat/cli-version-range branch from 5484c26 to d69b01b Compare August 8, 2026 00:07
@manus-use manus-use changed the title feat: implement 'version-range' CLI subcommand feat(cli): add version-range tool and CLI subcommand for affected version resolution (+56 tests) Aug 8, 2026
@manus-use
manus-use force-pushed the feat/cli-version-range branch from d69b01b to 3dfe4ff Compare August 9, 2026 16:09
@manus-use manus-use changed the title feat(cli): add version-range tool and CLI subcommand for affected version resolution (+56 tests) feat(tools): get_version_range — affected version range resolver + CLI subcommand (+79 tests) Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant