Last Updated: 2025-11-03 Target Audience: Existing users, integrators, contributors
Version 2.0 represents a major architectural evolution from a 3,387-line monolithic cli_audit.py to a modular design with:
- 18 specialized Python modules (6,608 total lines)
- 73 JSON tool catalog entries
- New entry point:
audit.py(50 lines) - Backward-compatible API via
__init__.pyexports
Good News: Most integrations will continue to work without changes thanks to comprehensive API exports in cli_audit/__init__.py.
Before (v1.x):
python3 cli_audit.py
CLI_AUDIT_COLLECT=1 python3 cli_audit.pyAfter (v2.0):
python3 audit.py
CLI_AUDIT_COLLECT=1 python3 audit.py --updateMakefile Commands (Unchanged):
make audit # Still works
make update # Still works
make upgrade # Still worksBefore (v1.x):
- Single file:
cli_audit.py(3,387 lines) - All functions in one namespace
After (v2.0):
audit.py (entry point, 50 lines)
cli_audit/
├── __init__.py # Public API exports
├── catalog.py # JSON catalog management
├── collectors.py # Upstream version collection
├── detection.py # Tool installation detection
├── render.py # Output formatting
├── snapshot.py # Snapshot management
├── tools.py # Tool definitions
├── common.py # Shared types
├── config.py # Configuration
├── environment.py # OS/arch detection
├── package_managers.py # Package manager abstractions
├── installer.py # Installation logic
├── install_plan.py # Planning & dependencies
├── bulk.py # Bulk operations
├── upgrade.py # Upgrade workflows
├── breaking_changes.py # Semver analysis
├── reconcile.py # Duplicate cleanup
└── logging_config.py # Logging setup
Before (v1.x):
- Tools defined in Python code (TOOLS tuple)
- Required code changes to add tools
After (v2.0):
- Tools defined in
catalog/*.jsonfiles (73 entries) - Add tools by creating JSON files (no code changes)
- Python TOOLS tuple remains as fallback
Unchanged:
upstream_versions.json(cache)tools_snapshot.json(snapshot)smart_column.py(formatting)MakefileandMakefile.d/scripts/directorytests/directory
New:
catalog/directory (73 JSON files)cli_audit/package (18 Python modules)audit.pyentry point
Renamed:
cli_audit.py→cli_audit_legacy.py(backup, may be removed later)
All Phase 1 and Phase 2 APIs are re-exported through cli_audit/__init__.py for compatibility:
These imports still work:
# Phase 1: Detection & Auditing
from cli_audit import Tool, all_tools, filter_tools
from cli_audit import audit_tool_installation, extract_version_number
from cli_audit import load_snapshot, write_snapshot, render_from_snapshot
from cli_audit import collect_github, collect_pypi, collect_npm, collect_crates
from cli_audit import status_icon, render_table, print_summary
# Phase 2: Installation & Upgrade
from cli_audit import Environment, detect_environment
from cli_audit import Config, load_config
from cli_audit import install_tool, upgrade_tool
from cli_audit import bulk_install, bulk_upgrade, bulk_reconcile
from cli_audit import detect_breaking_changesFor new code, import directly from modules:
# Detection & Auditing
from cli_audit.tools import Tool, all_tools, filter_tools
from cli_audit.catalog import ToolCatalog, ToolCatalogEntry
from cli_audit.detection import audit_tool_installation
from cli_audit.collectors import collect_github, collect_pypi
from cli_audit.snapshot import load_snapshot, write_snapshot
from cli_audit.render import render_table, status_icon
# Foundation
from cli_audit.environment import Environment, detect_environment
from cli_audit.config import Config, load_config
from cli_audit.common import InstallResult, AuditResult
# Installation
from cli_audit.installer import install_tool
from cli_audit.upgrade import upgrade_tool
from cli_audit.bulk import bulk_install, bulk_upgrade
from cli_audit.reconcile import reconcile_installationsBefore:
python3 cli_audit.py --only ripgrepAfter:
python3 audit.py --only ripgrepMigration:
- Update scripts/automation to use
audit.py - Or continue using
make auditwhich abstracts the entry point
Before:
# Location: cli_audit.py:729
@dataclass(frozen=True)
class Tool:
...After:
# Location: cli_audit/tools.py:14
@dataclass(frozen=True)
class Tool:
...Migration:
- Update documentation/comments referencing line numbers
- Use module paths instead:
cli_audit.tools.Tool
Before:
from cli_audit import _debug_log, _validate_cache # Private functionsAfter:
# Private functions NOT exported in __init__.py
# Access directly from modules if absolutely necessary:
from cli_audit.logging_config import _debug_log
from cli_audit.snapshot import _validate_snapshotMigration:
- Avoid using private functions (prefixed with
_) - Use public APIs where possible
- If unavoidable, import from specific modules
Before:
# Tools hardcoded in cli_audit.py
from cli_audit import TOOLS
tool = TOOLS[0]After:
# Option 1: Use tools.py fallback (maintains compatibility)
from cli_audit.tools import TOOLS
tool = TOOLS[0]
# Option 2: Use new catalog system (recommended)
from cli_audit.catalog import ToolCatalog
catalog = ToolCatalog()
entry = catalog.get("ripgrep")Migration:
TOOLStuple still exists incli_audit.toolsfor compatibility- New code should use
ToolCatalogfor accessing tool metadata
No Action Required ✅
Makefile commands abstract the entry point:
make audit # Uses audit.py internally
make update # Uses audit.py internally
make upgrade # Uses scripts/guide.shCheck and Update Entry Point:
Before:
# GitHub Actions
- run: python3 cli_audit.py --only python-coreAfter:
# GitHub Actions
- run: python3 audit.py --only python-core
# OR use Makefile abstraction:
- run: make audit-python-coreGitLab CI:
audit:
script:
- python3 audit.py --only agent-core
# OR: make audit-agent-coreOption A: No Changes (Backward Compatible)
# This still works due to __init__.py exports
from cli_audit import audit_tool_installation, all_tools
from cli_audit import load_snapshot, render_table
tools = all_tools()
snapshot = load_snapshot()
render_table(snapshot)Option B: Update to Modular Imports (Recommended)
# New modular approach
from cli_audit.tools import all_tools, filter_tools
from cli_audit.snapshot import load_snapshot, render_from_snapshot
from cli_audit.render import render_table, print_summary
tools = all_tools()
snapshot = load_snapshot()
render_table(snapshot)Before (v1.x): Edit Python Code
# Edit cli_audit.py, add to TOOLS tuple:
Tool("my-tool", ("my-tool",), "gh", ("owner", "repo"), "category", "hint")After (v2.0): Create JSON File
# Create catalog/my-tool.json:
{
"name": "my-tool",
"install_method": "github_release_binary",
"description": "My amazing tool",
"homepage": "https://github.com/owner/my-tool",
"github_repo": "owner/my-tool",
"binary_name": "my-tool",
"version_flag": "--version",
"notes": ""
}Migration:
- Tool definitions can be JSON files in
catalog/ - Python
TOOLStuple incli_audit.toolsremains as fallback - See CATALOG_GUIDE.md for schema details
Before:
from cli_audit import find_paths, get_version_line, extract_version_number
paths = find_paths("ripgrep")
version_line = get_version_line(paths[0], ("--version",))
version = extract_version_number(version_line)After (Same, Backward Compatible):
# Works unchanged due to __init__.py exports
from cli_audit import find_paths, get_version_line, extract_version_number
# OR use modular imports:
from cli_audit.detection import find_paths, get_version_line, extract_version_numberBefore:
from cli_audit import collect_github, collect_pypi
tag, version = collect_github("sharkdp", "fd")After (Backward Compatible):
# Works unchanged
from cli_audit import collect_github, collect_pypi
# OR modular:
from cli_audit.collectors import collect_github, collect_pypi# Test basic audit
python3 audit.py --only ripgrep
# Test collection
CLI_AUDIT_COLLECT=1 python3 audit.py --update
# Test with Make
make audit
make update# Test backward-compatible imports
python3 -c "from cli_audit import Tool, all_tools; print(f'Tools: {len(all_tools())}')"
# Test modular imports
python3 -c "from cli_audit.tools import all_tools; print(f'Tools: {len(all_tools())}')"
# Test catalog
python3 -c "from cli_audit.catalog import ToolCatalog; catalog = ToolCatalog(); print(f'Catalog entries: {len(catalog)}')"# Unit tests
python3 -m pytest tests/test_config.py -v
# Integration tests
python3 -m pytest tests/integration/ -v
# Smoke test
./scripts/test_smoke.shCause: Python path not set correctly
Solution:
export PYTHONPATH=/path/to/ai_cli_preparation:$PYTHONPATH
# OR run from project root
cd /path/to/ai_cli_preparation
python3 audit.pyCause: Running from wrong directory
Solution:
# Always run from project root
cd /path/to/ai_cli_preparation
python3 audit.pyCause: Function not exported in __init__.py (may be private or renamed)
Solution:
# Check if function is private (_prefixed)
# Import from specific module:
from cli_audit.detection import audit_tool_installation # Correct nameCause: Module loading overhead (minimal, ~10ms)
Solution:
- Use snapshot-based workflow:
make updateonce, thenmake auditrepeatedly - Performance should be equivalent after initial load
Cause: catalog/*.json files missing or invalid
Solution:
# Check catalog directory exists
ls -l catalog/
# Validate JSON files
for f in catalog/*.json; do jq . "$f" > /dev/null || echo "Invalid: $f"; done
# Fallback to Python TOOLS tuple automatically used if catalog missingIf you encounter critical issues, you can temporarily revert to the legacy monolith:
# cli_audit_legacy.py is the renamed original
python3 cli_audit_legacy.py# Revert to pre-v2.0 commit
git checkout <pre-v2.0-commit># If using pip/package manager
pip install ai-cli-preparation==1.x.xNote: Legacy support is temporary. Plan migration to v2.0 modular architecture.
After migration, you gain:
- Maintainability: Focused modules vs 3,387-line monolith
- Extensibility: Add tools via JSON, not code changes
- Testability: Isolated modules with targeted tests
- Performance: Optimized imports, faster startup
- Community: JSON contributions easier than Python code
- Documentation: Clearer module responsibilities
Resources:
- ARCHITECTURE.md - Understand modular design
- CATALOG_GUIDE.md - Work with JSON tool definitions
- API_REFERENCE.md - Comprehensive API documentation
- INDEX.md - Documentation navigation
Issues:
- GitHub Issues: Report migration problems
- Discussions: Ask questions about migration
Minimum Migration Effort:
- ✅ Makefile commands work unchanged
- ✅ Most Python imports work unchanged (via
__init__.py) ⚠️ Update entry point:cli_audit.py→audit.py(if direct invocation)⚠️ Update documentation references (line numbers)
Recommended Migration:
- Use modular imports for new code
- Adopt JSON catalog for new tools
- Update CI/CD to use
audit.pyor Makefile abstractions - Review ARCHITECTURE.md for deep understanding
Timeline:
- Immediate: Test with your integration
- Short-term (days): Update entry points in automation
- Medium-term (weeks): Adopt modular imports
- Long-term (months): Contribute JSON catalog entries
Welcome to v2.0! 🎉