Converge is a Python CLI for scanning a repository, building a local dependency graph, diagnosing dependency problems, creating a repository-scoped virtual environment, and applying validated manifest repairs.
It is designed for one core workflow:
- Point Converge at a repository
- Scan the repository into a local graph
- Diagnose problems from that graph
- Create or repair the environment using repository-scoped artifacts
Converge stores its own derived data inside the target repository, not in a global shared cache.
- Scans
pyproject.tomlandrequirements*.txt - Parses Python imports from the repository source tree
- Stores a repository-local graph at
.converge/graph.db - Detects unresolved imports and unused declared dependencies
- Creates a
.venvinside the target repository - Exports graph data to JSON or CSV artifacts
- Applies validated dependency additions to
pyproject.toml
When you run Converge against a repository, it writes derived artifacts inside that repository:
- Graph database:
.converge/graph.db - Exports:
.converge/exports/ - Incremental scan fingerprints:
.converge/scan_state.json - Fix audit log (append-only):
.converge/audit.log - Default environment:
.venv - Validation sandbox:
.venv-converge-test
This makes command behavior predictable and keeps multiple repositories isolated from each other.
Repository settings are read from .converge.toml (optional) and merged with [tool.converge] in pyproject.toml (values in pyproject.toml win on conflicts). See docs/ROADMAP.md for supported keys (for example incremental_scan, test_roots, repair_targets, extra_scan_roots).
Global CLI flags:
--json: machine-readable JSON on stdout for many commands (useful in CI). Each payload includes stable metadata:schema_version(integer, currently1) andtool_version(installedconverge-cliversion). Diagnostics go to stderr when using--verbose(logging).--quiet/--verbose: reduce or increase console noise; verbose enables DEBUG logging on theconverge.*loggers to stderr.
Exit codes (converge.exit_codes.ExitCode):
0— success; no actionable issues for commands that distinguish that case.1— completed but dependency conflicts were found (doctor,fixdry-run).2— error (missing graph, export failure, etc.).
Examples:
converge --json doctor /path/to/repo
converge --quiet scan /path/to/repouv tool install converge-clipipx install converge-cligit clone <your-repo-url>
cd converge
uv sync --devIf you are working from source in this repository, the test commands below assume:
PYTHONPATH=srcconverge scan /path/to/repoWhat it does:
- Parses declared dependencies from manifests
- Scans Python files for imports
- Writes the graph to
/path/to/repo/.converge/graph.db
Useful variant:
converge scan /path/to/repo --dry-runUse --dry-run when you want to inspect the scan result without writing the graph database.
converge doctor /path/to/repoWhat it reports today:
- Unresolved imports: a package is imported in code but missing from manifests
- Unused dependencies: a package is declared but never imported in scanned modules
- Version clashes if they exist in the graph
If the repository has not been scanned yet, doctor tells you to run scan first.
converge explain conflict:unresolved_mod:main.py_pkg:requests /path/to/repoYou can also explain an entity already present in the graph:
converge explain pkg:requests /path/to/repoUse explain when doctor finds an issue and you want clearer context for what Converge saw.
converge create /path/to/repo --provider uvWhat it does:
- Loads the repository graph
- Collects package nodes from that graph
- Creates
/path/to/repo/.venv - Installs the resolved package set into that environment
By default, Converge creates .venv inside the target repository and prints the activation command after creation.
Optional Python version:
converge create /path/to/repo --provider uv --python 3.12Dry run:
converge fix /path/to/repoApply a validated repair:
converge fix /path/to/repo --applyCurrent behavior:
- Detects unresolved imports from the graph
- Generates candidate repair plans
- Validates plans in an isolated sandbox
- Applies the selected validated change to
pyproject.tomland optionally torequirements*.txt(see[tool.converge]/repair_targets) - Appends a JSON line to
.converge/audit.logfor each successful--apply
Today, the repair flow is conservative and focused on dependency additions for unresolved imports.
Export to JSON:
converge export /path/to/repo --format jsonExport to CSV:
converge export /path/to/repo --format csvGenerated artifacts:
- JSON:
.converge/exports/graph.json - CSV:
.converge/exports/nodes.csvand.converge/exports/edges.csv
converge clean /path/to/repoThis removes Converge-generated artifacts such as:
.converge/graph.db.converge/exports/.converge/scan_state.json.converge/audit.log.venv-converge-test
converge scan PATH [--dry-run]PATH: target repository--dry-run: do not persist the graph
converge doctor PATHPATH: target repository that has already been scanned
converge explain TARGET PATHTARGET: entity ID or conflict IDPATH: target repository
converge create PATH [--provider uv|pip] [--python VERSION]PATH: target repository--provider: environment provisioning backend--python: interpreter version if supported by the selected provider
converge fix PATH [--apply]PATH: target repository--apply: validate and write the selected repair
converge export PATH [--format json|csv]PATH: target repository--format: output format
converge clean PATHPATH: target repository
Given a repository with this problem:
import requestsbut this manifest:
[project]
name = "demo"
dependencies = []You can run:
converge scan .
converge doctor .
converge fix .
converge fix . --applyAfter fix --apply, Converge updates pyproject.toml with the validated missing dependency and keeps the graph and environment operations scoped to that repository.
Converge aims for output that is:
- Repository-scoped
- Specific about what changed
- Honest about what was simulated versus applied
- Actionable for developers
If a command succeeds, it should tell you where artifacts were written. If it fails, it should tell you what prerequisite is missing or what next command to run.
TMPDIR=/tmp PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src .venv/bin/pytest tests/unit tests/integration -v -sTMPDIR=/tmp PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src .venv/bin/pytest tests/integration/test_fix_command.py -v -sIf you have the tools installed in the local environment:
.venv/bin/ruff check src tests
.venv/bin/mypy srcConverge is useful today, but it is not pretending to do more than the current implementation proves.
Examples of current limits:
- Repair planning is still focused on dependency additions, not broad manifest surgery
- Validation is smoke-test based, not a full application test harness
- Import classification is Python-focused and intentionally conservative
- Export formats are intentionally simple and designed for debugging and inspection
Run:
converge scan /path/to/repoYou need to scan the target repository first:
converge scan /path/to/repo
converge create /path/to/repoPossible reasons:
- No issues were found
- Validation failed for all candidate plans
pyproject.tomlis missing from the target repository
You likely have not scanned the repository yet:
converge scan /path/to/repo
converge export /path/to/repo --format jsonKey files:
src/converge/project_context.pysrc/converge/graph/store.pysrc/converge/scanner/project.pysrc/converge/scanner/ast_parser.pysrc/converge/env_manager.pysrc/converge/repair/manifest.pysrc/converge/cli/main.py
For repository-specific contributor guidance, see AGENTS.md.
MIT