roam-code 12.18__tar.gz → 12.19__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.18/src/roam_code.egg-info → roam_code-12.19}/PKG-INFO +13 -7
- {roam_code-12.18 → roam_code-12.19}/README.md +12 -6
- {roam_code-12.18 → roam_code-12.19}/pyproject.toml +1 -1
- {roam_code-12.18 → roam_code-12.19}/src/roam/cli.py +2 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_adversarial.py +35 -35
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_affected.py +10 -4
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_agent_export.py +39 -23
- roam_code-12.19/src/roam/commands/cmd_audit.py +169 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_complexity.py +41 -7
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_config.py +13 -12
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_coverage_gaps.py +23 -8
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_describe.py +32 -16
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_impact.py +71 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_metrics.py +48 -24
- roam_code-12.19/src/roam/commands/cmd_orphan_imports.py +435 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_safe_zones.py +14 -1
- {roam_code-12.18 → roam_code-12.19}/src/roam/competitor_site_data.py +2 -2
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp-server-card.json +4 -4
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/sampling.py +10 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_server.py +99 -0
- roam_code-12.19/src/roam/observability.py +58 -0
- {roam_code-12.18 → roam_code-12.19/src/roam_code.egg-info}/PKG-INFO +13 -7
- {roam_code-12.18 → roam_code-12.19}/src/roam_code.egg-info/SOURCES.txt +3 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_defer_loading.py +6 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_mcp_server.py +8 -2
- {roam_code-12.18 → roam_code-12.19}/tests/test_v1216_passes_41_50.py +9 -5
- roam_code-12.19/tests/test_v1219_passes_91_100.py +174 -0
- roam_code-12.18/src/roam/commands/cmd_orphan_imports.py +0 -175
- {roam_code-12.18 → roam_code-12.19}/LICENSE +0 -0
- {roam_code-12.18 → roam_code-12.19}/setup.cfg +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/__main__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/analysis/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/analysis/effects.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/analysis/taint.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/api.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/ask/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/ask/classifier.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/ask/recipes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/ask/runner.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/ask/workflow.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/attest/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/attest/cga.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/base.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/bridge_config.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/bridge_django.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/bridge_protobuf.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/bridge_rest_api.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/bridge_salesforce.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/bridge_template.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/bridges/registry.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/catalog/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/catalog/detectors.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/catalog/fixes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/catalog/python_idioms.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/catalog/smells.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/catalog/tasks.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/changed_files.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_adrs.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_affected_tests.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_agent_context.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_agent_plan.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_ai_ratio.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_ai_readiness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_alerts.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_annotate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_api.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_api_changes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_api_drift.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_ask.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_attest.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_auth_gaps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_bisect.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_breaking.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_budget.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_bus_factor.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_capsule.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_cga.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_changelog.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_check_rules.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_ci_setup.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_clean.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_clones.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_closure.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_clusters.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_codeowners.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_congestion.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_context.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_conventions.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_coupling.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_critique.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_cut.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_dark_matter.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_dashboard.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_dead.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_debt.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_deps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_dev_profile.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_diagnose.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_diff.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_disambiguate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_doc_staleness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_docs_coverage.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_doctor.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_drift.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_duplicates.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_effects.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_endpoints.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_entry_points.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_eval_retrieve.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_exit_codes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_fan.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_file.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_fingerprint.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_fitness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_flag_dead.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_fleet.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_fn_coupling.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_forecast.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_graph_export.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_graph_stats.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_grep.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_guard.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_health.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_help_search.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_hooks.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_hotspots.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_hover.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_index.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_index_bundle.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_index_stats.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_ingest_trace.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_init.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_intent.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_invariants.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_layers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_map.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_math.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_mcp_setup.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_mcp_status.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_migration_safety.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_minimap.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_missing_index.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_module.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_mutate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_n1.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_oracle.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_orchestrate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_orphan_routes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_over_fetch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_owner.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_partition.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_path_coverage.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_patterns.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_plan.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_plan_refactor.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_plugins.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_pr_diff.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_pr_prep.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_pr_risk.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_pre_commit.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_preflight.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_py_modern.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_py_types.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_pytest_fixtures.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_recipes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_recommend.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_relate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_report.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_reset.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_retrieve.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_risk.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_rules.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_safe_delete.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_sbom.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_schema.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_search.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_search_semantic.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_secrets.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_semantic_diff.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_simulate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_simulate_departure.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_sketch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_smells.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_spectral.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_split.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_stats.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_supply_chain.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_symbol.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_syntax_check.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_taint.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_telemetry.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_test_gaps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_test_impact.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_test_pyramid.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_test_scaffold.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_testmap.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_timeline.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_tour.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_trace.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_trends.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_triage.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_understand.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_uses.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_verify.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_verify_imports.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_version.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_vibe_check.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_visualize.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_vuln_map.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_vuln_reach.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_vulns.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_watch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_weather.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_why.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_why_fail.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_workflow.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_ws.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/cmd_xlang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/codeowners_helpers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/context_helpers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/gate_presets.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/graph_helpers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/metrics_history.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/next_steps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/resolve.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/commands/suppression.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/config.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/coverage_reports.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/critique/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/critique/aggregator.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/critique/checks.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/db/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/db/connection.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/db/queries.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/db/schema.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/eval/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/eval/harness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/exit_codes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/fleet/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/fleet/adapters.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/fleet/manifest.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/git_utils.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/anomaly.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/builder.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/clone_detect.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/clusters.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/cycles.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/dark_matter.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/diff.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/fingerprint.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/layers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/pagerank.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/partition.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/pathfinding.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/propagation.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/simulate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/spectral.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/graph/stats.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/complexity.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/discovery.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/django_post.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/file_roles.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/git_stats.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/gitignore.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/incremental.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/indexer.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/parser.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/pytest_fixtures.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/registry_dispatch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/relations.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/symbols.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/index/test_conventions.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/apex_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/aura_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/base.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/c_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/csharp_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/extractor_schema.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/extractors/kotlin.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/foxpro_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/generic_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/go_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/hcl_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/java_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/javascript_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/kotlin_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/php_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/python_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/query_engine.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/registry.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/ruby_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/rust_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/scala_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/sfxml_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/sql_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/swift_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/typescript_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/visualforce_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/languages/yaml_lang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/completions.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/concurrency.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/progress.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/session.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/mcp_extras/watcher.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/confidence.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/errors.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/file_role_hints.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/formatter.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/framework_filter.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/mermaid.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/project_shape.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/sarif.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/output/schema_registry.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/plugins.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/refactor/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/refactor/codegen.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/refactor/transforms.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/retrieve/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/retrieve/learned_ranker.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/retrieve/pipeline.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/retrieve/rerank.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/retrieve/seeds.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/retrieve/semantic.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/rules/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/rules/ast_match.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/rules/builtin.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/rules/dataflow.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/rules/engine.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/daemon.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/graph_backend.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/hotspots.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/lock_modes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/lockmgr.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/runtime/trace_ingest.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/search/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/search/framework_packs.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/search/index_embeddings.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/search/onnx_embeddings.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/search/tfidf.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/aibom_extension.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_classifier.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_engine.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/api_error_leak.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/java_fileupload_path_traversal.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/js_insecure_jwt_decode.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/js_localstorage_secrets.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/js_prototype_pollution.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/js_ssrf.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/js_xss.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/python_basic.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/python_deserialization.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/python_path_traversal.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/python_socketio_remote_source.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/python_sqli.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/python_urllib_open_redirect.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/taint_rules/vue_v_html.yaml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/vuln_reach.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/security/vuln_store.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/surface_counts.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/telemetry.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/templates/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/templates/ci/Jenkinsfile +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/templates/ci/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/templates/ci/azure-pipelines.yml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/templates/ci/bitbucket-pipelines.yml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/templates/ci/gitlab-ci.yml +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/workspace/__init__.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/workspace/aggregator.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/workspace/api_scanner.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/workspace/config.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam/workspace/db.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam_code.egg-info/dependency_links.txt +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam_code.egg-info/entry_points.txt +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam_code.egg-info/requires.txt +0 -0
- {roam_code-12.18 → roam_code-12.19}/src/roam_code.egg-info/top_level.txt +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_adrs.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_adversarial.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_affected.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_agent_export.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_agent_mode.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_agent_plan_context.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ai_ratio.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ai_readiness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_alerts_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_annotations.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_anomaly.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_api_changes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_api_drift.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ask.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_attest.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_auth_gaps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_backend_fixes_round2.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_backend_fixes_round3.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_basic.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_batch_mcp.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_bisect.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_bridge_django.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_bridges.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_bridges_extended.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_budget.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_budget_flag.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_budget_phase2.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_bus_factor.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_capsule.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_cga.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_check_rules.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ci_gate_eval.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ci_sarif_guard.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ci_setup.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_clones.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_closure.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_codeowners.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_commands_architecture.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_commands_exploration.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_commands_health.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_commands_refactoring.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_commands_workflow.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_competitor_site_data.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_comprehensive.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_config.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_congestion.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_context_propagation.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_conventions_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_coverage_gaps_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_coverage_ingestion.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_critique.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_cut.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_dark_matter.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_dark_matter_helpers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_dashboard.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_dataflow_dead.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_dead_aging.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_demo_gif_asset.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_describe.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_detail_flag_hints.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_detector_precision.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_deterministic_output.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_dev_profile.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_difficulty_scoring.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_doc_consistency.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_doc_staleness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_docker_assets.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_docs_coverage.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_docs_site_quality.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_doctor.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_drift.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_drift_by_team.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_duplicates.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_effects.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_effects_propagation.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_endpoints.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_entry_points_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_eval_retrieve.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_except_pass_narrow.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_exclude_patterns.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_exit_codes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_extractor_grammar_drift.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_fallback_contracts.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_file_roles.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_fingerprint.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_fixes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_flag_dead.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_fleet.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_fn_coupling.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_forecast.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_formatters.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_foxpro.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_framework_detection.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_gate_presets.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_git_utils.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_guard.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_health_gate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_hooks.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_hotspots.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_hover.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_index.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_index_bundle.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_init_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_install_check.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_intent.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_invariants.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_json_contracts.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_json_error_envelope.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_kotlin_swift_extractors.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_language_corpus.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_languages.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_library_api.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_math.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_math_tips.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_mcp_extras.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_mcp_setup.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_mermaid.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_metrics_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_migration_safety.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_minimap.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_missing_index.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_mutate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_n1.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_next_steps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_onboard.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_oracle.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_orchestrate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_orphan_routes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_oss_bench_harness.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_over_fetch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_pagerank_truncation.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_partition.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_path_coverage.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_patterns_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_performance.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_personalized_pagerank.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_plan.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_plugin_discovery.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_pr_comment_script.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_pr_diff.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_pr_risk_author.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_progress.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_progressive_disclosure.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_properties.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_pytest_fixtures.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_python_extractor_v2.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_python_idioms_e2e.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_python_pivot.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_readme_surface_consistency.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_realworld_feedback.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_refactoring_intelligence.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_registry_dispatch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_relate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_report.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_reset_clean.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_resolve.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_retrieve.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_retrieve_cross_repo.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_retrieve_seeds.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_risk.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ruby.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_rule_profiles.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_rules.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_rules_ast_match.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_rules_community_pack.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_rules_dataflow.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_rules_symbol_requirements.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_runtime.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_runtime_score.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_salesforce.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_sarif_flag.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_sbom.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_scala.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_schema_versioning.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_search_explain.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_secrets.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_secrets_v2.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_semantic_diff.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_semantic_onnx.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_semantic_search.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_simulate.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_simulate_departure.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_sketch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_smells.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_smoke.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_sna_metrics.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_spectral.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_split_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_sql.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_suggest_reviewers.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_supply_chain.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_surface_counts.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_syntax_check.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_taint.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_taint_analysis.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_taint_classifier.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_taint_intraprocedural.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_test_conventions.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_test_gaps.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_test_scaffold.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_testmap.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_top_flag_consistency.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_tour_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_trends.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_trends_cohort.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_triage.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_uses_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v1215_passes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v1216_passes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v1216_passes_51_60.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v1217_passes_61_80.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v1218_passes_81_90.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v12_2.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v6_features.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v71_features.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v7_features.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_v82_features.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_verify.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_verify_imports.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_vibe_check.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_visualize.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_vuln.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_vulns_cmd.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_watch.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_why.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_workspace.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_ws_resolve_fixes.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/tests/test_xlang.py +0 -0
- {roam_code-12.18 → roam_code-12.19}/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.19
|
|
4
4
|
Summary: Instant codebase comprehension for AI coding agents
|
|
5
5
|
Author: CosmoHac
|
|
6
6
|
License-Expression: MIT
|
|
@@ -62,9 +62,9 @@ Dynamic: license-file
|
|
|
62
62
|
|
|
63
63
|
**Architectural sight for AI coding agents — before they edit.**
|
|
64
64
|
|
|
65
|
-
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other
|
|
65
|
+
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 173 specialised commands are advanced surface for specialised workflows.
|
|
66
66
|
|
|
67
|
-
*
|
|
67
|
+
*178 commands · 128 MCP tools · 27 languages · 100% local · zero API keys*
|
|
68
68
|
|
|
69
69
|
[](https://pypi.org/project/roam-code/)
|
|
70
70
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -156,7 +156,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
156
156
|
- **`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.
|
|
157
157
|
- **`.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`.
|
|
158
158
|
- **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).
|
|
159
|
-
- **177 CLI commands,
|
|
159
|
+
- **177 CLI commands, 128 MCP tools** (`fleet`, `ask`, `workflow`, `cga`, `eval-retrieve` remain CLI-only; v12 exposes `roam_retrieve`, `roam_critique`, `roam_fleet_plan`, plus 5 v12.1 boolean oracles (`roam_oracle_*`), `roam_taint_classify`, `roam_pytest_fixtures`, and `roam_hover` as MCP tools). 35-tool `core` preset is the default for token-budget-conscious clients.
|
|
160
160
|
|
|
161
161
|
## What's New in v11
|
|
162
162
|
|
|
@@ -327,7 +327,7 @@ roam health
|
|
|
327
327
|
|
|
328
328
|
## Commands
|
|
329
329
|
|
|
330
|
-
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining
|
|
330
|
+
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 173 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 **178 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
|
|
331
331
|
|
|
332
332
|
<details>
|
|
333
333
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -375,6 +375,7 @@ roam health
|
|
|
375
375
|
| `roam api [--scope <dir>]` | List the public API surface (exported public symbols + signatures) |
|
|
376
376
|
| `roam exit-codes` | List every roam exit code with its meaning |
|
|
377
377
|
| `roam version [--check]` | Show installed version; with `--check` also queries PyPI for newer releases |
|
|
378
|
+
| `roam audit [--brief]` | One-shot AI Agent Readiness Audit — chains health + debt + dead + risk + test-pyramid + api into a single envelope |
|
|
378
379
|
| `roam disambiguate <name>` | List every symbol matching the name with file/line/kind/signature/docstring snippet to pick the right one |
|
|
379
380
|
| `roam pre-commit [--install\|--print]` | Install or preview a roam-critique git pre-commit hook |
|
|
380
381
|
| `roam mcp-status` | MCP server health: preset, registered tools, backpressure limits, cache entries, watcher state |
|
|
@@ -992,7 +993,7 @@ ROAM_MCP_LITE=0 roam mcp
|
|
|
992
993
|
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`.
|
|
993
994
|
|
|
994
995
|
<details>
|
|
995
|
-
<summary><strong>MCP tool list (all
|
|
996
|
+
<summary><strong>MCP tool list (all 128)</strong></summary>
|
|
996
997
|
|
|
997
998
|
| Tool | Description |
|
|
998
999
|
|------|-------------|
|
|
@@ -1116,6 +1117,11 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
|
|
|
1116
1117
|
| `roam_reset` | Reset the roam index and cached data |
|
|
1117
1118
|
| `roam_clean` | Remove stale or orphaned index entries |
|
|
1118
1119
|
| `roam_catalog` | Machine-readable list of every registered MCP tool with capability flags (read_only / destructive / core) |
|
|
1120
|
+
| `roam_alerts` | Active health alerts: thresholds breached on tangle, complexity, churn, or coverage |
|
|
1121
|
+
| `roam_timeline` | Chronological commits that touched the file owning a symbol |
|
|
1122
|
+
| `roam_test_impact` | Tests transitively reachable from changed symbols (sharper than affected_tests) |
|
|
1123
|
+
| `roam_disambiguate` | List every symbol matching a name with file/line/kind/PageRank — pick the right overload |
|
|
1124
|
+
| `roam_why_fail` | Triage a failing test/symbol: recently-changed reachable symbols ranked by recency |
|
|
1119
1125
|
| `roam_batch_search` | Batch symbol search: run multiple pattern queries in a single call |
|
|
1120
1126
|
| `roam_batch_get` | Batch context retrieval: fetch multiple symbols/files in a single call |
|
|
1121
1127
|
| `roam_dev_profile` | Developer productivity profile: commit patterns, specialization, and impact |
|
|
@@ -1728,7 +1734,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
|
|
|
1728
1734
|
### Shipped
|
|
1729
1735
|
|
|
1730
1736
|
- [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
|
|
1731
|
-
- [x] Full command and MCP inventory parity in docs: 177 canonical CLI commands and
|
|
1737
|
+
- [x] Full command and MCP inventory parity in docs: 177 canonical CLI commands and 128 MCP tools.
|
|
1732
1738
|
- [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
|
|
1733
1739
|
- [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
|
|
1734
1740
|
- [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
**Architectural sight for AI coding agents — before they edit.**
|
|
6
6
|
|
|
7
|
-
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other
|
|
7
|
+
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 173 specialised commands are advanced surface for specialised workflows.
|
|
8
8
|
|
|
9
|
-
*
|
|
9
|
+
*178 commands · 128 MCP tools · 27 languages · 100% local · zero API keys*
|
|
10
10
|
|
|
11
11
|
[](https://pypi.org/project/roam-code/)
|
|
12
12
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -98,7 +98,7 @@ $ roam diff # blast radius of uncommitted changes
|
|
|
98
98
|
- **`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.
|
|
99
99
|
- **`.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`.
|
|
100
100
|
- **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).
|
|
101
|
-
- **177 CLI commands,
|
|
101
|
+
- **177 CLI commands, 128 MCP tools** (`fleet`, `ask`, `workflow`, `cga`, `eval-retrieve` remain CLI-only; v12 exposes `roam_retrieve`, `roam_critique`, `roam_fleet_plan`, plus 5 v12.1 boolean oracles (`roam_oracle_*`), `roam_taint_classify`, `roam_pytest_fixtures`, and `roam_hover` as MCP tools). 35-tool `core` preset is the default for token-budget-conscious clients.
|
|
102
102
|
|
|
103
103
|
## What's New in v11
|
|
104
104
|
|
|
@@ -269,7 +269,7 @@ roam health
|
|
|
269
269
|
|
|
270
270
|
## Commands
|
|
271
271
|
|
|
272
|
-
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining
|
|
272
|
+
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 173 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 **178 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
|
|
273
273
|
|
|
274
274
|
<details>
|
|
275
275
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -317,6 +317,7 @@ roam health
|
|
|
317
317
|
| `roam api [--scope <dir>]` | List the public API surface (exported public symbols + signatures) |
|
|
318
318
|
| `roam exit-codes` | List every roam exit code with its meaning |
|
|
319
319
|
| `roam version [--check]` | Show installed version; with `--check` also queries PyPI for newer releases |
|
|
320
|
+
| `roam audit [--brief]` | One-shot AI Agent Readiness Audit — chains health + debt + dead + risk + test-pyramid + api into a single envelope |
|
|
320
321
|
| `roam disambiguate <name>` | List every symbol matching the name with file/line/kind/signature/docstring snippet to pick the right one |
|
|
321
322
|
| `roam pre-commit [--install\|--print]` | Install or preview a roam-critique git pre-commit hook |
|
|
322
323
|
| `roam mcp-status` | MCP server health: preset, registered tools, backpressure limits, cache entries, watcher state |
|
|
@@ -934,7 +935,7 @@ ROAM_MCP_LITE=0 roam mcp
|
|
|
934
935
|
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`.
|
|
935
936
|
|
|
936
937
|
<details>
|
|
937
|
-
<summary><strong>MCP tool list (all
|
|
938
|
+
<summary><strong>MCP tool list (all 128)</strong></summary>
|
|
938
939
|
|
|
939
940
|
| Tool | Description |
|
|
940
941
|
|------|-------------|
|
|
@@ -1058,6 +1059,11 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
|
|
|
1058
1059
|
| `roam_reset` | Reset the roam index and cached data |
|
|
1059
1060
|
| `roam_clean` | Remove stale or orphaned index entries |
|
|
1060
1061
|
| `roam_catalog` | Machine-readable list of every registered MCP tool with capability flags (read_only / destructive / core) |
|
|
1062
|
+
| `roam_alerts` | Active health alerts: thresholds breached on tangle, complexity, churn, or coverage |
|
|
1063
|
+
| `roam_timeline` | Chronological commits that touched the file owning a symbol |
|
|
1064
|
+
| `roam_test_impact` | Tests transitively reachable from changed symbols (sharper than affected_tests) |
|
|
1065
|
+
| `roam_disambiguate` | List every symbol matching a name with file/line/kind/PageRank — pick the right overload |
|
|
1066
|
+
| `roam_why_fail` | Triage a failing test/symbol: recently-changed reachable symbols ranked by recency |
|
|
1061
1067
|
| `roam_batch_search` | Batch symbol search: run multiple pattern queries in a single call |
|
|
1062
1068
|
| `roam_batch_get` | Batch context retrieval: fetch multiple symbols/files in a single call |
|
|
1063
1069
|
| `roam_dev_profile` | Developer productivity profile: commit patterns, specialization, and impact |
|
|
@@ -1670,7 +1676,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
|
|
|
1670
1676
|
### Shipped
|
|
1671
1677
|
|
|
1672
1678
|
- [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
|
|
1673
|
-
- [x] Full command and MCP inventory parity in docs: 177 canonical CLI commands and
|
|
1679
|
+
- [x] Full command and MCP inventory parity in docs: 177 canonical CLI commands and 128 MCP tools.
|
|
1674
1680
|
- [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
|
|
1675
1681
|
- [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
|
|
1676
1682
|
- [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
|
|
@@ -127,6 +127,7 @@ _COMMANDS = {
|
|
|
127
127
|
"exit-codes": ("roam.commands.cmd_exit_codes", "exit_codes"),
|
|
128
128
|
"version": ("roam.commands.cmd_version", "version"),
|
|
129
129
|
"disambiguate": ("roam.commands.cmd_disambiguate", "disambiguate"),
|
|
130
|
+
"audit": ("roam.commands.cmd_audit", "audit"),
|
|
130
131
|
"pre-commit": ("roam.commands.cmd_pre_commit", "pre_commit"),
|
|
131
132
|
"mcp-status": ("roam.commands.cmd_mcp_status", "mcp_status"),
|
|
132
133
|
"test-impact": ("roam.commands.cmd_test_impact", "test_impact"),
|
|
@@ -245,6 +246,7 @@ _CATEGORIES = {
|
|
|
245
246
|
"mcp-status",
|
|
246
247
|
"ci-setup",
|
|
247
248
|
"adrs",
|
|
249
|
+
"audit",
|
|
248
250
|
"changelog",
|
|
249
251
|
"exit-codes",
|
|
250
252
|
"help-search",
|
|
@@ -12,7 +12,7 @@ import click
|
|
|
12
12
|
|
|
13
13
|
from roam.commands.changed_files import get_changed_files, resolve_changed_to_db
|
|
14
14
|
from roam.commands.resolve import ensure_index
|
|
15
|
-
from roam.db.connection import find_project_root, open_db
|
|
15
|
+
from roam.db.connection import batched_in, find_project_root, open_db
|
|
16
16
|
from roam.output.formatter import abbrev_kind, json_envelope, loc, to_json
|
|
17
17
|
|
|
18
18
|
# ---------------------------------------------------------------------------
|
|
@@ -308,28 +308,30 @@ def _check_cross_cluster(conn, changed_sym_ids):
|
|
|
308
308
|
|
|
309
309
|
|
|
310
310
|
def _check_orphaned_symbols(conn, changed_sym_ids):
|
|
311
|
-
"""Check for symbols in changed files with zero incoming edges.
|
|
311
|
+
"""Check for symbols in changed files with zero incoming edges.
|
|
312
|
+
|
|
313
|
+
Pass 94 — single batched query for in-degree + symbol metadata
|
|
314
|
+
instead of two queries per changed symbol.
|
|
315
|
+
"""
|
|
312
316
|
challenges = []
|
|
313
317
|
if not changed_sym_ids:
|
|
314
318
|
return challenges
|
|
315
319
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
sid_list = list(changed_sym_ids)
|
|
321
|
+
# One query per batch instead of two queries per symbol.
|
|
322
|
+
rows = batched_in(
|
|
323
|
+
conn,
|
|
324
|
+
"SELECT s.id, s.name, s.kind, f.path AS file_path, s.line_start, "
|
|
325
|
+
" (SELECT COUNT(*) FROM edges WHERE target_id = s.id) AS in_degree "
|
|
326
|
+
" FROM symbols s JOIN files f ON s.file_id = f.id "
|
|
327
|
+
" WHERE s.id IN ({ph})",
|
|
328
|
+
sid_list,
|
|
329
|
+
)
|
|
330
|
+
sym_by_id = {r["id"]: r for r in rows if r["in_degree"] == 0}
|
|
323
331
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
"FROM symbols s JOIN files f ON s.file_id = f.id WHERE s.id = ?",
|
|
328
|
-
(sid,),
|
|
329
|
-
).fetchone()
|
|
330
|
-
except Exception:
|
|
331
|
-
continue
|
|
332
|
-
if not sym:
|
|
332
|
+
for sid in changed_sym_ids:
|
|
333
|
+
sym = sym_by_id.get(sid)
|
|
334
|
+
if sym is None:
|
|
333
335
|
continue
|
|
334
336
|
|
|
335
337
|
# Only flag substantive symbols
|
|
@@ -371,25 +373,23 @@ def _check_high_fan_out(conn, changed_sym_ids):
|
|
|
371
373
|
|
|
372
374
|
_FAN_OUT_THRESHOLD = 10
|
|
373
375
|
|
|
374
|
-
for
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
376
|
+
# Pass 94 — single batched query for fan-out + metadata.
|
|
377
|
+
sid_list = list(changed_sym_ids)
|
|
378
|
+
rows = batched_in(
|
|
379
|
+
conn,
|
|
380
|
+
"SELECT s.id, s.name, s.kind, f.path AS file_path, s.line_start, "
|
|
381
|
+
" (SELECT COUNT(*) FROM edges WHERE source_id = s.id) AS fan_out "
|
|
382
|
+
" FROM symbols s JOIN files f ON s.file_id = f.id "
|
|
383
|
+
" WHERE s.id IN ({ph})",
|
|
384
|
+
sid_list,
|
|
385
|
+
)
|
|
386
|
+
sym_by_id = {r["id"]: r for r in rows if r["fan_out"] > _FAN_OUT_THRESHOLD}
|
|
381
387
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
"SELECT s.name, s.kind, f.path as file_path, s.line_start "
|
|
386
|
-
"FROM symbols s JOIN files f ON s.file_id = f.id WHERE s.id = ?",
|
|
387
|
-
(sid,),
|
|
388
|
-
).fetchone()
|
|
389
|
-
except Exception:
|
|
390
|
-
continue
|
|
391
|
-
if not sym:
|
|
388
|
+
for sid in changed_sym_ids:
|
|
389
|
+
sym = sym_by_id.get(sid)
|
|
390
|
+
if sym is None:
|
|
392
391
|
continue
|
|
392
|
+
fan_out = sym["fan_out"]
|
|
393
393
|
|
|
394
394
|
file_path = (sym["file_path"] or "").replace("\\", "/")
|
|
395
395
|
name = sym["name"] or ""
|
|
@@ -243,11 +243,17 @@ def affected(ctx, base_ref, max_depth, use_changed):
|
|
|
243
243
|
|
|
244
244
|
changed_paths = set(file_map.keys())
|
|
245
245
|
|
|
246
|
-
# Collect all symbol IDs in changed files
|
|
246
|
+
# Collect all symbol IDs in changed files. Pass 94 — single
|
|
247
|
+
# batched IN-clause replaces N round-trips (was one query per
|
|
248
|
+
# changed file; now one query for the whole set).
|
|
247
249
|
start_sym_ids = set()
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
if file_map:
|
|
251
|
+
sym_rows = batched_in(
|
|
252
|
+
conn,
|
|
253
|
+
"SELECT id FROM symbols WHERE file_id IN ({ph})",
|
|
254
|
+
list(file_map.values()),
|
|
255
|
+
)
|
|
256
|
+
start_sym_ids.update(s["id"] for s in sym_rows)
|
|
251
257
|
|
|
252
258
|
# BFS forward to find all dependents
|
|
253
259
|
reachable = _bfs_forward_with_depth(conn, start_sym_ids, max_depth)
|
|
@@ -699,8 +699,14 @@ def _write_with_preserve(filepath, content):
|
|
|
699
699
|
is_flag=True,
|
|
700
700
|
help="Write directly to project root (CLAUDE/AGENTS/CODEX/GEMINI/.cursorrules)",
|
|
701
701
|
)
|
|
702
|
+
@click.option(
|
|
703
|
+
"--brief",
|
|
704
|
+
"brief_mode",
|
|
705
|
+
is_flag=True,
|
|
706
|
+
help="Pass 100 — emit a compact summary (top-level fields only) instead of the full agent doc.",
|
|
707
|
+
)
|
|
702
708
|
@click.pass_context
|
|
703
|
-
def agent_export(ctx, output, fmt, profile, bundle, write_flag):
|
|
709
|
+
def agent_export(ctx, output, fmt, profile, bundle, write_flag, brief_mode):
|
|
704
710
|
"""Generate an AI agent context file from the roam index.
|
|
705
711
|
|
|
706
712
|
Produces a concise markdown document with architecture, key files,
|
|
@@ -781,6 +787,36 @@ def agent_export(ctx, output, fmt, profile, bundle, write_flag):
|
|
|
781
787
|
|
|
782
788
|
# JSON output
|
|
783
789
|
if json_mode:
|
|
790
|
+
envelope_kwargs = dict(
|
|
791
|
+
format=formats[0],
|
|
792
|
+
formats=formats,
|
|
793
|
+
profile=profile,
|
|
794
|
+
bundle=bundle,
|
|
795
|
+
project_name=project_name,
|
|
796
|
+
)
|
|
797
|
+
if not brief_mode:
|
|
798
|
+
# Pass 100 — full payload only when --brief is OFF.
|
|
799
|
+
envelope_kwargs.update(
|
|
800
|
+
languages=languages,
|
|
801
|
+
stats=stats,
|
|
802
|
+
directory_layout=layout,
|
|
803
|
+
key_files=key_files,
|
|
804
|
+
entry_points=entry_points,
|
|
805
|
+
hotspots=hotspots,
|
|
806
|
+
test_info=test_info,
|
|
807
|
+
health_summary=(
|
|
808
|
+
{
|
|
809
|
+
"score": health.get("health_score"),
|
|
810
|
+
"cycles": health.get("cycles", 0),
|
|
811
|
+
"god_components": health.get("god_components", 0),
|
|
812
|
+
"dead_exports": health.get("dead_exports", 0),
|
|
813
|
+
}
|
|
814
|
+
if health
|
|
815
|
+
else None
|
|
816
|
+
),
|
|
817
|
+
layers=layers,
|
|
818
|
+
clusters=clusters,
|
|
819
|
+
)
|
|
784
820
|
click.echo(
|
|
785
821
|
to_json(
|
|
786
822
|
json_envelope(
|
|
@@ -794,29 +830,9 @@ def agent_export(ctx, output, fmt, profile, bundle, write_flag):
|
|
|
794
830
|
"sections": section_count,
|
|
795
831
|
"files": stats["files"],
|
|
796
832
|
"symbols": stats["symbols"],
|
|
833
|
+
"brief": brief_mode,
|
|
797
834
|
},
|
|
798
|
-
|
|
799
|
-
formats=formats,
|
|
800
|
-
profile=profile,
|
|
801
|
-
bundle=bundle,
|
|
802
|
-
project_name=project_name,
|
|
803
|
-
languages=languages,
|
|
804
|
-
stats=stats,
|
|
805
|
-
directory_layout=layout,
|
|
806
|
-
key_files=key_files,
|
|
807
|
-
entry_points=entry_points,
|
|
808
|
-
hotspots=hotspots,
|
|
809
|
-
test_info=test_info,
|
|
810
|
-
health_summary={
|
|
811
|
-
"score": health.get("health_score"),
|
|
812
|
-
"cycles": health.get("cycles", 0),
|
|
813
|
-
"god_components": health.get("god_components", 0),
|
|
814
|
-
"dead_exports": health.get("dead_exports", 0),
|
|
815
|
-
}
|
|
816
|
-
if health
|
|
817
|
-
else None,
|
|
818
|
-
layers=layers,
|
|
819
|
-
clusters=clusters,
|
|
835
|
+
**envelope_kwargs,
|
|
820
836
|
)
|
|
821
837
|
)
|
|
822
838
|
)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""``roam audit`` — AI Agent Readiness Audit.
|
|
2
|
+
|
|
3
|
+
Pass 97 — Priority 1 strategic blocker per build_priorities.md. Chains
|
|
4
|
+
``index → describe → health → risk → dead → owner → test-map → pr-risk``
|
|
5
|
+
into a single structured-JSON envelope. The artifact paying customers
|
|
6
|
+
buy: a one-shot audit that calibrates how ready a codebase is for
|
|
7
|
+
agent-driven work.
|
|
8
|
+
|
|
9
|
+
Sections:
|
|
10
|
+
|
|
11
|
+
- ``health`` — composite health score with category breakdown
|
|
12
|
+
- ``debt`` — total estimated debt + top hotspots
|
|
13
|
+
- ``dead`` — unused-symbol count + top wasted-LOC files
|
|
14
|
+
- ``risk`` — surface high-risk files (churn × complexity × fan-in)
|
|
15
|
+
- ``test_pyramid`` — unit/integration/e2e/smoke distribution
|
|
16
|
+
- ``coverage`` — imported-coverage % when available
|
|
17
|
+
- ``api`` — count of public symbols (the agent-facing surface)
|
|
18
|
+
|
|
19
|
+
Each section runs the corresponding sub-command in --json mode and
|
|
20
|
+
extracts a small set of high-signal fields. Failures from individual
|
|
21
|
+
sections are surfaced as ``{"error": ...}`` rows so the audit never
|
|
22
|
+
fails the whole report.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import json as _json
|
|
28
|
+
|
|
29
|
+
import click
|
|
30
|
+
from click.testing import CliRunner
|
|
31
|
+
|
|
32
|
+
from roam.commands.resolve import ensure_index
|
|
33
|
+
from roam.output.formatter import json_envelope, to_json
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _capture(args: list[str]) -> dict:
|
|
37
|
+
"""Invoke a roam subcommand in --json mode in-process."""
|
|
38
|
+
from roam.cli import cli
|
|
39
|
+
|
|
40
|
+
runner = CliRunner()
|
|
41
|
+
result = runner.invoke(cli, ["--json", *args])
|
|
42
|
+
if result.exit_code not in (0, 5): # 5 = gate failure (still produces JSON)
|
|
43
|
+
return {
|
|
44
|
+
"_error": f"exit {result.exit_code}",
|
|
45
|
+
"_command": args,
|
|
46
|
+
"_output_head": (result.output or "")[:200],
|
|
47
|
+
}
|
|
48
|
+
try:
|
|
49
|
+
return _json.loads(result.output)
|
|
50
|
+
except Exception as exc:
|
|
51
|
+
return {
|
|
52
|
+
"_error": f"non-JSON output: {exc}",
|
|
53
|
+
"_command": args,
|
|
54
|
+
"_output_head": (result.output or "")[:200],
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _summary_field(payload: dict, *keys: str, default=None):
|
|
59
|
+
summary = payload.get("summary") or {}
|
|
60
|
+
for k in keys:
|
|
61
|
+
if k in summary and summary[k] is not None:
|
|
62
|
+
return summary[k]
|
|
63
|
+
return default
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@click.command()
|
|
67
|
+
@click.option(
|
|
68
|
+
"--brief",
|
|
69
|
+
is_flag=True,
|
|
70
|
+
help="Drop per-section detail; keep only the top-level summary scores.",
|
|
71
|
+
)
|
|
72
|
+
@click.pass_context
|
|
73
|
+
def audit(ctx, brief) -> None:
|
|
74
|
+
"""One-shot AI Agent Readiness Audit.
|
|
75
|
+
|
|
76
|
+
Bundles health, debt, dead-code, risk, test-pyramid, coverage, and
|
|
77
|
+
API-surface signals into a single envelope. Designed as the
|
|
78
|
+
structured artifact a paid audit attaches to its report.
|
|
79
|
+
"""
|
|
80
|
+
json_mode = ctx.obj.get("json") if ctx.obj else False
|
|
81
|
+
ensure_index()
|
|
82
|
+
|
|
83
|
+
health = _capture(["health"])
|
|
84
|
+
debt = _capture(["debt"])
|
|
85
|
+
dead = _capture(["dead"])
|
|
86
|
+
test_pyramid = _capture(["test-pyramid"])
|
|
87
|
+
api = _capture(["api", "--limit", "0"])
|
|
88
|
+
stats = _capture(["stats"])
|
|
89
|
+
hotspots = _capture(["hotspots", "--danger"])
|
|
90
|
+
|
|
91
|
+
# Top-level scores so consumers can branch fast.
|
|
92
|
+
health_score = _summary_field(health, "health_score", "score")
|
|
93
|
+
debt_total = _summary_field(debt, "total_minutes", "estimated_minutes", "total")
|
|
94
|
+
dead_count = _summary_field(dead, "dead_count", "total")
|
|
95
|
+
danger_count = _summary_field(hotspots, "count", "danger_count", default=0)
|
|
96
|
+
pyramid_total = _summary_field(test_pyramid, "total", default=0)
|
|
97
|
+
api_count = _summary_field(api, "count", default=0)
|
|
98
|
+
file_total = _summary_field(stats, "file_total", default=0)
|
|
99
|
+
sym_total = _summary_field(stats, "symbol_total", default=0)
|
|
100
|
+
coverage_pct = _summary_field(health, "imported_coverage_pct")
|
|
101
|
+
|
|
102
|
+
# Verdict — stack-rank the most pressing dimension.
|
|
103
|
+
pressures = []
|
|
104
|
+
if isinstance(health_score, (int, float)) and health_score < 60:
|
|
105
|
+
pressures.append(f"health {health_score}/100")
|
|
106
|
+
if isinstance(danger_count, int) and danger_count > 0:
|
|
107
|
+
pressures.append(f"{danger_count} danger-zone file(s)")
|
|
108
|
+
if isinstance(coverage_pct, (int, float)) and coverage_pct < 40:
|
|
109
|
+
pressures.append(f"coverage {coverage_pct:.0f}%")
|
|
110
|
+
if pressures:
|
|
111
|
+
verdict = "AUDIT — pressures: " + ", ".join(pressures)
|
|
112
|
+
else:
|
|
113
|
+
verdict = (
|
|
114
|
+
f"AUDIT — health {health_score or '?'}/100, "
|
|
115
|
+
f"{file_total} files, {sym_total} symbols, "
|
|
116
|
+
f"{api_count} public-API symbols"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
summary = {
|
|
120
|
+
"verdict": verdict,
|
|
121
|
+
"health_score": health_score,
|
|
122
|
+
"debt_total": debt_total,
|
|
123
|
+
"dead_count": dead_count,
|
|
124
|
+
"danger_zone_count": danger_count,
|
|
125
|
+
"test_count": pyramid_total,
|
|
126
|
+
"api_surface": api_count,
|
|
127
|
+
"imported_coverage_pct": coverage_pct,
|
|
128
|
+
"file_total": file_total,
|
|
129
|
+
"symbol_total": sym_total,
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
sections = {
|
|
133
|
+
"health": health if not brief else {"summary": health.get("summary", {})},
|
|
134
|
+
"debt": debt if not brief else {"summary": debt.get("summary", {})},
|
|
135
|
+
"dead": dead if not brief else {"summary": dead.get("summary", {})},
|
|
136
|
+
"test_pyramid": test_pyramid if not brief else {"summary": test_pyramid.get("summary", {})},
|
|
137
|
+
"hotspots_danger": hotspots if not brief else {"summary": hotspots.get("summary", {})},
|
|
138
|
+
"stats": stats if not brief else {"summary": stats.get("summary", {})},
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if json_mode:
|
|
142
|
+
click.echo(
|
|
143
|
+
to_json(
|
|
144
|
+
json_envelope(
|
|
145
|
+
"audit",
|
|
146
|
+
summary=summary,
|
|
147
|
+
sections=sections,
|
|
148
|
+
api_count=api_count,
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
return
|
|
153
|
+
|
|
154
|
+
click.echo(f"VERDICT: {verdict}")
|
|
155
|
+
click.echo()
|
|
156
|
+
click.echo(f"{'Metric':<28} Value")
|
|
157
|
+
click.echo(f"{'-' * 28} {'-' * 30}")
|
|
158
|
+
for label, value in [
|
|
159
|
+
("health score (0-100)", health_score),
|
|
160
|
+
("debt (total)", debt_total),
|
|
161
|
+
("dead symbols", dead_count),
|
|
162
|
+
("danger-zone files", danger_count),
|
|
163
|
+
("test files indexed", pyramid_total),
|
|
164
|
+
("public API surface", api_count),
|
|
165
|
+
("imported coverage %", coverage_pct),
|
|
166
|
+
("total files", file_total),
|
|
167
|
+
("total symbols", sym_total),
|
|
168
|
+
]:
|
|
169
|
+
click.echo(f"{label:<28} {value}")
|
|
@@ -111,11 +111,21 @@ def complexity(ctx, target, limit, threshold, by_file, bumpy_road, include_tooli
|
|
|
111
111
|
try:
|
|
112
112
|
count = conn.execute("SELECT COUNT(*) FROM symbol_metrics").fetchone()[0]
|
|
113
113
|
except Exception:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
count = -1
|
|
115
|
+
if count <= 0:
|
|
116
|
+
verdict = "No complexity data found. Re-index with: roam index --force"
|
|
117
|
+
if json_mode:
|
|
118
|
+
click.echo(
|
|
119
|
+
to_json(
|
|
120
|
+
json_envelope(
|
|
121
|
+
"complexity",
|
|
122
|
+
summary={"verdict": verdict, "total": 0},
|
|
123
|
+
results=[],
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
else:
|
|
128
|
+
click.echo(verdict)
|
|
119
129
|
raise SystemExit(1)
|
|
120
130
|
|
|
121
131
|
if bumpy_road:
|
|
@@ -179,7 +189,19 @@ def complexity(ctx, target, limit, threshold, by_file, bumpy_road, include_tooli
|
|
|
179
189
|
sarif = complexity_to_sarif([], threshold=threshold or 0)
|
|
180
190
|
click.echo(write_sarif(sarif))
|
|
181
191
|
return
|
|
182
|
-
|
|
192
|
+
verdict = "No matching symbols found."
|
|
193
|
+
if json_mode:
|
|
194
|
+
click.echo(
|
|
195
|
+
to_json(
|
|
196
|
+
json_envelope(
|
|
197
|
+
"complexity",
|
|
198
|
+
summary={"verdict": verdict, "total": 0},
|
|
199
|
+
results=[],
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
else:
|
|
204
|
+
click.echo(verdict)
|
|
183
205
|
return
|
|
184
206
|
|
|
185
207
|
if sarif_mode:
|
|
@@ -398,7 +420,19 @@ def _bumpy_road(conn, json_mode, limit, threshold):
|
|
|
398
420
|
).fetchall()
|
|
399
421
|
|
|
400
422
|
if not rows:
|
|
401
|
-
|
|
423
|
+
verdict = "No bumpy-road files found."
|
|
424
|
+
if json_mode:
|
|
425
|
+
click.echo(
|
|
426
|
+
to_json(
|
|
427
|
+
json_envelope(
|
|
428
|
+
"complexity",
|
|
429
|
+
summary={"verdict": verdict, "total": 0},
|
|
430
|
+
bumpy_road=[],
|
|
431
|
+
)
|
|
432
|
+
)
|
|
433
|
+
)
|
|
434
|
+
else:
|
|
435
|
+
click.echo(verdict)
|
|
402
436
|
return
|
|
403
437
|
|
|
404
438
|
if json_mode:
|
|
@@ -543,18 +543,19 @@ def _no_mutating_options(
|
|
|
543
543
|
exclude_pattern,
|
|
544
544
|
remove_pattern,
|
|
545
545
|
) -> bool:
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
546
|
+
# Pass 91 — ``use_local_cache`` is a ``is_flag=True`` Click option,
|
|
547
|
+
# so its default is ``False`` not ``None``. The previous all(... is
|
|
548
|
+
# None) check returned False even when nothing was passed, leaving
|
|
549
|
+
# ``roam config`` (no flags, no --show) silent in --json mode.
|
|
550
|
+
return (
|
|
551
|
+
db_dir is None
|
|
552
|
+
and not use_local_cache
|
|
553
|
+
and semantic_backend is None
|
|
554
|
+
and onnx_model is None
|
|
555
|
+
and onnx_tokenizer is None
|
|
556
|
+
and onnx_max_length is None
|
|
557
|
+
and exclude_pattern is None
|
|
558
|
+
and remove_pattern is None
|
|
558
559
|
)
|
|
559
560
|
|
|
560
561
|
|