roam-code 11.1.3__tar.gz → 11.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {roam_code-11.1.3/src/roam_code.egg-info → roam_code-11.2.0}/PKG-INFO +15 -8
- {roam_code-11.1.3 → roam_code-11.2.0}/README.md +14 -7
- {roam_code-11.1.3 → roam_code-11.2.0}/pyproject.toml +1 -1
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/cli.py +3 -1
- roam_code-11.2.0/src/roam/commands/cmd_clones.py +163 -0
- roam_code-11.2.0/src/roam/graph/clone_detect.py +552 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/mcp_server.py +31 -0
- {roam_code-11.1.3 → roam_code-11.2.0/src/roam_code.egg-info}/PKG-INFO +15 -8
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam_code.egg-info/SOURCES.txt +3 -0
- roam_code-11.2.0/tests/test_clones.py +400 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_surface_counts.py +6 -6
- {roam_code-11.1.3 → roam_code-11.2.0}/LICENSE +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/setup.cfg +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/__main__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/analysis/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/analysis/effects.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/analysis/taint.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/api.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/base.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/bridge_config.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/bridge_protobuf.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/bridge_rest_api.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/bridge_salesforce.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/bridge_template.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/bridges/registry.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/catalog/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/catalog/detectors.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/catalog/fixes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/catalog/smells.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/catalog/tasks.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/changed_files.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_adrs.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_adversarial.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_affected.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_affected_tests.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_agent_context.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_agent_export.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_agent_plan.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_ai_ratio.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_ai_readiness.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_alerts.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_annotate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_api_changes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_api_drift.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_attest.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_auth_gaps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_bisect.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_breaking.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_budget.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_bus_factor.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_capsule.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_check_rules.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_ci_setup.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_clean.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_closure.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_clusters.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_codeowners.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_complexity.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_config.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_congestion.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_context.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_conventions.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_coupling.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_coverage_gaps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_cut.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_dark_matter.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_dashboard.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_dead.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_debt.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_deps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_describe.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_dev_profile.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_diagnose.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_diff.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_doc_staleness.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_docs_coverage.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_doctor.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_drift.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_duplicates.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_effects.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_endpoints.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_entry_points.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_fan.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_file.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_fingerprint.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_fitness.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_flag_dead.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_fn_coupling.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_forecast.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_grep.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_guard.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_health.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_hooks.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_hotspots.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_impact.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_index.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_ingest_trace.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_init.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_intent.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_invariants.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_layers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_map.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_math.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_mcp_setup.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_metrics.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_migration_safety.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_minimap.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_missing_index.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_module.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_mutate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_n1.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_orchestrate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_orphan_routes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_over_fetch.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_owner.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_partition.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_path_coverage.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_patterns.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_plan.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_plan_refactor.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_pr_diff.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_pr_risk.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_preflight.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_relate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_report.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_reset.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_risk.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_rules.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_safe_delete.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_safe_zones.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_sbom.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_schema.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_search.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_search_semantic.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_secrets.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_semantic_diff.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_simulate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_simulate_departure.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_sketch.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_smells.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_spectral.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_split.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_supply_chain.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_symbol.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_syntax_check.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_test_gaps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_test_scaffold.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_testmap.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_tour.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_trace.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_trends.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_triage.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_understand.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_uses.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_verify.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_verify_imports.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_vibe_check.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_visualize.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_vuln_map.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_vuln_reach.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_vulns.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_watch.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_weather.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_why.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_ws.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/cmd_xlang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/codeowners_helpers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/context_helpers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/gate_presets.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/graph_helpers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/metrics_history.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/next_steps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/resolve.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/commands/suppression.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/competitor_site_data.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/coverage_reports.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/db/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/db/connection.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/db/queries.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/db/schema.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/exit_codes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/anomaly.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/builder.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/clusters.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/cycles.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/dark_matter.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/diff.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/fingerprint.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/layers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/pagerank.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/partition.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/pathfinding.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/propagation.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/simulate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/spectral.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/graph/stats.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/complexity.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/discovery.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/file_roles.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/git_stats.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/gitignore.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/incremental.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/indexer.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/parser.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/relations.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/symbols.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/index/test_conventions.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/apex_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/aura_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/base.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/c_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/csharp_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/extractor_schema.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/foxpro_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/generic_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/go_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/hcl_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/java_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/javascript_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/kotlin_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/php_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/python_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/query_engine.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/registry.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/ruby_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/rust_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/scala_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/sfxml_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/sql_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/swift_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/typescript_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/visualforce_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/languages/yaml_lang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/output/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/output/formatter.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/output/mermaid.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/output/sarif.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/output/schema_registry.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/plugins.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/refactor/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/refactor/codegen.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/refactor/transforms.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/rules/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/rules/ast_match.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/rules/builtin.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/rules/dataflow.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/rules/engine.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/runtime/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/runtime/hotspots.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/runtime/trace_ingest.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/search/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/search/framework_packs.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/search/index_embeddings.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/search/onnx_embeddings.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/search/tfidf.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/security/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/security/vuln_reach.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/security/vuln_store.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/surface_counts.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/templates/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/templates/ci/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/workspace/__init__.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/workspace/aggregator.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/workspace/api_scanner.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/workspace/config.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam/workspace/db.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam_code.egg-info/dependency_links.txt +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam_code.egg-info/entry_points.txt +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam_code.egg-info/requires.txt +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/src/roam_code.egg-info/top_level.txt +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_adrs.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_adversarial.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_affected.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_agent_export.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_agent_mode.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_agent_plan_context.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_ai_ratio.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_ai_readiness.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_alerts_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_annotations.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_anomaly.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_api_changes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_api_drift.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_attest.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_auth_gaps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_backend_fixes_round2.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_backend_fixes_round3.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_basic.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_batch_mcp.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_bisect.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_bridges.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_bridges_extended.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_budget.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_budget_flag.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_budget_phase2.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_bus_factor.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_capsule.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_check_rules.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_ci_gate_eval.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_ci_sarif_guard.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_ci_setup.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_closure.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_codeowners.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_commands_architecture.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_commands_exploration.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_commands_health.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_commands_refactoring.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_commands_workflow.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_competitor_site_data.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_comprehensive.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_congestion.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_context_propagation.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_conventions_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_coverage_gaps_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_coverage_ingestion.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_cut.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_dark_matter.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_dashboard.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_dataflow_dead.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_dead_aging.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_defer_loading.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_demo_gif_asset.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_describe.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_deterministic_output.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_dev_profile.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_difficulty_scoring.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_doc_staleness.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_docker_assets.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_docs_coverage.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_docs_site_quality.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_doctor.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_drift.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_duplicates.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_effects.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_effects_propagation.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_endpoints.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_entry_points_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_exclude_patterns.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_exit_codes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_file_roles.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_fingerprint.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_fixes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_flag_dead.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_fn_coupling.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_forecast.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_formatters.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_foxpro.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_framework_detection.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_gate_presets.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_guard.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_health_gate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_hooks.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_hotspots.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_index.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_init_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_install_check.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_intent.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_invariants.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_json_contracts.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_kotlin_swift_extractors.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_language_corpus.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_languages.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_library_api.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_math.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_math_tips.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_mcp_server.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_mcp_setup.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_mermaid.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_metrics_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_migration_safety.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_minimap.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_missing_index.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_mutate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_n1.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_next_steps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_onboard.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_orchestrate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_orphan_routes.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_oss_bench_harness.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_over_fetch.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_pagerank_truncation.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_partition.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_path_coverage.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_patterns_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_performance.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_plan.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_plugin_discovery.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_pr_comment_script.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_pr_diff.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_pr_risk_author.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_progress.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_progressive_disclosure.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_properties.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_python_extractor_v2.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_readme_surface_consistency.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_refactoring_intelligence.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_relate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_report.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_reset_clean.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_resolve.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_risk.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_ruby.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_rule_profiles.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_rules.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_rules_ast_match.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_rules_community_pack.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_rules_dataflow.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_rules_symbol_requirements.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_runtime.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_salesforce.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_sarif_flag.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_sbom.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_scala.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_schema_versioning.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_search_explain.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_secrets.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_secrets_v2.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_semantic_diff.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_semantic_onnx.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_semantic_search.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_simulate.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_simulate_departure.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_sketch.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_smells.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_smoke.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_sna_metrics.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_spectral.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_split_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_sql.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_suggest_reviewers.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_supply_chain.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_syntax_check.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_taint_analysis.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_test_conventions.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_test_gaps.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_test_scaffold.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_testmap.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_tour_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_trends.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_trends_cohort.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_triage.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_uses_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_v6_features.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_v71_features.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_v7_features.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_v82_features.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_verify.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_verify_imports.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_vibe_check.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_visualize.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_vuln.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_vulns_cmd.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_watch.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_why.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_workspace.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_xlang.py +0 -0
- {roam_code-11.1.3 → roam_code-11.2.0}/tests/test_yaml_hcl.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: roam-code
|
|
3
|
-
Version: 11.
|
|
3
|
+
Version: 11.2.0
|
|
4
4
|
Summary: Instant codebase comprehension for AI coding agents
|
|
5
5
|
Author: CosmoHac
|
|
6
6
|
License-Expression: MIT
|
|
@@ -51,7 +51,7 @@ Dynamic: license-file
|
|
|
51
51
|
|
|
52
52
|
**The architectural intelligence layer for AI coding agents. Structural graph, architecture governance, multi-agent orchestration, vulnerability mapping, runtime analysis -- one CLI, zero API keys.**
|
|
53
53
|
|
|
54
|
-
*
|
|
54
|
+
*140 commands · 102 MCP tools · 27 languages · 100% local*
|
|
55
55
|
|
|
56
56
|
[](https://pypi.org/project/roam-code/)
|
|
57
57
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -111,6 +111,11 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
111
111
|
|
|
112
112
|
## What's New in v11
|
|
113
113
|
|
|
114
|
+
### v11.2 -- AST Clone Detection + Debug Artifact Rules
|
|
115
|
+
- **`roam clones`**: New AST structural clone detection via subtree hashing. Finds Type-2 clones (identical control flow, different identifiers/literals) with Jaccard similarity scoring, Union-Find clustering, and automated refactoring suggestions. More precise than the metric-based `duplicates` command.
|
|
116
|
+
- **9 debug artifact rules** (COR-560 through COR-568): Detect leftover `print()`, `breakpoint()`, `pdb.set_trace()`, `console.log()`, `debugger`, and `System.out.println()` in Python, JavaScript, TypeScript, and Java code. All use `ast_match` type with test file exemptions.
|
|
117
|
+
- **140 commands, 102 MCP tools**.
|
|
118
|
+
|
|
114
119
|
### v11.1.2 -- SQL + Scala Tier 1, 27 Languages
|
|
115
120
|
- **SQL DDL promoted to Tier 1** with dedicated `SqlExtractor` -- tables, columns, views, functions, triggers, schemas, types (enums), sequences, ALTER TABLE ADD COLUMN. Foreign keys produce graph edges; views and triggers reference source tables. Database-schema projects now work with `roam health`, `roam layers`, `roam impact`, `roam coupling` and all graph commands.
|
|
116
121
|
- **Scala promoted to Tier 1** with dedicated `ScalaExtractor` -- classes, traits, objects, case classes, sealed hierarchies, val/var properties, type aliases, imports, and inheritance. Full `extends` + `with` trait mixin resolution.
|
|
@@ -118,7 +123,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
118
123
|
- `server.json` for official MCP Registry submission.
|
|
119
124
|
|
|
120
125
|
### v11.1.1 -- Command Quality Audit
|
|
121
|
-
- **Full command audit**: all
|
|
126
|
+
- **Full command audit**: all 140 commands reviewed for usefulness, duplicates, and test coverage. ~20 bugs fixed, 21 new test files (700+ tests), every command docstring updated with cross-references to related commands.
|
|
122
127
|
- **Kotlin promoted to Tier 1** via new YAML-based declarative extractor architecture. Classes, interfaces, enums, objects, functions, methods, properties, and inheritance fully extracted.
|
|
123
128
|
- **7 new commands**: `roam congestion`, `roam adrs`, `roam flag-dead`, `roam test-scaffold`, `roam sbom`, `roam triage`, `roam ci-setup`.
|
|
124
129
|
- **CI templates**: `roam ci-setup` generates pipelines for GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, and Bitbucket.
|
|
@@ -273,7 +278,7 @@ roam health
|
|
|
273
278
|
|
|
274
279
|
## Commands
|
|
275
280
|
|
|
276
|
-
The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. All
|
|
281
|
+
The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. All 140 commands are organized into 7 categories.
|
|
277
282
|
|
|
278
283
|
<details>
|
|
279
284
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -531,6 +536,7 @@ The sentinel pair `<!-- roam:minimap -->` / `<!-- /roam:minimap -->` is replaced
|
|
|
531
536
|
| `roam safe-zones` | Graph-based containment boundaries |
|
|
532
537
|
| `roam coverage-gaps` | Unprotected entry points with no path to gate symbols |
|
|
533
538
|
| `roam duplicates [--threshold T] [--min-lines N]` | Semantic duplicate detector: functionally equivalent code clusters with divergent edge-case handling |
|
|
539
|
+
| `roam clones [--threshold T] [--min-lines N] [--scope P]` | AST structural clone detection: Type-2 clones via subtree hashing (more precise than `duplicates`) |
|
|
534
540
|
|
|
535
541
|
### Exploration
|
|
536
542
|
|
|
@@ -869,7 +875,7 @@ pip install "roam-code[mcp]"
|
|
|
869
875
|
roam mcp
|
|
870
876
|
```
|
|
871
877
|
|
|
872
|
-
|
|
878
|
+
102 tools, 10 resources, and 5 prompts are available in the full preset. Most tools are read-only index queries; side-effect tools are explicitly annotated.
|
|
873
879
|
|
|
874
880
|
**MCP v2 highlights (v11):**
|
|
875
881
|
- In-process MCP execution (no subprocess shell-out per call)
|
|
@@ -936,6 +942,7 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
|
|
|
936
942
|
| `roam_bisect_blame` | Architectural git bisect |
|
|
937
943
|
| `roam_doc_intent` | Doc-to-code linking |
|
|
938
944
|
| `roam_cut_analysis` | Minimum graph cut analysis |
|
|
945
|
+
| `roam_clones` | AST structural clone detection (Type-2 clones) |
|
|
939
946
|
| `roam_annotate_symbol` | Attach persistent notes to symbols |
|
|
940
947
|
| `roam_get_annotations` | View stored annotations |
|
|
941
948
|
| `roam_relate` | Show relationship between two symbols |
|
|
@@ -1512,8 +1519,8 @@ roam-code/
|
|
|
1512
1519
|
├── action.yml # Reusable GitHub Action
|
|
1513
1520
|
├── src/roam/
|
|
1514
1521
|
│ ├── __init__.py # Version (from pyproject.toml)
|
|
1515
|
-
│ ├── cli.py # Click CLI (
|
|
1516
|
-
│ ├── mcp_server.py # MCP server (
|
|
1522
|
+
│ ├── cli.py # Click CLI (140 commands)
|
|
1523
|
+
│ ├── mcp_server.py # MCP server (102 tools, 10 resources, 5 prompts)
|
|
1517
1524
|
│ ├── db/
|
|
1518
1525
|
│ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
|
|
1519
1526
|
│ │ ├── schema.py # Tables, indexes, migrations
|
|
@@ -1607,7 +1614,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
|
|
|
1607
1614
|
### Shipped
|
|
1608
1615
|
|
|
1609
1616
|
- [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
|
|
1610
|
-
- [x] Full command and MCP inventory parity in docs:
|
|
1617
|
+
- [x] Full command and MCP inventory parity in docs: 140 CLI commands and 102 MCP tools.
|
|
1611
1618
|
- [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
|
|
1612
1619
|
- [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
|
|
1613
1620
|
- [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**The architectural intelligence layer for AI coding agents. Structural graph, architecture governance, multi-agent orchestration, vulnerability mapping, runtime analysis -- one CLI, zero API keys.**
|
|
6
6
|
|
|
7
|
-
*
|
|
7
|
+
*140 commands · 102 MCP tools · 27 languages · 100% local*
|
|
8
8
|
|
|
9
9
|
[](https://pypi.org/project/roam-code/)
|
|
10
10
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -64,6 +64,11 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
64
64
|
|
|
65
65
|
## What's New in v11
|
|
66
66
|
|
|
67
|
+
### v11.2 -- AST Clone Detection + Debug Artifact Rules
|
|
68
|
+
- **`roam clones`**: New AST structural clone detection via subtree hashing. Finds Type-2 clones (identical control flow, different identifiers/literals) with Jaccard similarity scoring, Union-Find clustering, and automated refactoring suggestions. More precise than the metric-based `duplicates` command.
|
|
69
|
+
- **9 debug artifact rules** (COR-560 through COR-568): Detect leftover `print()`, `breakpoint()`, `pdb.set_trace()`, `console.log()`, `debugger`, and `System.out.println()` in Python, JavaScript, TypeScript, and Java code. All use `ast_match` type with test file exemptions.
|
|
70
|
+
- **140 commands, 102 MCP tools**.
|
|
71
|
+
|
|
67
72
|
### v11.1.2 -- SQL + Scala Tier 1, 27 Languages
|
|
68
73
|
- **SQL DDL promoted to Tier 1** with dedicated `SqlExtractor` -- tables, columns, views, functions, triggers, schemas, types (enums), sequences, ALTER TABLE ADD COLUMN. Foreign keys produce graph edges; views and triggers reference source tables. Database-schema projects now work with `roam health`, `roam layers`, `roam impact`, `roam coupling` and all graph commands.
|
|
69
74
|
- **Scala promoted to Tier 1** with dedicated `ScalaExtractor` -- classes, traits, objects, case classes, sealed hierarchies, val/var properties, type aliases, imports, and inheritance. Full `extends` + `with` trait mixin resolution.
|
|
@@ -71,7 +76,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
71
76
|
- `server.json` for official MCP Registry submission.
|
|
72
77
|
|
|
73
78
|
### v11.1.1 -- Command Quality Audit
|
|
74
|
-
- **Full command audit**: all
|
|
79
|
+
- **Full command audit**: all 140 commands reviewed for usefulness, duplicates, and test coverage. ~20 bugs fixed, 21 new test files (700+ tests), every command docstring updated with cross-references to related commands.
|
|
75
80
|
- **Kotlin promoted to Tier 1** via new YAML-based declarative extractor architecture. Classes, interfaces, enums, objects, functions, methods, properties, and inheritance fully extracted.
|
|
76
81
|
- **7 new commands**: `roam congestion`, `roam adrs`, `roam flag-dead`, `roam test-scaffold`, `roam sbom`, `roam triage`, `roam ci-setup`.
|
|
77
82
|
- **CI templates**: `roam ci-setup` generates pipelines for GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, and Bitbucket.
|
|
@@ -226,7 +231,7 @@ roam health
|
|
|
226
231
|
|
|
227
232
|
## Commands
|
|
228
233
|
|
|
229
|
-
The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. All
|
|
234
|
+
The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. All 140 commands are organized into 7 categories.
|
|
230
235
|
|
|
231
236
|
<details>
|
|
232
237
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -484,6 +489,7 @@ The sentinel pair `<!-- roam:minimap -->` / `<!-- /roam:minimap -->` is replaced
|
|
|
484
489
|
| `roam safe-zones` | Graph-based containment boundaries |
|
|
485
490
|
| `roam coverage-gaps` | Unprotected entry points with no path to gate symbols |
|
|
486
491
|
| `roam duplicates [--threshold T] [--min-lines N]` | Semantic duplicate detector: functionally equivalent code clusters with divergent edge-case handling |
|
|
492
|
+
| `roam clones [--threshold T] [--min-lines N] [--scope P]` | AST structural clone detection: Type-2 clones via subtree hashing (more precise than `duplicates`) |
|
|
487
493
|
|
|
488
494
|
### Exploration
|
|
489
495
|
|
|
@@ -822,7 +828,7 @@ pip install "roam-code[mcp]"
|
|
|
822
828
|
roam mcp
|
|
823
829
|
```
|
|
824
830
|
|
|
825
|
-
|
|
831
|
+
102 tools, 10 resources, and 5 prompts are available in the full preset. Most tools are read-only index queries; side-effect tools are explicitly annotated.
|
|
826
832
|
|
|
827
833
|
**MCP v2 highlights (v11):**
|
|
828
834
|
- In-process MCP execution (no subprocess shell-out per call)
|
|
@@ -889,6 +895,7 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
|
|
|
889
895
|
| `roam_bisect_blame` | Architectural git bisect |
|
|
890
896
|
| `roam_doc_intent` | Doc-to-code linking |
|
|
891
897
|
| `roam_cut_analysis` | Minimum graph cut analysis |
|
|
898
|
+
| `roam_clones` | AST structural clone detection (Type-2 clones) |
|
|
892
899
|
| `roam_annotate_symbol` | Attach persistent notes to symbols |
|
|
893
900
|
| `roam_get_annotations` | View stored annotations |
|
|
894
901
|
| `roam_relate` | Show relationship between two symbols |
|
|
@@ -1465,8 +1472,8 @@ roam-code/
|
|
|
1465
1472
|
├── action.yml # Reusable GitHub Action
|
|
1466
1473
|
├── src/roam/
|
|
1467
1474
|
│ ├── __init__.py # Version (from pyproject.toml)
|
|
1468
|
-
│ ├── cli.py # Click CLI (
|
|
1469
|
-
│ ├── mcp_server.py # MCP server (
|
|
1475
|
+
│ ├── cli.py # Click CLI (140 commands)
|
|
1476
|
+
│ ├── mcp_server.py # MCP server (102 tools, 10 resources, 5 prompts)
|
|
1470
1477
|
│ ├── db/
|
|
1471
1478
|
│ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
|
|
1472
1479
|
│ │ ├── schema.py # Tables, indexes, migrations
|
|
@@ -1560,7 +1567,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
|
|
|
1560
1567
|
### Shipped
|
|
1561
1568
|
|
|
1562
1569
|
- [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
|
|
1563
|
-
- [x] Full command and MCP inventory parity in docs:
|
|
1570
|
+
- [x] Full command and MCP inventory parity in docs: 140 CLI commands and 102 MCP tools.
|
|
1564
1571
|
- [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
|
|
1565
1572
|
- [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
|
|
1566
1573
|
- [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
|
|
@@ -14,7 +14,7 @@ import click
|
|
|
14
14
|
|
|
15
15
|
# Lazy-loading command group: imports command modules only when invoked.
|
|
16
16
|
# This avoids importing networkx (~500ms) on every CLI call.
|
|
17
|
-
# Total:
|
|
17
|
+
# Total: 143 invokable command names (140 canonical commands + 3 alias pairs).
|
|
18
18
|
# If this changes, update README.md, CLAUDE.md, llms-install.md, and docs copy.
|
|
19
19
|
_COMMANDS = {
|
|
20
20
|
"index": ("roam.commands.cmd_index", "index"),
|
|
@@ -159,6 +159,7 @@ _COMMANDS = {
|
|
|
159
159
|
"sbom": ("roam.commands.cmd_sbom", "sbom"),
|
|
160
160
|
"triage": ("roam.commands.cmd_triage", "triage"),
|
|
161
161
|
"ci-setup": ("roam.commands.cmd_ci_setup", "ci_setup"),
|
|
162
|
+
"clones": ("roam.commands.cmd_clones", "clones"),
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
# Command categories for organized --help display
|
|
@@ -252,6 +253,7 @@ _CATEGORIES = {
|
|
|
252
253
|
"visualize",
|
|
253
254
|
"x-lang",
|
|
254
255
|
"fingerprint",
|
|
256
|
+
"clones",
|
|
255
257
|
],
|
|
256
258
|
"Exploration": [
|
|
257
259
|
"search",
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""Detect near-duplicate code via AST structural hashing.
|
|
2
|
+
|
|
3
|
+
Unlike ``duplicates`` (which uses metric-based similarity from the DB),
|
|
4
|
+
this command re-parses source files and compares actual AST subtree
|
|
5
|
+
structures. Detects Type-2 clones: identical control flow with different
|
|
6
|
+
identifiers or literals.
|
|
7
|
+
|
|
8
|
+
Related commands: ``duplicates`` (metric-based), ``suggest-refactoring``,
|
|
9
|
+
``split`` (extract responsibilities).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import click
|
|
15
|
+
|
|
16
|
+
from roam.commands.resolve import ensure_index
|
|
17
|
+
from roam.db.connection import open_db
|
|
18
|
+
from roam.output.formatter import (
|
|
19
|
+
abbrev_kind,
|
|
20
|
+
format_table,
|
|
21
|
+
json_envelope,
|
|
22
|
+
loc,
|
|
23
|
+
to_json,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@click.command()
|
|
28
|
+
@click.option(
|
|
29
|
+
"--threshold",
|
|
30
|
+
default=0.70,
|
|
31
|
+
show_default=True,
|
|
32
|
+
type=click.FloatRange(0.0, 1.0),
|
|
33
|
+
help="Minimum Jaccard similarity (0.0-1.0)",
|
|
34
|
+
)
|
|
35
|
+
@click.option(
|
|
36
|
+
"--min-lines",
|
|
37
|
+
default=5,
|
|
38
|
+
show_default=True,
|
|
39
|
+
type=int,
|
|
40
|
+
help="Skip functions shorter than N lines",
|
|
41
|
+
)
|
|
42
|
+
@click.option("--scope", default=None, type=str, help="Limit to files under this path prefix")
|
|
43
|
+
@click.option("--top", default=0, type=int, help="Show only top N clusters (0=all)")
|
|
44
|
+
@click.pass_context
|
|
45
|
+
def clones(ctx, threshold, min_lines, scope, top):
|
|
46
|
+
"""Detect near-duplicate code via AST structural hashing.
|
|
47
|
+
|
|
48
|
+
Re-parses source files and compares function AST structures via subtree
|
|
49
|
+
hashing. Finds Type-2 clones: identical control flow with different
|
|
50
|
+
identifiers or literals.
|
|
51
|
+
|
|
52
|
+
Unlike ``duplicates`` (metric-based), this uses actual tree-sitter AST
|
|
53
|
+
comparison for higher precision.
|
|
54
|
+
"""
|
|
55
|
+
json_mode = ctx.obj.get("json") if ctx.obj else False
|
|
56
|
+
token_budget = ctx.obj.get("budget", 0) if ctx.obj else 0
|
|
57
|
+
ensure_index()
|
|
58
|
+
|
|
59
|
+
from roam.graph.clone_detect import detect_clones
|
|
60
|
+
|
|
61
|
+
with open_db(readonly=True) as conn:
|
|
62
|
+
pairs, clusters = detect_clones(
|
|
63
|
+
conn,
|
|
64
|
+
min_similarity=threshold,
|
|
65
|
+
min_lines=min_lines,
|
|
66
|
+
scope=scope,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if top > 0:
|
|
70
|
+
clusters = clusters[:top]
|
|
71
|
+
|
|
72
|
+
# Summary stats
|
|
73
|
+
total_functions = sum(len(c.members) for c in clusters)
|
|
74
|
+
total_pairs = len(pairs)
|
|
75
|
+
avg_sim = sum(c.avg_similarity for c in clusters) / len(clusters) if clusters else 0.0
|
|
76
|
+
|
|
77
|
+
# Estimate reducible lines
|
|
78
|
+
reducible_lines = 0
|
|
79
|
+
for c in clusters:
|
|
80
|
+
lines = sorted(m["line_end"] - m["line_start"] + 1 for m in c.members)
|
|
81
|
+
if len(lines) > 1:
|
|
82
|
+
reducible_lines += sum(lines[:-1])
|
|
83
|
+
|
|
84
|
+
verdict = (
|
|
85
|
+
f"{len(clusters)} clone cluster{'s' if len(clusters) != 1 else ''} "
|
|
86
|
+
f"found ({total_functions} functions, {round(avg_sim * 100)}% avg similarity)"
|
|
87
|
+
if clusters
|
|
88
|
+
else "No structural clones detected"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if json_mode:
|
|
92
|
+
clusters_json = []
|
|
93
|
+
for c in clusters:
|
|
94
|
+
clusters_json.append(
|
|
95
|
+
{
|
|
96
|
+
"cluster_id": c.cluster_id,
|
|
97
|
+
"avg_similarity": c.avg_similarity,
|
|
98
|
+
"size": len(c.members),
|
|
99
|
+
"members": c.members,
|
|
100
|
+
"pattern": c.pattern,
|
|
101
|
+
"suggestion": c.suggestion,
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
pairs_json = [
|
|
106
|
+
{
|
|
107
|
+
"file_a": p.file_a,
|
|
108
|
+
"func_a": p.func_a,
|
|
109
|
+
"line_a": p.line_a,
|
|
110
|
+
"file_b": p.file_b,
|
|
111
|
+
"func_b": p.func_b,
|
|
112
|
+
"line_b": p.line_b,
|
|
113
|
+
"similarity": p.similarity,
|
|
114
|
+
}
|
|
115
|
+
for p in pairs[:50] # Cap pair output
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
click.echo(
|
|
119
|
+
to_json(
|
|
120
|
+
json_envelope(
|
|
121
|
+
"clones",
|
|
122
|
+
summary={
|
|
123
|
+
"verdict": verdict,
|
|
124
|
+
"clusters": len(clusters),
|
|
125
|
+
"clone_pairs": total_pairs,
|
|
126
|
+
"total_functions": total_functions,
|
|
127
|
+
"avg_similarity": round(avg_sim, 3),
|
|
128
|
+
"estimated_reducible_lines": reducible_lines,
|
|
129
|
+
},
|
|
130
|
+
budget=token_budget,
|
|
131
|
+
clusters=clusters_json,
|
|
132
|
+
pairs=pairs_json,
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
# Text output
|
|
139
|
+
click.echo(f"VERDICT: {verdict}")
|
|
140
|
+
|
|
141
|
+
if not clusters:
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
click.echo()
|
|
145
|
+
for c in clusters:
|
|
146
|
+
sim_pct = round(c.avg_similarity * 100)
|
|
147
|
+
click.echo(f"CLUSTER {c.cluster_id} -- {sim_pct}% similarity, {len(c.members)} functions:")
|
|
148
|
+
for m in c.members:
|
|
149
|
+
lines = m["line_end"] - m["line_start"] + 1
|
|
150
|
+
click.echo(
|
|
151
|
+
f" {m['function']:<40s} "
|
|
152
|
+
f"{loc(m['file'], m['line_start'])}"
|
|
153
|
+
f" ({lines} lines, {m['ast_nodes']} AST nodes)"
|
|
154
|
+
)
|
|
155
|
+
click.echo(f" Pattern: {c.pattern}")
|
|
156
|
+
click.echo(f" Suggestion: {c.suggestion}")
|
|
157
|
+
click.echo()
|
|
158
|
+
|
|
159
|
+
click.echo(
|
|
160
|
+
f"SUMMARY: {len(clusters)} clusters, "
|
|
161
|
+
f"{total_functions} functions, "
|
|
162
|
+
f"~{reducible_lines} lines of reducible duplication"
|
|
163
|
+
)
|