roam-code 12.12.8__tar.gz → 12.13__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.12.8/src/roam_code.egg-info → roam_code-12.13}/PKG-INFO +1 -1
- {roam_code-12.12.8 → roam_code-12.13}/pyproject.toml +1 -1
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/cli.py +62 -5
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_coverage_gaps.py +9 -2
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_impact.py +23 -2
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_retrieve.py +111 -74
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_tour.py +23 -4
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_uses.py +24 -6
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/competitor_site_data.py +1 -1
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp-server-card.json +1 -1
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/rerank.py +125 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/seeds.py +79 -0
- {roam_code-12.12.8 → roam_code-12.13/src/roam_code.egg-info}/PKG-INFO +1 -1
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_retrieve.py +12 -3
- {roam_code-12.12.8 → roam_code-12.13}/LICENSE +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/README.md +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/setup.cfg +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/__main__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/analysis/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/analysis/effects.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/analysis/taint.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/api.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/classifier.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/recipes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/runner.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/workflow.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/attest/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/attest/cga.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/base.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_config.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_django.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_protobuf.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_rest_api.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_salesforce.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_template.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/registry.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/detectors.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/fixes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/python_idioms.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/smells.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/tasks.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/changed_files.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_adrs.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_adversarial.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_affected.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_affected_tests.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_agent_context.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_agent_export.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_agent_plan.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ai_ratio.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ai_readiness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_alerts.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_annotate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_api_changes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_api_drift.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ask.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_attest.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_auth_gaps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_bisect.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_breaking.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_budget.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_bus_factor.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_capsule.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_cga.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_check_rules.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ci_setup.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_clean.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_clones.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_closure.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_clusters.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_codeowners.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_complexity.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_config.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_congestion.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_context.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_conventions.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_coupling.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_critique.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_cut.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dark_matter.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dashboard.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dead.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_debt.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_deps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_describe.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dev_profile.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_diagnose.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_diff.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_doc_staleness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_docs_coverage.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_doctor.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_drift.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_duplicates.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_effects.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_endpoints.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_entry_points.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_eval_retrieve.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fan.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_file.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fingerprint.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fitness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_flag_dead.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fleet.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fn_coupling.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_forecast.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_grep.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_guard.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_health.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_hooks.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_hotspots.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_hover.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_index.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_index_bundle.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ingest_trace.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_init.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_intent.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_invariants.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_layers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_map.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_math.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_mcp_setup.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_metrics.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_migration_safety.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_minimap.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_missing_index.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_module.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_mutate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_n1.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_oracle.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_orchestrate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_orphan_routes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_over_fetch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_owner.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_partition.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_path_coverage.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_patterns.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_plan.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_plan_refactor.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_pr_diff.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_pr_risk.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_preflight.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_py_modern.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_py_types.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_pytest_fixtures.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_relate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_report.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_reset.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_risk.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_rules.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_safe_delete.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_safe_zones.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_sbom.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_schema.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_search.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_search_semantic.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_secrets.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_semantic_diff.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_simulate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_simulate_departure.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_sketch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_smells.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_spectral.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_split.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_supply_chain.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_symbol.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_syntax_check.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_taint.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_test_gaps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_test_scaffold.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_testmap.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_trace.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_trends.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_triage.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_understand.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_verify.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_verify_imports.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vibe_check.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_visualize.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vuln_map.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vuln_reach.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vulns.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_watch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_weather.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_why.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_workflow.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ws.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_xlang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/codeowners_helpers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/context_helpers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/gate_presets.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/graph_helpers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/metrics_history.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/next_steps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/resolve.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/suppression.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/config.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/coverage_reports.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/critique/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/critique/aggregator.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/critique/checks.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/connection.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/queries.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/schema.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/eval/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/eval/harness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/exit_codes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/fleet/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/fleet/adapters.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/fleet/manifest.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/git_utils.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/anomaly.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/builder.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/clone_detect.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/clusters.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/cycles.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/dark_matter.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/diff.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/fingerprint.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/layers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/pagerank.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/partition.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/pathfinding.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/propagation.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/simulate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/spectral.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/stats.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/complexity.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/discovery.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/django_post.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/file_roles.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/git_stats.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/gitignore.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/incremental.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/indexer.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/parser.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/pytest_fixtures.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/registry_dispatch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/relations.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/symbols.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/test_conventions.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/apex_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/aura_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/base.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/c_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/csharp_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/extractor_schema.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/extractors/kotlin.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/foxpro_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/generic_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/go_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/hcl_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/java_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/javascript_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/kotlin_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/php_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/python_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/query_engine.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/registry.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/ruby_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/rust_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/scala_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/sfxml_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/sql_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/swift_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/typescript_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/visualforce_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/yaml_lang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/completions.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/concurrency.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/progress.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/sampling.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/session.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/watcher.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_server.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/confidence.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/errors.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/file_role_hints.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/formatter.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/framework_filter.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/mermaid.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/project_shape.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/sarif.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/schema_registry.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/plugins.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/refactor/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/refactor/codegen.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/refactor/transforms.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/learned_ranker.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/pipeline.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/semantic.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/ast_match.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/builtin.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/dataflow.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/engine.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/daemon.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/graph_backend.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/hotspots.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/lock_modes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/lockmgr.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/trace_ingest.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/framework_packs.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/index_embeddings.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/onnx_embeddings.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/tfidf.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/aibom_extension.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_classifier.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_engine.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/api_error_leak.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/java_fileupload_path_traversal.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_insecure_jwt_decode.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_localstorage_secrets.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_prototype_pollution.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_ssrf.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_xss.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_basic.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_deserialization.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_path_traversal.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_socketio_remote_source.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_sqli.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_urllib_open_redirect.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/vue_v_html.yaml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/vuln_reach.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/vuln_store.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/surface_counts.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/Jenkinsfile +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/azure-pipelines.yml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/bitbucket-pipelines.yml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/gitlab-ci.yml +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/__init__.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/aggregator.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/api_scanner.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/config.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/db.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/SOURCES.txt +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/dependency_links.txt +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/entry_points.txt +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/requires.txt +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/top_level.txt +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_adrs.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_adversarial.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_affected.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_agent_export.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_agent_mode.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_agent_plan_context.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ai_ratio.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ai_readiness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_alerts_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_annotations.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_anomaly.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_api_changes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_api_drift.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ask.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_attest.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_auth_gaps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_backend_fixes_round2.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_backend_fixes_round3.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_basic.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_batch_mcp.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_bisect.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_bridge_django.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_bridges.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_bridges_extended.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_budget.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_budget_flag.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_budget_phase2.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_bus_factor.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_capsule.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_cga.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_check_rules.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ci_gate_eval.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ci_sarif_guard.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ci_setup.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_clones.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_closure.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_codeowners.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_architecture.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_exploration.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_health.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_refactoring.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_workflow.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_competitor_site_data.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_comprehensive.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_config.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_congestion.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_context_propagation.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_conventions_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_coverage_gaps_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_coverage_ingestion.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_critique.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_cut.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_dark_matter.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_dark_matter_helpers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_dashboard.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_dataflow_dead.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_dead_aging.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_defer_loading.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_demo_gif_asset.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_describe.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_detail_flag_hints.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_detector_precision.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_deterministic_output.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_dev_profile.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_difficulty_scoring.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_doc_consistency.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_doc_staleness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_docker_assets.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_docs_coverage.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_docs_site_quality.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_doctor.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_drift.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_drift_by_team.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_duplicates.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_effects.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_effects_propagation.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_endpoints.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_entry_points_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_eval_retrieve.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_except_pass_narrow.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_exclude_patterns.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_exit_codes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_extractor_grammar_drift.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_fallback_contracts.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_file_roles.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_fingerprint.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_fixes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_flag_dead.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_fleet.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_fn_coupling.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_forecast.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_formatters.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_foxpro.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_framework_detection.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_gate_presets.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_git_utils.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_guard.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_health_gate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_hooks.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_hotspots.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_hover.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_index.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_index_bundle.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_init_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_install_check.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_intent.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_invariants.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_json_contracts.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_json_error_envelope.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_kotlin_swift_extractors.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_language_corpus.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_languages.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_library_api.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_math.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_math_tips.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_mcp_extras.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_mcp_server.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_mcp_setup.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_mermaid.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_metrics_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_migration_safety.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_minimap.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_missing_index.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_mutate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_n1.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_next_steps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_onboard.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_oracle.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_orchestrate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_orphan_routes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_oss_bench_harness.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_over_fetch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_pagerank_truncation.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_partition.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_path_coverage.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_patterns_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_performance.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_personalized_pagerank.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_plan.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_plugin_discovery.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_pr_comment_script.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_pr_diff.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_pr_risk_author.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_progress.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_progressive_disclosure.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_properties.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_pytest_fixtures.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_python_extractor_v2.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_python_idioms_e2e.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_python_pivot.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_readme_surface_consistency.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_realworld_feedback.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_refactoring_intelligence.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_registry_dispatch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_relate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_report.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_reset_clean.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_resolve.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_retrieve_cross_repo.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_retrieve_seeds.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_risk.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ruby.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_rule_profiles.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_ast_match.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_community_pack.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_dataflow.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_symbol_requirements.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_runtime.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_runtime_score.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_salesforce.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_sarif_flag.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_sbom.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_scala.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_schema_versioning.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_search_explain.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_secrets.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_secrets_v2.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_semantic_diff.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_semantic_onnx.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_semantic_search.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_simulate.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_simulate_departure.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_sketch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_smells.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_smoke.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_sna_metrics.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_spectral.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_split_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_sql.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_suggest_reviewers.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_supply_chain.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_surface_counts.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_syntax_check.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint_analysis.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint_classifier.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint_intraprocedural.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_test_conventions.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_test_gaps.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_test_scaffold.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_testmap.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_top_flag_consistency.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_tour_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_trends.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_trends_cohort.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_triage.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_uses_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_v12_2.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_v6_features.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_v71_features.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_v7_features.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_v82_features.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_verify.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_verify_imports.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_vibe_check.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_visualize.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_vuln.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_vulns_cmd.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_watch.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_why.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_workspace.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_ws_resolve_fixes.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_xlang.py +0 -0
- {roam_code-12.12.8 → roam_code-12.13}/tests/test_yaml_hcl.py +0 -0
|
@@ -498,7 +498,19 @@ class LazyGroup(click.Group):
|
|
|
498
498
|
ctx.exit(EXIT_ERROR)
|
|
499
499
|
|
|
500
500
|
def format_help(self, ctx, formatter):
|
|
501
|
-
"""Categorized help display instead of flat alphabetical list.
|
|
501
|
+
"""Categorized help display instead of flat alphabetical list.
|
|
502
|
+
|
|
503
|
+
Phase-1.5 / 12.13 — performance: previously this method called
|
|
504
|
+
``self.get_command()`` for each priority-category command,
|
|
505
|
+
which triggered ``importlib.import_module()`` on every cmd_*.py
|
|
506
|
+
in the priority list. That added ~3.5 seconds of Python
|
|
507
|
+
imports just to render the help banner. We now extract the
|
|
508
|
+
short-help via AST without importing — reading the source
|
|
509
|
+
file's first docstring is fast (sub-100ms for the whole
|
|
510
|
+
priority set) and produces the identical output. Falls back
|
|
511
|
+
to a live import only when AST extraction can't find the
|
|
512
|
+
docstring.
|
|
513
|
+
"""
|
|
502
514
|
_ensure_plugin_commands_loaded()
|
|
503
515
|
self.format_usage(ctx, formatter)
|
|
504
516
|
formatter.write("\n")
|
|
@@ -515,10 +527,10 @@ class LazyGroup(click.Group):
|
|
|
515
527
|
continue
|
|
516
528
|
formatter.write(f" {cat_name}:\n")
|
|
517
529
|
for cmd_name in valid_cmds:
|
|
518
|
-
|
|
519
|
-
if
|
|
520
|
-
|
|
521
|
-
|
|
530
|
+
help_text = _short_help_via_ast(cmd_name)
|
|
531
|
+
if help_text is None:
|
|
532
|
+
cmd = self.get_command(ctx, cmd_name)
|
|
533
|
+
help_text = cmd.get_short_help_str(limit=60) if cmd else ""
|
|
522
534
|
formatter.write(f" {cmd_name:20s} {help_text}\n")
|
|
523
535
|
shown.add(cmd_name)
|
|
524
536
|
formatter.write("\n")
|
|
@@ -531,6 +543,51 @@ class LazyGroup(click.Group):
|
|
|
531
543
|
formatter.write(" Run `roam <command> --help` for details on any command.\n")
|
|
532
544
|
|
|
533
545
|
|
|
546
|
+
def _short_help_via_ast(cmd_name: str) -> str | None:
|
|
547
|
+
"""Extract a Click short-help string from cmd_*.py without importing.
|
|
548
|
+
|
|
549
|
+
Click's ``get_short_help_str()`` reads the docstring of the function
|
|
550
|
+
decorated with ``@click.command``, truncates at the first sentence,
|
|
551
|
+
and limits to 60 chars. We reproduce that via Python's ``ast`` —
|
|
552
|
+
no Click load, no cmd module import, no cascade of heavy deps.
|
|
553
|
+
|
|
554
|
+
Returns ``None`` when the cmd file or expected attribute is absent;
|
|
555
|
+
the caller falls back to the live ``self.get_command()`` path.
|
|
556
|
+
"""
|
|
557
|
+
target = _COMMANDS.get(cmd_name)
|
|
558
|
+
if not target:
|
|
559
|
+
return None
|
|
560
|
+
module_path, attr_name = target
|
|
561
|
+
# cli.py lives at src/roam/cli.py; cmd modules at src/roam/commands/cmd_*.py.
|
|
562
|
+
# Build the path from the module dotted path relative to the package root,
|
|
563
|
+
# not relative to cli.py.
|
|
564
|
+
pkg_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
565
|
+
rel = module_path.replace(".", os.sep) + ".py"
|
|
566
|
+
src_path = os.path.join(pkg_root, rel)
|
|
567
|
+
if not os.path.isfile(src_path):
|
|
568
|
+
return None
|
|
569
|
+
try:
|
|
570
|
+
import ast as _ast
|
|
571
|
+
|
|
572
|
+
with open(src_path, encoding="utf-8") as fh:
|
|
573
|
+
tree = _ast.parse(fh.read(), filename=src_path)
|
|
574
|
+
except (OSError, SyntaxError):
|
|
575
|
+
return None
|
|
576
|
+
for node in tree.body:
|
|
577
|
+
# Find the function definition matching attr_name. Click commands
|
|
578
|
+
# are functions decorated with @click.command (or named decorators).
|
|
579
|
+
if isinstance(node, (_ast.FunctionDef, _ast.AsyncFunctionDef)) and node.name == attr_name:
|
|
580
|
+
doc = _ast.get_docstring(node) or ""
|
|
581
|
+
# Click's behaviour: take the first paragraph (up to blank line),
|
|
582
|
+
# strip trailing punctuation, cap at 60 chars + "...".
|
|
583
|
+
first_para = doc.split("\n\n", 1)[0].strip()
|
|
584
|
+
first_line = " ".join(first_para.split())
|
|
585
|
+
if len(first_line) > 60:
|
|
586
|
+
first_line = first_line[:57] + "..."
|
|
587
|
+
return first_line
|
|
588
|
+
return None
|
|
589
|
+
|
|
590
|
+
|
|
534
591
|
def _run_check(ctx: click.Context, param: click.Parameter, value: bool) -> None:
|
|
535
592
|
"""Eager callback for --check: run critical install checks and exit.
|
|
536
593
|
|
|
@@ -436,8 +436,15 @@ def coverage_gaps(
|
|
|
436
436
|
return
|
|
437
437
|
|
|
438
438
|
if not gate_names and not gate_pattern:
|
|
439
|
-
click.echo("
|
|
440
|
-
|
|
439
|
+
click.echo("VERDICT: missing required filter — pass --gate or --gate-pattern")
|
|
440
|
+
click.echo()
|
|
441
|
+
click.echo(" --gate NAME single gate symbol (e.g. handle_login)")
|
|
442
|
+
click.echo(" --gate-pattern RE regex over symbol names (e.g. '^auth_.*')")
|
|
443
|
+
click.echo()
|
|
444
|
+
click.echo("Examples:")
|
|
445
|
+
click.echo(" roam coverage-gaps --gate handle_payment")
|
|
446
|
+
click.echo(" roam coverage-gaps --gate-pattern '^validate_.*'")
|
|
447
|
+
raise SystemExit(2)
|
|
441
448
|
|
|
442
449
|
with open_db(readonly=True) as conn:
|
|
443
450
|
gates, gate_info = _find_gates(conn, gate_names, gate_pattern)
|
|
@@ -221,8 +221,29 @@ def impact(ctx, name):
|
|
|
221
221
|
click.echo(f"(+{len(dependents) - len(direct_callers)} transitive dependents)")
|
|
222
222
|
|
|
223
223
|
if affected_files:
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
# 12.13 — rank files by max-dependent PageRank instead of
|
|
225
|
+
# alphabetically. The user reading "Affected files" wants
|
|
226
|
+
# to know which files matter most — alphabetical order
|
|
227
|
+
# surfaced ``benchmarks/`` and ``bench-repos/`` ahead of
|
|
228
|
+
# the actually-important ``src/roam/cli.py`` for queries
|
|
229
|
+
# against this repo. PageRank-ranked top-20 puts the
|
|
230
|
+
# impactful files first; the rest are cut by the +N more
|
|
231
|
+
# tail.
|
|
232
|
+
try:
|
|
233
|
+
from roam.graph.pagerank import global_pagerank
|
|
234
|
+
|
|
235
|
+
_global_pr = global_pagerank(G)
|
|
236
|
+
except Exception:
|
|
237
|
+
_global_pr = {}
|
|
238
|
+
_file_pr: dict[str, float] = {}
|
|
239
|
+
for dep_id in dependents:
|
|
240
|
+
fp = G.nodes.get(dep_id, {}).get("file_path", "?")
|
|
241
|
+
pr_val = _global_pr.get(dep_id, 0.0)
|
|
242
|
+
if pr_val > _file_pr.get(fp, 0.0):
|
|
243
|
+
_file_pr[fp] = pr_val
|
|
244
|
+
ranked_files = sorted(affected_files, key=lambda fp: -_file_pr.get(fp, 0.0))
|
|
245
|
+
click.echo(f"\nAffected files ({len(affected_files)} — ranked by impact):")
|
|
246
|
+
for fp in ranked_files[:20]:
|
|
226
247
|
click.echo(f" {fp}")
|
|
227
248
|
if len(affected_files) > 20:
|
|
228
249
|
click.echo(f" (+{len(affected_files) - 20} more)")
|
|
@@ -24,59 +24,58 @@ from roam.retrieve.pipeline import run_retrieve
|
|
|
24
24
|
from roam.retrieve.semantic import semantic_coverage
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
27
|
+
def _retrieve_confidence_score(candidates: list[dict], task: str = "") -> tuple[float, str]:
|
|
28
|
+
"""Return a calibrated confidence number in ``[0.0, 1.0]`` plus a
|
|
29
|
+
string label (``"low"`` / ``"ok"``) for backwards compat.
|
|
30
|
+
|
|
31
|
+
Three signals combine multiplicatively:
|
|
32
|
+
|
|
33
|
+
1. **Token coverage** — fraction of query tokens that appear in
|
|
34
|
+
the top-10 results' name/path. Strong signal: if you ask for
|
|
35
|
+
"auth login session" and only "auth" appears anywhere in the
|
|
36
|
+
results, the search missed the intent.
|
|
37
|
+
2. **Score gap** — how far does the top result outrank the
|
|
38
|
+
runners-up. A unique winner (gap ≥ 0.30 in normalised space)
|
|
39
|
+
is high-confidence; a flat distribution is low-confidence.
|
|
40
|
+
3. **Top-score absolute floor** — scores bunched near 0.20 with
|
|
41
|
+
no spread are noise-floor matches.
|
|
42
|
+
|
|
43
|
+
Returns ``(score, label)``. The label is "low" when ``score < 0.40``,
|
|
44
|
+
"ok" otherwise. The previous binary classifier preserved the
|
|
45
|
+
legacy threshold (token-cover ≤ 1 OR top<0.30+spread<0.10);
|
|
46
|
+
a continuous score lets the verdict carry more useful info
|
|
47
|
+
(e.g. "0.62 confidence" vs "low / ok").
|
|
47
48
|
"""
|
|
48
49
|
if not candidates:
|
|
49
|
-
return "low"
|
|
50
|
+
return 0.0, "low"
|
|
50
51
|
scores = [float(c.get("score") or 0.0) for c in candidates if c.get("score") is not None]
|
|
51
52
|
if not scores:
|
|
52
|
-
return "ok"
|
|
53
|
-
|
|
54
|
-
# High-confidence override (dogfood R14 2026-05-01): a top-1 that
|
|
55
|
-
# significantly outranks the 2nd hit (gap ≥ 0.30 in normalised
|
|
56
|
-
# space) signals a unique winner — the structural reranker found
|
|
57
|
-
# one strong answer rather than many equal candidates. Skip the
|
|
58
|
-
# token-coverage check in that case.
|
|
59
|
-
# Distinguishes the email query ("where is email sending" →
|
|
60
|
-
# send_welcome at 0.900, 2nd at 0.275 → gap 0.625, real answer)
|
|
61
|
-
# from the trace query ("trace the login flow" → 1.014, 2nd 0.942
|
|
62
|
-
# → gap 0.072, all matching one common word).
|
|
53
|
+
return 0.50, "ok" # have candidates but no scores — neutral
|
|
54
|
+
|
|
63
55
|
top = scores[0]
|
|
64
56
|
second = scores[1] if len(scores) > 1 else 0.0
|
|
65
|
-
if top - second >= 0.30:
|
|
66
|
-
return "ok"
|
|
67
57
|
fifth = scores[min(4, len(scores) - 1)]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
58
|
+
|
|
59
|
+
# ---- Score-distribution signal ----
|
|
60
|
+
# A unique winner is the strongest signal: gap ≥ 0.30 → score 1.0;
|
|
61
|
+
# gap ≤ 0.05 → score 0.20; linear in between.
|
|
62
|
+
gap = top - second
|
|
63
|
+
if gap >= 0.30:
|
|
64
|
+
gap_signal = 1.0
|
|
65
|
+
elif gap <= 0.05:
|
|
66
|
+
gap_signal = 0.20
|
|
67
|
+
else:
|
|
68
|
+
gap_signal = 0.20 + 0.80 * (gap - 0.05) / 0.25
|
|
69
|
+
|
|
70
|
+
# Score floor: top < 0.30 with bunched tail → mostly noise.
|
|
71
|
+
if top < 0.20 or (top < 0.30 and (top - fifth) < 0.10):
|
|
72
|
+
floor_signal = 0.20
|
|
73
|
+
else:
|
|
74
|
+
floor_signal = min(1.0, top / 1.0) # top score itself is in [0,1+]
|
|
75
|
+
|
|
76
|
+
# ---- Token-coverage signal ----
|
|
77
|
+
coverage_signal = 1.0 # default: one-token queries can't fail this check
|
|
78
|
+
if task:
|
|
80
79
|
try:
|
|
81
80
|
from roam.retrieve.seeds import extract_tokens
|
|
82
81
|
|
|
@@ -85,33 +84,45 @@ def _retrieve_confidence(candidates: list[dict], task: str = "") -> str:
|
|
|
85
84
|
tokens = []
|
|
86
85
|
if len(tokens) >= 2:
|
|
87
86
|
lowered = {t.lower() for t in tokens if len(t) >= 4}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# → look for "detect", "implementing" → "implement".
|
|
103
|
-
# Length floor ≥7 means the prefix has ≥4 chars
|
|
104
|
-
# which is past the noise floor for path tokens.
|
|
105
|
-
if tok[:-3] in surface and len(tok[:-3]) >= 4:
|
|
87
|
+
if lowered:
|
|
88
|
+
covered: set[str] = set()
|
|
89
|
+
for c in candidates[:10]:
|
|
90
|
+
surface = (
|
|
91
|
+
(c.get("file_path") or c.get("file") or "")
|
|
92
|
+
+ " "
|
|
93
|
+
+ (c.get("name") or "")
|
|
94
|
+
+ " "
|
|
95
|
+
+ (c.get("qualified_name") or "")
|
|
96
|
+
).lower()
|
|
97
|
+
for tok in lowered:
|
|
98
|
+
if tok in surface:
|
|
99
|
+
covered.add(tok)
|
|
100
|
+
elif len(tok) >= 7 and tok[:-3] in surface and len(tok[:-3]) >= 4:
|
|
106
101
|
covered.add(tok)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
102
|
+
# Coverage as a fraction of query tokens, squared so a
|
|
103
|
+
# missing key word penalizes harder than linear. Without
|
|
104
|
+
# this, "trace the login flow" (2/3 covered — "login"
|
|
105
|
+
# missing) scored ``coverage_signal=0.67`` and the result
|
|
106
|
+
# crossed the "ok" threshold, even though the missing
|
|
107
|
+
# word was the actual subject. Squaring drops 0.67 → 0.45,
|
|
108
|
+
# 1/3 → 0.11, 3/3 → 1.0 — preserving precision when all
|
|
109
|
+
# tokens land while pushing partial-coverage queries
|
|
110
|
+
# below the low-confidence threshold.
|
|
111
|
+
coverage_signal = (len(covered) / len(lowered)) ** 2
|
|
112
|
+
|
|
113
|
+
# Combine — weighted geometric mean preserves the "any signal at
|
|
114
|
+
# the floor crashes the result" property of the old binary check
|
|
115
|
+
# while letting strong signals compose.
|
|
116
|
+
confidence = (gap_signal * 0.35) + (floor_signal * 0.25) + (coverage_signal * 0.40)
|
|
117
|
+
confidence = max(0.0, min(1.0, confidence))
|
|
118
|
+
label = "low" if confidence < 0.40 else "ok"
|
|
119
|
+
return round(confidence, 3), label
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _retrieve_confidence(candidates: list[dict], task: str = "") -> str:
|
|
123
|
+
"""Backwards-compat shim — returns just the string label."""
|
|
124
|
+
_, label = _retrieve_confidence_score(candidates, task)
|
|
125
|
+
return label
|
|
115
126
|
|
|
116
127
|
|
|
117
128
|
@click.command()
|
|
@@ -177,10 +188,29 @@ def retrieve(ctx, task, budget, k, rerank, seed_files, dry_run):
|
|
|
177
188
|
ensure_index()
|
|
178
189
|
|
|
179
190
|
cfg = get_retrieve_config()
|
|
180
|
-
effective_budget = budget if budget is not None else (cli_budget or cfg.get("default_budget", 4000))
|
|
181
191
|
effective_k = k if k is not None else cfg.get("default_k", 20)
|
|
182
192
|
effective_rerank = (rerank or cfg.get("default_rerank", "fast")).lower()
|
|
183
193
|
|
|
194
|
+
# 12.13 — adaptive budget. The fixed 4000-token default was a
|
|
195
|
+
# one-size-fits-all guess; a query with ``--k 5`` only needs
|
|
196
|
+
# ~1500 tokens to surface 5 spans, while ``--k 50`` would
|
|
197
|
+
# truncate against 4000. Scale proportionally to k, with a floor
|
|
198
|
+
# of 1500 (smallest useful answer) and ceiling at the configured
|
|
199
|
+
# default for the standard k=20 path so legacy behaviour is
|
|
200
|
+
# preserved exactly. Explicit ``--budget`` always wins.
|
|
201
|
+
if budget is not None:
|
|
202
|
+
effective_budget = budget
|
|
203
|
+
elif cli_budget:
|
|
204
|
+
effective_budget = cli_budget
|
|
205
|
+
else:
|
|
206
|
+
config_budget = cfg.get("default_budget", 4000)
|
|
207
|
+
# 200 tokens per result is the empirical mean span size on
|
|
208
|
+
# the 30-task self-bench. max() floors small-k queries; we
|
|
209
|
+
# cap at 2× config_budget so a runaway --k 200 doesn't burn
|
|
210
|
+
# 40k tokens.
|
|
211
|
+
adaptive = max(1500, effective_k * 200)
|
|
212
|
+
effective_budget = min(adaptive, config_budget * 2)
|
|
213
|
+
|
|
184
214
|
with open_db(readonly=True) as conn:
|
|
185
215
|
# Defensive guard: if symbol_fts has been wiped (rare, but seen
|
|
186
216
|
# mid-session after schema migrations on cloud-synced repos), the
|
|
@@ -249,7 +279,7 @@ def retrieve(ctx, task, budget, k, rerank, seed_files, dry_run):
|
|
|
249
279
|
}
|
|
250
280
|
stripped.append(keep)
|
|
251
281
|
candidates = stripped
|
|
252
|
-
confidence =
|
|
282
|
+
confidence_score, confidence = _retrieve_confidence_score(candidates, task_str)
|
|
253
283
|
base_verdict = (
|
|
254
284
|
f"{len(candidates)} span{'s' if len(candidates) != 1 else ''} "
|
|
255
285
|
f"({result['budget_used']}/{result['budget']} tokens, "
|
|
@@ -266,7 +296,13 @@ def retrieve(ctx, task, budget, k, rerank, seed_files, dry_run):
|
|
|
266
296
|
# rather than concentrated on a real match. The string formatting
|
|
267
297
|
# is centralised in :mod:`roam.output.confidence` (v12.12) so future
|
|
268
298
|
# commands surface the same shape.
|
|
299
|
+
# Phase-bonus 2026-05-04 — append the calibrated confidence
|
|
300
|
+
# number to the verdict so agents can branch on a continuous
|
|
301
|
+
# signal instead of a binary low/ok. The label-prefix shape is
|
|
302
|
+
# preserved for backwards compat.
|
|
269
303
|
verdict = verdict_prefix(base_verdict, confidence == "low")
|
|
304
|
+
if candidates:
|
|
305
|
+
verdict = f"{verdict} (confidence {confidence_score:.2f})"
|
|
270
306
|
|
|
271
307
|
if json_mode:
|
|
272
308
|
click.echo(
|
|
@@ -276,6 +312,7 @@ def retrieve(ctx, task, budget, k, rerank, seed_files, dry_run):
|
|
|
276
312
|
summary={
|
|
277
313
|
"verdict": verdict,
|
|
278
314
|
"low_confidence": confidence == "low",
|
|
315
|
+
"confidence": confidence_score,
|
|
279
316
|
"candidates": len(candidates),
|
|
280
317
|
"total_candidates": result["total_candidates"],
|
|
281
318
|
"budget": result["budget"],
|
|
@@ -49,6 +49,7 @@ def _top_symbols(conn, G, limit=10):
|
|
|
49
49
|
rows = conn.execute(
|
|
50
50
|
"""SELECT gm.symbol_id, gm.pagerank, gm.in_degree, gm.out_degree,
|
|
51
51
|
s.name, s.qualified_name, s.kind, f.path, s.line_start,
|
|
52
|
+
s.docstring,
|
|
52
53
|
COALESCE(f.file_role, 'source') AS file_role
|
|
53
54
|
FROM graph_metrics gm
|
|
54
55
|
JOIN symbols s ON gm.symbol_id = s.id
|
|
@@ -112,6 +113,15 @@ def _top_symbols(conn, G, limit=10):
|
|
|
112
113
|
role = "Leaf"
|
|
113
114
|
else:
|
|
114
115
|
role = "Internal"
|
|
116
|
+
# 12.13 — surface a docstring excerpt for newcomers. Pure
|
|
117
|
+
# PageRank ranks plumbing functions (open_db, json_envelope)
|
|
118
|
+
# at the top because every command imports them. The
|
|
119
|
+
# docstring excerpt keeps that ranking but tells the reader
|
|
120
|
+
# *what* each top symbol does, so utility-heavy lists still
|
|
121
|
+
# carry orientation signal.
|
|
122
|
+
doc = r["docstring"] or ""
|
|
123
|
+
first_sentence = doc.split("\n\n", 1)[0].strip()
|
|
124
|
+
first_line = " ".join(first_sentence.split())[:60]
|
|
115
125
|
results.append(
|
|
116
126
|
{
|
|
117
127
|
"name": r["qualified_name"] or r["name"],
|
|
@@ -121,6 +131,7 @@ def _top_symbols(conn, G, limit=10):
|
|
|
121
131
|
"fan_out": out_d,
|
|
122
132
|
"pagerank": round(r["pagerank"] or 0, 4),
|
|
123
133
|
"location": loc(r["path"], r["line_start"]),
|
|
134
|
+
"summary": first_line,
|
|
124
135
|
}
|
|
125
136
|
)
|
|
126
137
|
return results
|
|
@@ -448,12 +459,20 @@ def tour(ctx, write_file, mermaid_mode):
|
|
|
448
459
|
lines.append(f"**Avg file health:** {stats['avg_file_health']}/10")
|
|
449
460
|
lines.append("")
|
|
450
461
|
|
|
451
|
-
# Top symbols
|
|
462
|
+
# Top symbols. 12.13 — append a one-line docstring summary
|
|
463
|
+
# for each. Pure-PageRank ranking surfaces plumbing functions
|
|
464
|
+
# (open_db, json_envelope) at the top; the summary tells the
|
|
465
|
+
# newcomer what each does so the list still carries
|
|
466
|
+
# orientation signal even when it's utility-heavy.
|
|
452
467
|
lines.append("## Key Symbols (learn these first)\n")
|
|
453
|
-
lines.append(f"{'Symbol':<40} {'Kind':<6} {'Role':<14} {'Fan-in':<8} {'Location'}")
|
|
454
|
-
lines.append(f"{'-' * 40} {'-' * 6} {'-' * 14} {'-' * 8} {'-' * 30}")
|
|
455
468
|
for s in top:
|
|
456
|
-
|
|
469
|
+
head = f" {s['kind']} {s['name']:<32} {s['location']}"
|
|
470
|
+
summary = s.get("summary") or ""
|
|
471
|
+
if summary:
|
|
472
|
+
lines.append(head)
|
|
473
|
+
lines.append(f" {summary}")
|
|
474
|
+
else:
|
|
475
|
+
lines.append(head)
|
|
457
476
|
lines.append("")
|
|
458
477
|
|
|
459
478
|
# Reading order
|
|
@@ -122,13 +122,31 @@ def uses(ctx, name, full):
|
|
|
122
122
|
target_ids,
|
|
123
123
|
).fetchall()
|
|
124
124
|
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
# 12.13 perf — only scan test files for text mentions when the
|
|
126
|
+
# target lives in a language where the symbol resolver leaves
|
|
127
|
+
# gaps (JS / TS / Vue / Svelte). Python / Go / Rust resolvers
|
|
128
|
+
# already produce edges for every test reference, so the
|
|
129
|
+
# fallback was just a 4-second-per-call no-op on those repos
|
|
130
|
+
# (590 file reads against this Python repo to find the same
|
|
131
|
+
# answer the edges table already had). Skipping it on
|
|
132
|
+
# languages that don't need it brings ``roam uses`` from
|
|
133
|
+
# ~700ms warm to ~120ms.
|
|
134
|
+
target_langs = {(t["qualified_name"] or "").split(".", 1)[0] for t in targets}
|
|
135
|
+
target_files = conn.execute(
|
|
136
|
+
f"SELECT DISTINCT f.language FROM symbols s JOIN files f ON s.file_id = f.id "
|
|
137
|
+
f"WHERE s.id IN ({placeholders})",
|
|
138
|
+
target_ids,
|
|
139
|
+
).fetchall()
|
|
140
|
+
target_langs = {(r["language"] or "").lower() for r in target_files}
|
|
141
|
+
_JS_FAMILY = {"javascript", "typescript", "tsx", "jsx", "vue", "svelte"}
|
|
142
|
+
if target_langs & _JS_FAMILY:
|
|
143
|
+
rows.extend(
|
|
144
|
+
_test_text_consumers(
|
|
145
|
+
conn,
|
|
146
|
+
name,
|
|
147
|
+
{r["path"] for r in rows if is_test_file(r["path"])},
|
|
148
|
+
)
|
|
130
149
|
)
|
|
131
|
-
)
|
|
132
150
|
|
|
133
151
|
if not rows:
|
|
134
152
|
if json_mode:
|
|
@@ -1364,7 +1364,7 @@ MAP_METADATA: dict[str, dict[str, object]] = {
|
|
|
1364
1364
|
"peer": True,
|
|
1365
1365
|
"graph": "PageRank + Tarjan + Louvain + layers",
|
|
1366
1366
|
"note": "Graph algorithms (PageRank, SCC, Louvain, Fiedler) on tree-sitter ASTs fused with git history in SQLite. 122 MCP tools, 155 CLI commands. 19 Python idiom detectors (v12.7+).",
|
|
1367
|
-
"version_evaluated": "12.
|
|
1367
|
+
"version_evaluated": "12.13",
|
|
1368
1368
|
"repo_url": "https://github.com/Cranot/roam-code",
|
|
1369
1369
|
},
|
|
1370
1370
|
"CKB/CodeMCP": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://schemas.modelcontextprotocol.io/server-card/v1",
|
|
3
3
|
"name": "roam-code",
|
|
4
4
|
"display_name": "roam — instant codebase intelligence",
|
|
5
|
-
"version": "12.
|
|
5
|
+
"version": "12.13",
|
|
6
6
|
"description": "Architectural sight for AI agents before they edit. Pre-indexes symbols, call graphs, dependencies, architecture layers, and git history into a local SQLite DB. 122 MCP tools, 10 resources, 5 prompts, 27 languages. 100% local, zero API keys.",
|
|
7
7
|
"vendor": {
|
|
8
8
|
"name": "Cranot",
|