roam-code 12.1.0__tar.gz → 12.3.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-12.1.0/src/roam_code.egg-info → roam_code-12.3.0}/PKG-INFO +24 -9
- {roam_code-12.1.0 → roam_code-12.3.0}/README.md +11 -7
- {roam_code-12.1.0 → roam_code-12.3.0}/pyproject.toml +46 -2
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/attest/cga.py +34 -9
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_cga.py +21 -4
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_critique.py +63 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_dead.py +16 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_diagnose.py +9 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_entry_points.py +7 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_fan.py +41 -2
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_health.py +30 -6
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_mcp_setup.py +39 -2
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_oracle.py +64 -22
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_preflight.py +45 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_retrieve.py +96 -3
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_rules.py +14 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_sbom.py +26 -2
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_search.py +10 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_smells.py +77 -3
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_taint.py +22 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_weather.py +12 -2
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/metrics_history.py +16 -11
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/resolve.py +58 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/competitor_site_data.py +1 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/config.py +4 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/clusters.py +63 -8
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/pagerank.py +16 -6
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/kotlin_lang.py +92 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_server.py +215 -2
- roam_code-12.3.0/src/roam/retrieve/learned_ranker.py +241 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/retrieve/pipeline.py +222 -7
- roam_code-12.3.0/src/roam/retrieve/rerank.py +510 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/retrieve/seeds.py +19 -13
- roam_code-12.3.0/src/roam/retrieve/semantic.py +194 -0
- roam_code-12.3.0/src/roam/runtime/daemon.py +100 -0
- roam_code-12.3.0/src/roam/runtime/graph_backend.py +92 -0
- roam_code-12.3.0/src/roam/runtime/lock_modes.py +50 -0
- roam_code-12.3.0/src/roam/runtime/lockmgr.py +136 -0
- roam_code-12.3.0/src/roam/security/aibom_extension.py +249 -0
- {roam_code-12.1.0 → roam_code-12.3.0/src/roam_code.egg-info}/PKG-INFO +24 -9
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam_code.egg-info/SOURCES.txt +11 -0
- roam_code-12.3.0/src/roam_code.egg-info/requires.txt +34 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_batch_mcp.py +9 -1
- roam_code-12.3.0/tests/test_extractor_grammar_drift.py +171 -0
- roam_code-12.3.0/tests/test_fallback_contracts.py +225 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_mcp_server.py +14 -2
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_readme_surface_consistency.py +7 -1
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_retrieve.py +1 -0
- roam_code-12.3.0/tests/test_retrieve_cross_repo.py +249 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_retrieve_seeds.py +12 -4
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_surface_counts.py +2 -0
- roam_code-12.3.0/tests/test_v12_2.py +300 -0
- roam_code-12.1.0/src/roam/retrieve/rerank.py +0 -266
- roam_code-12.1.0/src/roam_code.egg-info/requires.txt +0 -19
- {roam_code-12.1.0 → roam_code-12.3.0}/LICENSE +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/setup.cfg +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/__main__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/analysis/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/analysis/effects.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/analysis/taint.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/api.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/ask/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/ask/classifier.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/ask/recipes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/ask/runner.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/attest/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/base.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/bridge_config.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/bridge_django.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/bridge_protobuf.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/bridge_rest_api.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/bridge_salesforce.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/bridge_template.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/bridges/registry.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/catalog/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/catalog/detectors.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/catalog/fixes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/catalog/smells.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/catalog/tasks.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/cli.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/changed_files.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_adrs.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_adversarial.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_affected.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_affected_tests.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_agent_context.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_agent_export.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_agent_plan.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_ai_ratio.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_ai_readiness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_alerts.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_annotate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_api_changes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_api_drift.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_ask.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_attest.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_auth_gaps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_bisect.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_breaking.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_budget.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_bus_factor.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_capsule.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_check_rules.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_ci_setup.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_clean.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_clones.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_closure.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_clusters.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_codeowners.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_complexity.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_config.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_congestion.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_context.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_conventions.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_coupling.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_coverage_gaps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_cut.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_dark_matter.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_dashboard.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_debt.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_deps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_describe.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_dev_profile.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_diff.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_doc_staleness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_docs_coverage.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_doctor.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_drift.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_duplicates.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_effects.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_endpoints.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_eval_retrieve.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_file.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_fingerprint.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_fitness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_flag_dead.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_fleet.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_fn_coupling.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_forecast.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_grep.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_guard.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_hooks.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_hotspots.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_impact.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_index.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_index_bundle.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_ingest_trace.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_init.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_intent.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_invariants.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_layers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_map.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_math.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_metrics.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_migration_safety.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_minimap.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_missing_index.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_module.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_mutate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_n1.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_orchestrate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_orphan_routes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_over_fetch.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_owner.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_partition.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_path_coverage.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_patterns.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_plan.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_plan_refactor.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_pr_diff.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_pr_risk.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_relate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_report.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_reset.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_risk.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_safe_delete.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_safe_zones.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_schema.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_search_semantic.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_secrets.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_semantic_diff.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_simulate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_simulate_departure.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_sketch.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_spectral.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_split.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_supply_chain.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_symbol.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_syntax_check.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_test_gaps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_test_scaffold.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_testmap.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_tour.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_trace.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_trends.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_triage.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_understand.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_uses.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_verify.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_verify_imports.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_vibe_check.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_visualize.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_vuln_map.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_vuln_reach.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_vulns.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_watch.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_why.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_ws.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/cmd_xlang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/codeowners_helpers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/context_helpers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/gate_presets.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/graph_helpers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/next_steps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/commands/suppression.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/coverage_reports.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/critique/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/critique/aggregator.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/critique/checks.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/db/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/db/connection.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/db/queries.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/db/schema.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/eval/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/eval/harness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/exit_codes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/fleet/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/fleet/adapters.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/fleet/manifest.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/git_utils.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/anomaly.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/builder.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/clone_detect.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/cycles.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/dark_matter.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/diff.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/fingerprint.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/layers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/partition.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/pathfinding.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/propagation.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/simulate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/spectral.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/graph/stats.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/complexity.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/discovery.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/django_post.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/file_roles.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/git_stats.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/gitignore.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/incremental.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/indexer.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/parser.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/relations.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/symbols.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/index/test_conventions.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/apex_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/aura_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/base.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/c_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/csharp_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/extractor_schema.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/foxpro_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/generic_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/go_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/hcl_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/java_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/javascript_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/php_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/python_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/query_engine.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/registry.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/ruby_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/rust_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/scala_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/sfxml_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/sql_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/swift_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/typescript_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/visualforce_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/languages/yaml_lang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_extras/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_extras/completions.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_extras/progress.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_extras/sampling.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_extras/session.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/mcp_extras/watcher.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/output/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/output/formatter.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/output/mermaid.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/output/sarif.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/output/schema_registry.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/plugins.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/refactor/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/refactor/codegen.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/refactor/transforms.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/retrieve/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/rules/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/rules/ast_match.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/rules/builtin.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/rules/dataflow.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/rules/engine.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/runtime/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/runtime/hotspots.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/runtime/trace_ingest.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/search/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/search/framework_packs.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/search/index_embeddings.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/search/onnx_embeddings.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/search/tfidf.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/security/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/security/taint_classifier.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/security/taint_engine.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/security/vuln_reach.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/security/vuln_store.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/surface_counts.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/templates/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/templates/ci/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/workspace/__init__.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/workspace/aggregator.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/workspace/api_scanner.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/workspace/config.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam/workspace/db.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam_code.egg-info/dependency_links.txt +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam_code.egg-info/entry_points.txt +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/src/roam_code.egg-info/top_level.txt +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_adrs.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_adversarial.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_affected.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_agent_export.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_agent_mode.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_agent_plan_context.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ai_ratio.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ai_readiness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_alerts_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_annotations.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_anomaly.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_api_changes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_api_drift.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ask.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_attest.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_auth_gaps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_backend_fixes_round2.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_backend_fixes_round3.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_basic.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_bisect.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_bridge_django.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_bridges.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_bridges_extended.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_budget.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_budget_flag.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_budget_phase2.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_bus_factor.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_capsule.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_cga.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_check_rules.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ci_gate_eval.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ci_sarif_guard.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ci_setup.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_clones.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_closure.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_codeowners.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_commands_architecture.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_commands_exploration.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_commands_health.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_commands_refactoring.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_commands_workflow.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_competitor_site_data.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_comprehensive.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_config.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_congestion.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_context_propagation.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_conventions_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_coverage_gaps_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_coverage_ingestion.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_critique.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_cut.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_dark_matter.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_dark_matter_helpers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_dashboard.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_dataflow_dead.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_dead_aging.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_defer_loading.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_demo_gif_asset.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_describe.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_detail_flag_hints.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_deterministic_output.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_dev_profile.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_difficulty_scoring.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_doc_staleness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_docker_assets.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_docs_coverage.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_docs_site_quality.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_doctor.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_drift.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_duplicates.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_effects.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_effects_propagation.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_endpoints.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_entry_points_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_eval_retrieve.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_exclude_patterns.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_exit_codes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_file_roles.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_fingerprint.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_fixes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_flag_dead.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_fleet.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_fn_coupling.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_forecast.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_formatters.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_foxpro.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_framework_detection.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_gate_presets.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_git_utils.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_guard.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_health_gate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_hooks.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_hotspots.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_index.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_index_bundle.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_init_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_install_check.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_intent.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_invariants.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_json_contracts.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_json_error_envelope.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_kotlin_swift_extractors.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_language_corpus.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_languages.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_library_api.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_math.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_math_tips.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_mcp_extras.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_mcp_setup.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_mermaid.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_metrics_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_migration_safety.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_minimap.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_missing_index.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_mutate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_n1.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_next_steps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_onboard.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_oracle.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_orchestrate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_orphan_routes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_oss_bench_harness.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_over_fetch.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_pagerank_truncation.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_partition.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_path_coverage.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_patterns_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_performance.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_personalized_pagerank.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_plan.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_plugin_discovery.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_pr_comment_script.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_pr_diff.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_pr_risk_author.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_progress.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_progressive_disclosure.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_properties.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_python_extractor_v2.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_refactoring_intelligence.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_relate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_report.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_reset_clean.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_resolve.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_risk.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ruby.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_rule_profiles.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_rules.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_rules_ast_match.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_rules_community_pack.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_rules_dataflow.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_rules_symbol_requirements.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_runtime.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_runtime_score.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_salesforce.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_sarif_flag.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_sbom.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_scala.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_schema_versioning.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_search_explain.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_secrets.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_secrets_v2.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_semantic_diff.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_semantic_onnx.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_semantic_search.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_simulate.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_simulate_departure.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_sketch.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_smells.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_smoke.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_sna_metrics.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_spectral.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_split_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_sql.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_suggest_reviewers.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_supply_chain.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_syntax_check.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_taint.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_taint_analysis.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_taint_classifier.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_test_conventions.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_test_gaps.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_test_scaffold.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_testmap.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_top_flag_consistency.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_tour_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_trends.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_trends_cohort.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_triage.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_uses_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_v6_features.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_v71_features.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_v7_features.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_v82_features.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_verify.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_verify_imports.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_vibe_check.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_visualize.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_vuln.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_vulns_cmd.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_watch.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_why.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_workspace.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_ws_resolve_fixes.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.0}/tests/test_xlang.py +0 -0
- {roam_code-12.1.0 → roam_code-12.3.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: 12.
|
|
3
|
+
Version: 12.3.0
|
|
4
4
|
Summary: Instant codebase comprehension for AI coding agents
|
|
5
5
|
Author: CosmoHac
|
|
6
6
|
License-Expression: MIT
|
|
@@ -29,7 +29,7 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
License-File: LICENSE
|
|
30
30
|
Requires-Dist: click>=8.0
|
|
31
31
|
Requires-Dist: tree-sitter>=0.23
|
|
32
|
-
Requires-Dist: tree-sitter-language-pack
|
|
32
|
+
Requires-Dist: tree-sitter-language-pack<1.6.3,>=0.6
|
|
33
33
|
Requires-Dist: networkx>=3.0
|
|
34
34
|
Provides-Extra: mcp
|
|
35
35
|
Requires-Dist: fastmcp>=2.0; extra == "mcp"
|
|
@@ -37,9 +37,20 @@ Provides-Extra: semantic
|
|
|
37
37
|
Requires-Dist: numpy>=1.24; extra == "semantic"
|
|
38
38
|
Requires-Dist: onnxruntime>=1.16; extra == "semantic"
|
|
39
39
|
Requires-Dist: tokenizers>=0.15; extra == "semantic"
|
|
40
|
+
Provides-Extra: leiden
|
|
41
|
+
Requires-Dist: igraph>=0.11; extra == "leiden"
|
|
42
|
+
Requires-Dist: leidenalg>=0.10; extra == "leiden"
|
|
43
|
+
Provides-Extra: graph-fast
|
|
44
|
+
Requires-Dist: rustworkx>=0.14; extra == "graph-fast"
|
|
45
|
+
Provides-Extra: sbom
|
|
46
|
+
Requires-Dist: cyclonedx-python-lib>=8.0; extra == "sbom"
|
|
47
|
+
Provides-Extra: learned
|
|
48
|
+
Requires-Dist: lightgbm>=4.0; extra == "learned"
|
|
40
49
|
Provides-Extra: dev
|
|
41
50
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
42
51
|
Requires-Dist: pytest-xdist>=3.0; extra == "dev"
|
|
52
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
53
|
+
Requires-Dist: scipy>=1.11; extra == "dev"
|
|
43
54
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
44
55
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
45
56
|
Requires-Dist: twine>=5.0; extra == "dev"
|
|
@@ -51,7 +62,7 @@ Dynamic: license-file
|
|
|
51
62
|
|
|
52
63
|
**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
64
|
|
|
54
|
-
*150 commands ·
|
|
65
|
+
*150 commands · 116 MCP tools · 27 languages · 100% local*
|
|
55
66
|
|
|
56
67
|
[](https://pypi.org/project/roam-code/)
|
|
57
68
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -128,7 +139,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
128
139
|
- **`personalized_pagerank()`** in `graph/pagerank.py`: NetworkX `personalization=` wrapper with empty-seed fallback to global PR; biases ranking toward query-relevant nodes for the retrieve reranker.
|
|
129
140
|
- **`.roam/config.toml`** (new): zero-dep TOML loader (stdlib `tomllib` → `tomli` → in-tree subset parser). Tunable retrieve weights (`alpha`/`beta`/`gamma`/`delta`/`epsilon`), `tokens_per_line`, `lexical_baseline`, `first_stage_token_cap`, `default_budget`, `default_k`, `default_rerank`.
|
|
130
141
|
- **DX corrections from dogfood pass**: `roam --detail <cmd>` is the canonical group-level flag; misleading "use --detail" hints in 7 commands rewritten to point users at `roam --detail <cmd>`. `--top N` aliased on `complexity`/`algo`/`rules` (`--top 0` means unlimited on `rules`). `roam fingerprint` no longer refuses graphs ≥5,000 symbols (new soft-warn threshold 20k, hard cap 100k).
|
|
131
|
-
- **150 CLI commands,
|
|
142
|
+
- **150 CLI commands, 116 MCP tools** (`fleet`, `ask`, `taint`, `cga`, `eval-retrieve` remain CLI-only; v12 exposes `roam_retrieve`, `roam_critique`, `roam_fleet_plan`, plus 5 v12.1 boolean oracles (`roam_oracle_*`) and `roam_taint_classify` as MCP tools). 33-tool `core` preset is the default for token-budget-conscious clients.
|
|
132
143
|
|
|
133
144
|
## What's New in v11
|
|
134
145
|
|
|
@@ -159,7 +170,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
159
170
|
- MCP token overhead for default core context dropped from ~36K to <3K tokens (about 92% reduction).
|
|
160
171
|
|
|
161
172
|
### Performance and Retrieval
|
|
162
|
-
- Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to milliseconds (
|
|
173
|
+
- Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to tens of milliseconds on the indexed cohort (mileage varies by repo size and query selectivity — see `bench/retrieve/` for the methodology).
|
|
163
174
|
- Incremental indexing shifted from O(N) full-edge rebuild behavior to O(changed) updates.
|
|
164
175
|
- DB/runtime optimizations (`mmap_size`, safer large-graph guards, batched writes) reduce first-run and reindex friction on larger repos.
|
|
165
176
|
|
|
@@ -299,7 +310,7 @@ roam health
|
|
|
299
310
|
|
|
300
311
|
## Commands
|
|
301
312
|
|
|
302
|
-
The [5 core commands](#core-commands)
|
|
313
|
+
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 145 commands are detail surface for specialised workflows (taint, fleet, cga, oracle, eval, …) — they're called by agents on demand, not memorised. This is intentional design; under the hood the canonical surface is **150 commands organised into 7 categories**, but you don't need to know that to start.
|
|
303
314
|
|
|
304
315
|
<details>
|
|
305
316
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -937,7 +948,7 @@ ROAM_MCP_LITE=0 roam mcp
|
|
|
937
948
|
Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`, `roam_complete`, `roam_complexity_report`, `roam_context`, `roam_dead_code`, `roam_deps`, `roam_diagnose`, `roam_diagnose_issue`, `roam_diff`, `roam_expand_toolset`, `roam_explore`, `roam_file_info`, `roam_health`, `roam_impact`, `roam_pr_risk`, `roam_preflight`, `roam_prepare_change`, `roam_review_change`, `roam_search_symbol`, `roam_syntax_check`, `roam_trace`, `roam_understand`, `roam_uses`.
|
|
938
949
|
|
|
939
950
|
<details>
|
|
940
|
-
<summary><strong>MCP tool list (all
|
|
951
|
+
<summary><strong>MCP tool list (all 116)</strong></summary>
|
|
941
952
|
|
|
942
953
|
| Tool | Description |
|
|
943
954
|
|------|-------------|
|
|
@@ -957,6 +968,10 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
|
|
|
957
968
|
| `roam_oracle_is_reachable_from_entry` | Boolean oracle: can BFS reach this symbol from any entry-point? |
|
|
958
969
|
| `roam_oracle_is_clone_of` | Boolean oracle: does this symbol participate in a persisted clone cluster? |
|
|
959
970
|
| `roam_taint_classify` | LLM-augmented taint classification (IDOR/AUTHZ/SQLI/...) via MCP sampling |
|
|
971
|
+
| `roam_taint` | Static taint analysis — graph-reach BFS with OpenVEX-correct findings |
|
|
972
|
+
| `roam_sbom` | CycloneDX 1.7 / SPDX 2.3 SBOM emit with optional AIBOM extension (EU AI Act) |
|
|
973
|
+
| `roam_cga_emit` | Emit a Code Graph Attestation (in-toto v1) with optional cosign signing |
|
|
974
|
+
| `roam_cga_verify` | Verify a CGA statement — re-derives Merkle + edge digest, checks cosign signature |
|
|
960
975
|
| `roam_trace` | Dependency path between two symbols |
|
|
961
976
|
| `roam_impact` | Blast radius of changing a symbol |
|
|
962
977
|
| `roam_file_info` | File skeleton with all definitions |
|
|
@@ -1568,7 +1583,7 @@ roam-code/
|
|
|
1568
1583
|
├── src/roam/
|
|
1569
1584
|
│ ├── __init__.py # Version (from pyproject.toml)
|
|
1570
1585
|
│ ├── cli.py # Click CLI (150 commands)
|
|
1571
|
-
│ ├── mcp_server.py # MCP server (
|
|
1586
|
+
│ ├── mcp_server.py # MCP server (116 tools, 10 resources, 5 prompts)
|
|
1572
1587
|
│ ├── db/
|
|
1573
1588
|
│ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
|
|
1574
1589
|
│ │ ├── schema.py # Tables, indexes, migrations
|
|
@@ -1662,7 +1677,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
|
|
|
1662
1677
|
### Shipped
|
|
1663
1678
|
|
|
1664
1679
|
- [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
|
|
1665
|
-
- [x] Full command and MCP inventory parity in docs: 150 CLI commands and
|
|
1680
|
+
- [x] Full command and MCP inventory parity in docs: 150 CLI commands and 116 MCP tools.
|
|
1666
1681
|
- [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
|
|
1667
1682
|
- [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
|
|
1668
1683
|
- [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
|
-
*150 commands ·
|
|
7
|
+
*150 commands · 116 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)
|
|
@@ -81,7 +81,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
81
81
|
- **`personalized_pagerank()`** in `graph/pagerank.py`: NetworkX `personalization=` wrapper with empty-seed fallback to global PR; biases ranking toward query-relevant nodes for the retrieve reranker.
|
|
82
82
|
- **`.roam/config.toml`** (new): zero-dep TOML loader (stdlib `tomllib` → `tomli` → in-tree subset parser). Tunable retrieve weights (`alpha`/`beta`/`gamma`/`delta`/`epsilon`), `tokens_per_line`, `lexical_baseline`, `first_stage_token_cap`, `default_budget`, `default_k`, `default_rerank`.
|
|
83
83
|
- **DX corrections from dogfood pass**: `roam --detail <cmd>` is the canonical group-level flag; misleading "use --detail" hints in 7 commands rewritten to point users at `roam --detail <cmd>`. `--top N` aliased on `complexity`/`algo`/`rules` (`--top 0` means unlimited on `rules`). `roam fingerprint` no longer refuses graphs ≥5,000 symbols (new soft-warn threshold 20k, hard cap 100k).
|
|
84
|
-
- **150 CLI commands,
|
|
84
|
+
- **150 CLI commands, 116 MCP tools** (`fleet`, `ask`, `taint`, `cga`, `eval-retrieve` remain CLI-only; v12 exposes `roam_retrieve`, `roam_critique`, `roam_fleet_plan`, plus 5 v12.1 boolean oracles (`roam_oracle_*`) and `roam_taint_classify` as MCP tools). 33-tool `core` preset is the default for token-budget-conscious clients.
|
|
85
85
|
|
|
86
86
|
## What's New in v11
|
|
87
87
|
|
|
@@ -112,7 +112,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
112
112
|
- MCP token overhead for default core context dropped from ~36K to <3K tokens (about 92% reduction).
|
|
113
113
|
|
|
114
114
|
### Performance and Retrieval
|
|
115
|
-
- Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to milliseconds (
|
|
115
|
+
- Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to tens of milliseconds on the indexed cohort (mileage varies by repo size and query selectivity — see `bench/retrieve/` for the methodology).
|
|
116
116
|
- Incremental indexing shifted from O(N) full-edge rebuild behavior to O(changed) updates.
|
|
117
117
|
- DB/runtime optimizations (`mmap_size`, safer large-graph guards, batched writes) reduce first-run and reindex friction on larger repos.
|
|
118
118
|
|
|
@@ -252,7 +252,7 @@ roam health
|
|
|
252
252
|
|
|
253
253
|
## Commands
|
|
254
254
|
|
|
255
|
-
The [5 core commands](#core-commands)
|
|
255
|
+
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 145 commands are detail surface for specialised workflows (taint, fleet, cga, oracle, eval, …) — they're called by agents on demand, not memorised. This is intentional design; under the hood the canonical surface is **150 commands organised into 7 categories**, but you don't need to know that to start.
|
|
256
256
|
|
|
257
257
|
<details>
|
|
258
258
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -890,7 +890,7 @@ ROAM_MCP_LITE=0 roam mcp
|
|
|
890
890
|
Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`, `roam_complete`, `roam_complexity_report`, `roam_context`, `roam_dead_code`, `roam_deps`, `roam_diagnose`, `roam_diagnose_issue`, `roam_diff`, `roam_expand_toolset`, `roam_explore`, `roam_file_info`, `roam_health`, `roam_impact`, `roam_pr_risk`, `roam_preflight`, `roam_prepare_change`, `roam_review_change`, `roam_search_symbol`, `roam_syntax_check`, `roam_trace`, `roam_understand`, `roam_uses`.
|
|
891
891
|
|
|
892
892
|
<details>
|
|
893
|
-
<summary><strong>MCP tool list (all
|
|
893
|
+
<summary><strong>MCP tool list (all 116)</strong></summary>
|
|
894
894
|
|
|
895
895
|
| Tool | Description |
|
|
896
896
|
|------|-------------|
|
|
@@ -910,6 +910,10 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
|
|
|
910
910
|
| `roam_oracle_is_reachable_from_entry` | Boolean oracle: can BFS reach this symbol from any entry-point? |
|
|
911
911
|
| `roam_oracle_is_clone_of` | Boolean oracle: does this symbol participate in a persisted clone cluster? |
|
|
912
912
|
| `roam_taint_classify` | LLM-augmented taint classification (IDOR/AUTHZ/SQLI/...) via MCP sampling |
|
|
913
|
+
| `roam_taint` | Static taint analysis — graph-reach BFS with OpenVEX-correct findings |
|
|
914
|
+
| `roam_sbom` | CycloneDX 1.7 / SPDX 2.3 SBOM emit with optional AIBOM extension (EU AI Act) |
|
|
915
|
+
| `roam_cga_emit` | Emit a Code Graph Attestation (in-toto v1) with optional cosign signing |
|
|
916
|
+
| `roam_cga_verify` | Verify a CGA statement — re-derives Merkle + edge digest, checks cosign signature |
|
|
913
917
|
| `roam_trace` | Dependency path between two symbols |
|
|
914
918
|
| `roam_impact` | Blast radius of changing a symbol |
|
|
915
919
|
| `roam_file_info` | File skeleton with all definitions |
|
|
@@ -1521,7 +1525,7 @@ roam-code/
|
|
|
1521
1525
|
├── src/roam/
|
|
1522
1526
|
│ ├── __init__.py # Version (from pyproject.toml)
|
|
1523
1527
|
│ ├── cli.py # Click CLI (150 commands)
|
|
1524
|
-
│ ├── mcp_server.py # MCP server (
|
|
1528
|
+
│ ├── mcp_server.py # MCP server (116 tools, 10 resources, 5 prompts)
|
|
1525
1529
|
│ ├── db/
|
|
1526
1530
|
│ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
|
|
1527
1531
|
│ │ ├── schema.py # Tables, indexes, migrations
|
|
@@ -1615,7 +1619,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
|
|
|
1615
1619
|
### Shipped
|
|
1616
1620
|
|
|
1617
1621
|
- [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
|
|
1618
|
-
- [x] Full command and MCP inventory parity in docs: 150 CLI commands and
|
|
1622
|
+
- [x] Full command and MCP inventory parity in docs: 150 CLI commands and 116 MCP tools.
|
|
1619
1623
|
- [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
|
|
1620
1624
|
- [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
|
|
1621
1625
|
- [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "roam-code"
|
|
7
|
-
version = "12.
|
|
7
|
+
version = "12.3.0"
|
|
8
8
|
description = "Instant codebase comprehension for AI coding agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -32,7 +32,11 @@ classifiers = [
|
|
|
32
32
|
dependencies = [
|
|
33
33
|
"click>=8.0",
|
|
34
34
|
"tree-sitter>=0.23",
|
|
35
|
-
|
|
35
|
+
# Pinned upper bound: 1.6.3's cp312 wheel ships a manylinux_2_34
|
|
36
|
+
# tarball that fails to register the ``tree_sitter_language_pack``
|
|
37
|
+
# module post-install (CI run 25217131296). 1.6.2 (cp310-abi3) works
|
|
38
|
+
# cleanly across 3.9–3.13.
|
|
39
|
+
"tree-sitter-language-pack>=0.6,<1.6.3",
|
|
36
40
|
"networkx>=3.0",
|
|
37
41
|
]
|
|
38
42
|
|
|
@@ -55,9 +59,42 @@ semantic = [
|
|
|
55
59
|
"onnxruntime>=1.16",
|
|
56
60
|
"tokenizers>=0.15",
|
|
57
61
|
]
|
|
62
|
+
leiden = [
|
|
63
|
+
# Strictly better community detection than Louvain (no badly-connected
|
|
64
|
+
# communities). Auto-detected at runtime; falls back to seeded Louvain
|
|
65
|
+
# when these aren't installed.
|
|
66
|
+
"igraph>=0.11",
|
|
67
|
+
"leidenalg>=0.10",
|
|
68
|
+
]
|
|
69
|
+
graph-fast = [
|
|
70
|
+
# rustworkx is a Rust-backed drop-in for many NetworkX algorithms;
|
|
71
|
+
# 3-100× speedup at >250k nodes per the v12.2 architecture review.
|
|
72
|
+
# Auto-detected via ``ROAM_GRAPH_BACKEND=rustworkx``.
|
|
73
|
+
"rustworkx>=0.14",
|
|
74
|
+
]
|
|
75
|
+
sbom = [
|
|
76
|
+
# CycloneDX 1.7 SBOM emit (with AIBOM extension) for `roam sbom`.
|
|
77
|
+
# Falls back to in-tree minimal emitter when not installed.
|
|
78
|
+
"cyclonedx-python-lib>=8.0",
|
|
79
|
+
]
|
|
80
|
+
learned = [
|
|
81
|
+
# LightGBM LambdaMART distillation for `roam retrieve --rerank learned`.
|
|
82
|
+
# Optional — current `--rerank fast` blend stays the default.
|
|
83
|
+
"lightgbm>=4.0",
|
|
84
|
+
]
|
|
58
85
|
dev = [
|
|
59
86
|
"pytest>=7.0",
|
|
60
87
|
"pytest-xdist>=3.0",
|
|
88
|
+
# pytest-asyncio is required by tests/test_taint_classifier.py — those
|
|
89
|
+
# tests use ``@pytest.mark.asyncio`` to verify the MCP-sampling-based
|
|
90
|
+
# taint classifier under a controlled async loop.
|
|
91
|
+
"pytest-asyncio>=0.23",
|
|
92
|
+
# scipy is required by ``nx.pagerank`` on networkx 3.x; without it,
|
|
93
|
+
# the personalized-pagerank tests exercise the degree-based fallback
|
|
94
|
+
# which doesn't honour ``alpha`` and trivially fails the
|
|
95
|
+
# alpha-override / chain-propagation invariants. Production users
|
|
96
|
+
# without scipy still get the (less accurate but correct) fallback.
|
|
97
|
+
"scipy>=1.11",
|
|
61
98
|
"ruff>=0.4",
|
|
62
99
|
"build>=1.0",
|
|
63
100
|
"twine>=5.0",
|
|
@@ -69,10 +106,17 @@ where = ["src"]
|
|
|
69
106
|
[tool.pytest.ini_options]
|
|
70
107
|
testpaths = ["tests"]
|
|
71
108
|
addopts = "-q --tb=short"
|
|
109
|
+
# v12.2: pytest-asyncio strict-mode + auto fixture loop scope. Avoids the
|
|
110
|
+
# 11 PytestUnknownMarkWarning warnings on `@pytest.mark.asyncio` in
|
|
111
|
+
# test_taint_classifier.py when pytest-asyncio is installed (it ships
|
|
112
|
+
# under the `[dev]` extra).
|
|
113
|
+
asyncio_mode = "strict"
|
|
114
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
72
115
|
markers = [
|
|
73
116
|
"smoke: fast, high-signal tests for local iteration",
|
|
74
117
|
"core: broader local suite for pre-push checks",
|
|
75
118
|
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
119
|
+
"asyncio: marks async tests requiring pytest-asyncio (skip when missing)",
|
|
76
120
|
]
|
|
77
121
|
|
|
78
122
|
[tool.ruff]
|
|
@@ -31,6 +31,11 @@ from typing import Any
|
|
|
31
31
|
from roam.security.taint_engine import OPENVEX_JUSTIFICATIONS, OPENVEX_STATUSES
|
|
32
32
|
|
|
33
33
|
PREDICATE_TYPE = "https://roam-code.dev/CodeGraph/v1"
|
|
34
|
+
# v12.2: fused CodeGraph + AIBOM predicate. Owns the "structurally bound
|
|
35
|
+
# AI authorship for tamper-evident codebases" lane that SLSA + SPDX +
|
|
36
|
+
# CycloneDX 1.7 + OpenVEX leave gapped. Reference impl candidate for
|
|
37
|
+
# the in-toto attestation registry.
|
|
38
|
+
PREDICATE_TYPE_AIBOM = "https://roam-code.dev/CodeGraph-AIBOM/v1"
|
|
34
39
|
STATEMENT_TYPE = "https://in-toto.io/Statement/v1"
|
|
35
40
|
SCHEMA_VERSION = "1"
|
|
36
41
|
|
|
@@ -218,6 +223,7 @@ def build_cga_statement(
|
|
|
218
223
|
project_root: Path,
|
|
219
224
|
tool_version: str | None = None,
|
|
220
225
|
taint_findings: list | None = None,
|
|
226
|
+
include_aibom: bool = False,
|
|
221
227
|
) -> dict[str, Any]:
|
|
222
228
|
"""Build the full in-toto v1 Statement wrapping the CGA predicate.
|
|
223
229
|
|
|
@@ -225,9 +231,15 @@ def build_cga_statement(
|
|
|
225
231
|
{
|
|
226
232
|
"_type": "https://in-toto.io/Statement/v1",
|
|
227
233
|
"predicateType": "https://roam-code.dev/CodeGraph/v1",
|
|
234
|
+
# → CodeGraph-AIBOM/v1 when include_aibom=True
|
|
228
235
|
"subject": [{"name": "...", "digest": {...}}],
|
|
229
236
|
"predicate": {...}
|
|
230
237
|
}
|
|
238
|
+
|
|
239
|
+
With ``include_aibom=True``, the predicate type promotes to
|
|
240
|
+
``CodeGraph-AIBOM/v1`` and embeds an ``aibom`` block binding
|
|
241
|
+
AI-authored commits to the indexed symbols they touched. Required
|
|
242
|
+
for EU AI Act Art. 50 disclosure (effective 2026-08-02).
|
|
231
243
|
"""
|
|
232
244
|
sha = _git_commit_sha(project_root) or "unknown"
|
|
233
245
|
remote = _git_remote_url(project_root)
|
|
@@ -236,16 +248,26 @@ def build_cga_statement(
|
|
|
236
248
|
"name": subject_name,
|
|
237
249
|
"digest": {"git_commit_sha1": sha},
|
|
238
250
|
}
|
|
251
|
+
predicate = build_cga_predicate(
|
|
252
|
+
conn,
|
|
253
|
+
project_root=project_root,
|
|
254
|
+
tool_version=tool_version,
|
|
255
|
+
taint_findings=taint_findings,
|
|
256
|
+
)
|
|
257
|
+
predicate_type = PREDICATE_TYPE
|
|
258
|
+
if include_aibom:
|
|
259
|
+
try:
|
|
260
|
+
from roam.security.aibom_extension import build_aibom_block
|
|
261
|
+
|
|
262
|
+
predicate["aibom"] = build_aibom_block(project_root, conn)
|
|
263
|
+
predicate_type = PREDICATE_TYPE_AIBOM
|
|
264
|
+
except Exception as exc:
|
|
265
|
+
predicate["aibom_error"] = str(exc)
|
|
239
266
|
return {
|
|
240
267
|
"_type": STATEMENT_TYPE,
|
|
241
|
-
"predicateType":
|
|
268
|
+
"predicateType": predicate_type,
|
|
242
269
|
"subject": [subject],
|
|
243
|
-
"predicate":
|
|
244
|
-
conn,
|
|
245
|
-
project_root=project_root,
|
|
246
|
-
tool_version=tool_version,
|
|
247
|
-
taint_findings=taint_findings,
|
|
248
|
-
),
|
|
270
|
+
"predicate": predicate,
|
|
249
271
|
}
|
|
250
272
|
|
|
251
273
|
|
|
@@ -270,8 +292,11 @@ def verify_cga_statement(
|
|
|
270
292
|
errors: list[str] = []
|
|
271
293
|
if statement.get("_type") != STATEMENT_TYPE:
|
|
272
294
|
errors.append(f"_type mismatch: got {statement.get('_type')!r}, expected {STATEMENT_TYPE!r}")
|
|
273
|
-
|
|
274
|
-
|
|
295
|
+
accepted_types = (PREDICATE_TYPE, PREDICATE_TYPE_AIBOM)
|
|
296
|
+
if statement.get("predicateType") not in accepted_types:
|
|
297
|
+
errors.append(
|
|
298
|
+
f"predicateType mismatch: got {statement.get('predicateType')!r}, expected one of {accepted_types!r}"
|
|
299
|
+
)
|
|
275
300
|
predicate = statement.get("predicate") or {}
|
|
276
301
|
if not isinstance(predicate, dict):
|
|
277
302
|
return False, errors + ["predicate is not a JSON object"]
|
|
@@ -110,9 +110,25 @@ def _default_output_path(project_root: Path, statement: dict) -> Path:
|
|
|
110
110
|
"browser flow."
|
|
111
111
|
),
|
|
112
112
|
)
|
|
113
|
+
@click.option(
|
|
114
|
+
"--aibom",
|
|
115
|
+
is_flag=True,
|
|
116
|
+
help=(
|
|
117
|
+
"Promote the predicate to ``CodeGraph-AIBOM/v1`` and embed an "
|
|
118
|
+
"AIBOM block binding AI-authored commits to the indexed symbols "
|
|
119
|
+
"they touched. Required for EU AI Act Art. 50 disclosure (effective "
|
|
120
|
+
"2026-08-02) and the GPAI Code of Practice provenance mandate. "
|
|
121
|
+
"Reference impl candidate for the in-toto attestation registry."
|
|
122
|
+
),
|
|
123
|
+
)
|
|
113
124
|
@click.pass_context
|
|
114
|
-
def cga_emit(ctx, output_path, no_write, include_taint, taint_rules_dir, sign, key_path, keyless):
|
|
115
|
-
"""Emit a Code Graph Attestation (in-toto v1, optionally cosign-signed).
|
|
125
|
+
def cga_emit(ctx, output_path, no_write, include_taint, taint_rules_dir, sign, key_path, keyless, aibom):
|
|
126
|
+
"""Emit a Code Graph Attestation (in-toto v1, optionally cosign-signed).
|
|
127
|
+
|
|
128
|
+
With ``--aibom`` the predicate type promotes to
|
|
129
|
+
``roam-code.dev/CodeGraph-AIBOM/v1`` and the predicate gains an
|
|
130
|
+
``aibom`` block binding AI-authored commits to indexed symbols.
|
|
131
|
+
"""
|
|
116
132
|
json_mode = ctx.obj.get("json") if ctx.obj else False
|
|
117
133
|
token_budget = ctx.obj.get("budget", 0) if ctx.obj else 0
|
|
118
134
|
|
|
@@ -137,6 +153,7 @@ def cga_emit(ctx, output_path, no_write, include_taint, taint_rules_dir, sign, k
|
|
|
137
153
|
conn,
|
|
138
154
|
project_root=project_root,
|
|
139
155
|
taint_findings=taint_findings,
|
|
156
|
+
include_aibom=aibom,
|
|
140
157
|
)
|
|
141
158
|
|
|
142
159
|
canonical = serialize_statement(statement)
|
|
@@ -198,7 +215,7 @@ def cga_emit(ctx, output_path, no_write, include_taint, taint_rules_dir, sign, k
|
|
|
198
215
|
"edge_bundle_digest": pred["edge_bundle_digest"],
|
|
199
216
|
"symbol_count": pred["symbol_count"],
|
|
200
217
|
"edge_count": pred["edge_count"],
|
|
201
|
-
"predicate_type": PREDICATE_TYPE,
|
|
218
|
+
"predicate_type": statement.get("predicateType", PREDICATE_TYPE),
|
|
202
219
|
"statement_type": STATEMENT_TYPE,
|
|
203
220
|
"written_to": written_to,
|
|
204
221
|
"signed": bool(sign_result and sign_result.get("signed")),
|
|
@@ -212,7 +229,7 @@ def cga_emit(ctx, output_path, no_write, include_taint, taint_rules_dir, sign, k
|
|
|
212
229
|
return
|
|
213
230
|
|
|
214
231
|
click.echo(f"VERDICT: {verdict}")
|
|
215
|
-
click.echo(f"Predicate type: {PREDICATE_TYPE}")
|
|
232
|
+
click.echo(f"Predicate type: {statement.get('predicateType', PREDICATE_TYPE)}")
|
|
216
233
|
click.echo(f"Statement type: {STATEMENT_TYPE}")
|
|
217
234
|
click.echo(f"Languages: {', '.join(pred['languages']) or '(none)'}")
|
|
218
235
|
if written_to:
|
|
@@ -31,6 +31,57 @@ from roam.critique.checks import (
|
|
|
31
31
|
from roam.db.connection import open_db
|
|
32
32
|
from roam.output.formatter import json_envelope, to_json
|
|
33
33
|
|
|
34
|
+
# Hot-path → bench command. When a diff touches any of these path
|
|
35
|
+
# prefixes, the default critique rules can pass while the change
|
|
36
|
+
# materially alters retrieval/scoring/graph algorithms. The hint
|
|
37
|
+
# names the bench so the user includes it in their verification
|
|
38
|
+
# loop. Order matters: first match wins (most specific first).
|
|
39
|
+
_BENCH_RELEVANCE_RULES = [
|
|
40
|
+
(
|
|
41
|
+
("src/roam/retrieve/", "src/roam/eval/"),
|
|
42
|
+
"pytest tests/test_retrieve_cross_repo.py + roam eval-retrieve --tasks bench/retrieve/roam_self.jsonl",
|
|
43
|
+
),
|
|
44
|
+
(
|
|
45
|
+
("src/roam/graph/pagerank.py", "src/roam/graph/clusters.py"),
|
|
46
|
+
"pytest tests/test_personalized_pagerank.py tests/test_fallback_contracts.py",
|
|
47
|
+
),
|
|
48
|
+
(("src/roam/graph/",), "pytest tests/ -k graph_ -m 'not slow'"),
|
|
49
|
+
(
|
|
50
|
+
("src/roam/languages/", "src/roam/index/parser.py"),
|
|
51
|
+
"pytest tests/test_languages.py tests/test_extractor_grammar_drift.py",
|
|
52
|
+
),
|
|
53
|
+
(("src/roam/security/taint",), "pytest tests/test_taint_analysis.py tests/test_taint_classifier.py"),
|
|
54
|
+
(("src/roam/critique/",), "pytest tests/test_critique.py"),
|
|
55
|
+
(
|
|
56
|
+
("src/roam/commands/cmd_oracle.py", "src/roam/commands/cmd_health.py"),
|
|
57
|
+
"pytest tests/test_oracle.py tests/test_commands_health.py",
|
|
58
|
+
),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _bench_relevance_hint(regions) -> str:
|
|
63
|
+
"""Return a one-line bench/test suggestion when the diff touches a
|
|
64
|
+
structurally-significant path. ``regions`` is the
|
|
65
|
+
``critique.checks.ChangedRegion`` list from the diff parser; we
|
|
66
|
+
look at each region's file path and pick the first matching rule.
|
|
67
|
+
"""
|
|
68
|
+
paths = []
|
|
69
|
+
for r in regions:
|
|
70
|
+
path = getattr(r, "file_path", None) or getattr(r, "file", None) or ""
|
|
71
|
+
if path:
|
|
72
|
+
paths.append(path.replace("\\", "/"))
|
|
73
|
+
if not paths:
|
|
74
|
+
return ""
|
|
75
|
+
seen: set[str] = set()
|
|
76
|
+
for path in paths:
|
|
77
|
+
for prefixes, hint in _BENCH_RELEVANCE_RULES:
|
|
78
|
+
if any(path.startswith(p) or p in path for p in prefixes):
|
|
79
|
+
if hint in seen:
|
|
80
|
+
return hint
|
|
81
|
+
seen.add(hint)
|
|
82
|
+
return hint
|
|
83
|
+
return ""
|
|
84
|
+
|
|
34
85
|
|
|
35
86
|
@click.command()
|
|
36
87
|
@click.option(
|
|
@@ -163,5 +214,17 @@ def critique(ctx, input_path, high_callers, intent_text):
|
|
|
163
214
|
click.echo(f" {line}")
|
|
164
215
|
click.echo()
|
|
165
216
|
|
|
217
|
+
# Bench-relevance hint (dogfood notes 2026-05-01): when the diff
|
|
218
|
+
# touches files in the retrieve / graph / catalog hot path, the
|
|
219
|
+
# default rule set ("clones not edited", "blast radius") can
|
|
220
|
+
# legitimately say "no concerns" while the change quietly
|
|
221
|
+
# alters the structural-rerank scoring formula. Surfacing the
|
|
222
|
+
# bench command makes the verifier conversation include the
|
|
223
|
+
# one validation that actually exercises the modified code.
|
|
224
|
+
bench_hint = _bench_relevance_hint(regions)
|
|
225
|
+
if bench_hint:
|
|
226
|
+
click.echo()
|
|
227
|
+
click.echo(f"BENCH HINT: {bench_hint}")
|
|
228
|
+
|
|
166
229
|
if result["severity_breakdown"].get("high", 0) > 0:
|
|
167
230
|
ctx.exit(5)
|
|
@@ -358,6 +358,19 @@ def _group_dead(dead_items, by):
|
|
|
358
358
|
# ---------------------------------------------------------------------------
|
|
359
359
|
|
|
360
360
|
|
|
361
|
+
_TOOLING_PATH_HINTS = ("/dev/", "/benchmarks/", "/.github/", "\\dev\\", "\\benchmarks\\", "\\.github\\")
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def _is_tooling_path(path: str) -> bool:
|
|
365
|
+
"""Same hint set as cmd_fan / cmd_smells. Excluded from dead-code
|
|
366
|
+
headline by default (dogfood notes 2026-05-01) — CI scripts are
|
|
367
|
+
expected to have unreferenced helper functions."""
|
|
368
|
+
if not path:
|
|
369
|
+
return False
|
|
370
|
+
p = "/" + path.replace("\\", "/")
|
|
371
|
+
return any(hint.replace("\\", "/") in p for hint in _TOOLING_PATH_HINTS)
|
|
372
|
+
|
|
373
|
+
|
|
361
374
|
def _analyze_dead(conn):
|
|
362
375
|
"""Run the full dead code analysis.
|
|
363
376
|
|
|
@@ -366,6 +379,9 @@ def _analyze_dead(conn):
|
|
|
366
379
|
rows = conn.execute(UNREFERENCED_EXPORTS).fetchall()
|
|
367
380
|
# Exclude test files — their symbols are discovered by pytest, not imported
|
|
368
381
|
rows = [r for r in rows if not _is_test_path(r["file_path"])]
|
|
382
|
+
# Exclude tooling/CI/benchmarks/dev — same default-exclusion that
|
|
383
|
+
# ``cmd_smells`` and ``cmd_fan`` apply.
|
|
384
|
+
rows = [r for r in rows if not _is_tooling_path(r["file_path"])]
|
|
369
385
|
if not rows:
|
|
370
386
|
return [], [], set()
|
|
371
387
|
|
|
@@ -315,6 +315,15 @@ def diagnose(ctx, name, depth):
|
|
|
315
315
|
|
|
316
316
|
# Text output
|
|
317
317
|
click.echo(f"VERDICT: {verdict}")
|
|
318
|
+
# Index-staleness hint (dogfood notes 2026-05-01): when index
|
|
319
|
+
# is older than HEAD, commit_count / churn columns are
|
|
320
|
+
# unreliable — surface this so the user knows whether to trust
|
|
321
|
+
# the numbers or re-index.
|
|
322
|
+
from roam.commands.resolve import index_staleness_hint as _stale_hint
|
|
323
|
+
|
|
324
|
+
_stale = _stale_hint()
|
|
325
|
+
if _stale:
|
|
326
|
+
click.echo(f"NOTE: {_stale}")
|
|
318
327
|
sym_name = sym["qualified_name"] or sym["name"]
|
|
319
328
|
click.echo(f"Diagnose: {sym_name}")
|
|
320
329
|
click.echo(f" {loc(target_metrics['file_path'], sym['line_start'])}")
|
|
@@ -103,7 +103,13 @@ _NAME_PATTERNS = [
|
|
|
103
103
|
("Scheduled", re.compile(r"cron|schedule|periodic|tick", re.IGNORECASE)),
|
|
104
104
|
("Message", re.compile(r"consume|subscriber|on_message|process_message", re.IGNORECASE)),
|
|
105
105
|
("CLI", re.compile(r"^cmd_|_command$|_cmd$", re.IGNORECASE)),
|
|
106
|
-
|
|
106
|
+
# HTTP name patterns: only the strong endpoint/controller suffixes.
|
|
107
|
+
# ``_view$`` and ``_handler$`` matched too broadly — dogfood notes
|
|
108
|
+
# 2026-05-01 caught ``_extract_create_view`` (a SQL parser method)
|
|
109
|
+
# and ``error_handler`` (signal handler) being classified as HTTP
|
|
110
|
+
# routes. The decorator pattern above already catches genuine
|
|
111
|
+
# ``@app.route`` etc. — name fallback can be conservative.
|
|
112
|
+
("HTTP", re.compile(r"_endpoint$|_controller$", re.IGNORECASE)),
|
|
107
113
|
]
|
|
108
114
|
|
|
109
115
|
|
|
@@ -107,12 +107,43 @@ _FRAMEWORK_NAMES = frozenset(
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
_TOOLING_PATH_HINTS = ("/dev/", "/benchmarks/", "/.github/", "\\dev\\", "\\benchmarks\\", "\\.github\\")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _is_tooling_path(path: str) -> bool:
|
|
114
|
+
"""Return True for paths that belong to tooling/CI/benchmarks/dev.
|
|
115
|
+
|
|
116
|
+
Default-excluded from headline metrics so first-time users aren't
|
|
117
|
+
dominated by ``pr-comment.js`` and ``roam-bench.py`` rows.
|
|
118
|
+
Matches the hint set used by ``cmd_smells._file_role_lookup``.
|
|
119
|
+
"""
|
|
120
|
+
if not path:
|
|
121
|
+
return False
|
|
122
|
+
p = "/" + path.replace("\\", "/")
|
|
123
|
+
return any(hint.replace("\\", "/") in p for hint in _TOOLING_PATH_HINTS)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _filter_tooling_rows(rows):
|
|
127
|
+
"""Filter out rows whose ``file_path`` is in a tooling location."""
|
|
128
|
+
return [r for r in rows if not _is_tooling_path(r["file_path"] or "")]
|
|
129
|
+
|
|
130
|
+
|
|
110
131
|
@click.command()
|
|
111
132
|
@click.argument("mode", default="symbol", type=click.Choice(["symbol", "file"]))
|
|
112
133
|
@click.option("-n", "count", default=20, help="Number of items to show")
|
|
113
134
|
@click.option("--no-framework", is_flag=True, help="Filter out framework/boilerplate symbols")
|
|
135
|
+
@click.option(
|
|
136
|
+
"--include-tooling",
|
|
137
|
+
is_flag=True,
|
|
138
|
+
default=False,
|
|
139
|
+
help=(
|
|
140
|
+
"Include CI scripts, dev tooling, build, and generated files. "
|
|
141
|
+
"Excluded by default — high fan-in in dev/.github/benchmarks "
|
|
142
|
+
"is expected and dominates the headline (dogfood notes 2026-05-01)."
|
|
143
|
+
),
|
|
144
|
+
)
|
|
114
145
|
@click.pass_context
|
|
115
|
-
def fan(ctx, mode, count, no_framework):
|
|
146
|
+
def fan(ctx, mode, count, no_framework, include_tooling):
|
|
116
147
|
"""Show fan-in/fan-out: most connected symbols or files.
|
|
117
148
|
|
|
118
149
|
Unlike ``coupling`` (which measures temporal co-change frequency), this
|
|
@@ -124,6 +155,10 @@ def fan(ctx, mode, count, no_framework):
|
|
|
124
155
|
ensure_index()
|
|
125
156
|
|
|
126
157
|
with open_db(readonly=True) as conn:
|
|
158
|
+
# Pull more rows than ``count`` when filtering, so the displayed
|
|
159
|
+
# top-N still has ``count`` entries after exclusions. 5x is a
|
|
160
|
+
# comfortable safety factor for typical tooling shares.
|
|
161
|
+
fetch_limit = count * 5 if not include_tooling else count
|
|
127
162
|
if mode == "symbol":
|
|
128
163
|
rows = conn.execute(
|
|
129
164
|
"""
|
|
@@ -138,9 +173,13 @@ def fan(ctx, mode, count, no_framework):
|
|
|
138
173
|
ORDER BY total DESC
|
|
139
174
|
LIMIT ?
|
|
140
175
|
""",
|
|
141
|
-
(
|
|
176
|
+
(fetch_limit,),
|
|
142
177
|
).fetchall()
|
|
143
178
|
|
|
179
|
+
if not include_tooling:
|
|
180
|
+
rows = _filter_tooling_rows(rows)
|
|
181
|
+
rows = rows[:count]
|
|
182
|
+
|
|
144
183
|
if no_framework:
|
|
145
184
|
rows = [r for r in rows if r["name"] not in _FRAMEWORK_NAMES]
|
|
146
185
|
|