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.
Files changed (583) hide show
  1. {roam_code-12.12.8/src/roam_code.egg-info → roam_code-12.13}/PKG-INFO +1 -1
  2. {roam_code-12.12.8 → roam_code-12.13}/pyproject.toml +1 -1
  3. {roam_code-12.12.8 → roam_code-12.13}/src/roam/cli.py +62 -5
  4. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_coverage_gaps.py +9 -2
  5. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_impact.py +23 -2
  6. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_retrieve.py +111 -74
  7. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_tour.py +23 -4
  8. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_uses.py +24 -6
  9. {roam_code-12.12.8 → roam_code-12.13}/src/roam/competitor_site_data.py +1 -1
  10. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp-server-card.json +1 -1
  11. {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/rerank.py +125 -0
  12. {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/seeds.py +79 -0
  13. {roam_code-12.12.8 → roam_code-12.13/src/roam_code.egg-info}/PKG-INFO +1 -1
  14. {roam_code-12.12.8 → roam_code-12.13}/tests/test_retrieve.py +12 -3
  15. {roam_code-12.12.8 → roam_code-12.13}/LICENSE +0 -0
  16. {roam_code-12.12.8 → roam_code-12.13}/README.md +0 -0
  17. {roam_code-12.12.8 → roam_code-12.13}/setup.cfg +0 -0
  18. {roam_code-12.12.8 → roam_code-12.13}/src/roam/__init__.py +0 -0
  19. {roam_code-12.12.8 → roam_code-12.13}/src/roam/__main__.py +0 -0
  20. {roam_code-12.12.8 → roam_code-12.13}/src/roam/analysis/__init__.py +0 -0
  21. {roam_code-12.12.8 → roam_code-12.13}/src/roam/analysis/effects.py +0 -0
  22. {roam_code-12.12.8 → roam_code-12.13}/src/roam/analysis/taint.py +0 -0
  23. {roam_code-12.12.8 → roam_code-12.13}/src/roam/api.py +0 -0
  24. {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/__init__.py +0 -0
  25. {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/classifier.py +0 -0
  26. {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/recipes.py +0 -0
  27. {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/runner.py +0 -0
  28. {roam_code-12.12.8 → roam_code-12.13}/src/roam/ask/workflow.py +0 -0
  29. {roam_code-12.12.8 → roam_code-12.13}/src/roam/attest/__init__.py +0 -0
  30. {roam_code-12.12.8 → roam_code-12.13}/src/roam/attest/cga.py +0 -0
  31. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/__init__.py +0 -0
  32. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/base.py +0 -0
  33. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_config.py +0 -0
  34. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_django.py +0 -0
  35. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_protobuf.py +0 -0
  36. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_rest_api.py +0 -0
  37. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_salesforce.py +0 -0
  38. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/bridge_template.py +0 -0
  39. {roam_code-12.12.8 → roam_code-12.13}/src/roam/bridges/registry.py +0 -0
  40. {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/__init__.py +0 -0
  41. {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/detectors.py +0 -0
  42. {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/fixes.py +0 -0
  43. {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/python_idioms.py +0 -0
  44. {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/smells.py +0 -0
  45. {roam_code-12.12.8 → roam_code-12.13}/src/roam/catalog/tasks.py +0 -0
  46. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/__init__.py +0 -0
  47. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/changed_files.py +0 -0
  48. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_adrs.py +0 -0
  49. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_adversarial.py +0 -0
  50. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_affected.py +0 -0
  51. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_affected_tests.py +0 -0
  52. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_agent_context.py +0 -0
  53. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_agent_export.py +0 -0
  54. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_agent_plan.py +0 -0
  55. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ai_ratio.py +0 -0
  56. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ai_readiness.py +0 -0
  57. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_alerts.py +0 -0
  58. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_annotate.py +0 -0
  59. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_api_changes.py +0 -0
  60. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_api_drift.py +0 -0
  61. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ask.py +0 -0
  62. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_attest.py +0 -0
  63. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_auth_gaps.py +0 -0
  64. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_bisect.py +0 -0
  65. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_breaking.py +0 -0
  66. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_budget.py +0 -0
  67. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_bus_factor.py +0 -0
  68. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_capsule.py +0 -0
  69. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_cga.py +0 -0
  70. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_check_rules.py +0 -0
  71. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ci_setup.py +0 -0
  72. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_clean.py +0 -0
  73. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_clones.py +0 -0
  74. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_closure.py +0 -0
  75. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_clusters.py +0 -0
  76. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_codeowners.py +0 -0
  77. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_complexity.py +0 -0
  78. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_config.py +0 -0
  79. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_congestion.py +0 -0
  80. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_context.py +0 -0
  81. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_conventions.py +0 -0
  82. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_coupling.py +0 -0
  83. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_critique.py +0 -0
  84. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_cut.py +0 -0
  85. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dark_matter.py +0 -0
  86. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dashboard.py +0 -0
  87. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dead.py +0 -0
  88. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_debt.py +0 -0
  89. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_deps.py +0 -0
  90. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_describe.py +0 -0
  91. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_dev_profile.py +0 -0
  92. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_diagnose.py +0 -0
  93. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_diff.py +0 -0
  94. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_doc_staleness.py +0 -0
  95. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_docs_coverage.py +0 -0
  96. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_doctor.py +0 -0
  97. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_drift.py +0 -0
  98. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_duplicates.py +0 -0
  99. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_effects.py +0 -0
  100. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_endpoints.py +0 -0
  101. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_entry_points.py +0 -0
  102. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_eval_retrieve.py +0 -0
  103. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fan.py +0 -0
  104. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_file.py +0 -0
  105. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fingerprint.py +0 -0
  106. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fitness.py +0 -0
  107. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_flag_dead.py +0 -0
  108. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fleet.py +0 -0
  109. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_fn_coupling.py +0 -0
  110. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_forecast.py +0 -0
  111. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_grep.py +0 -0
  112. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_guard.py +0 -0
  113. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_health.py +0 -0
  114. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_hooks.py +0 -0
  115. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_hotspots.py +0 -0
  116. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_hover.py +0 -0
  117. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_index.py +0 -0
  118. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_index_bundle.py +0 -0
  119. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ingest_trace.py +0 -0
  120. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_init.py +0 -0
  121. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_intent.py +0 -0
  122. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_invariants.py +0 -0
  123. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_layers.py +0 -0
  124. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_map.py +0 -0
  125. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_math.py +0 -0
  126. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_mcp_setup.py +0 -0
  127. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_metrics.py +0 -0
  128. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_migration_safety.py +0 -0
  129. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_minimap.py +0 -0
  130. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_missing_index.py +0 -0
  131. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_module.py +0 -0
  132. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_mutate.py +0 -0
  133. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_n1.py +0 -0
  134. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_oracle.py +0 -0
  135. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_orchestrate.py +0 -0
  136. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_orphan_routes.py +0 -0
  137. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_over_fetch.py +0 -0
  138. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_owner.py +0 -0
  139. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_partition.py +0 -0
  140. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_path_coverage.py +0 -0
  141. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_patterns.py +0 -0
  142. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_plan.py +0 -0
  143. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_plan_refactor.py +0 -0
  144. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_pr_diff.py +0 -0
  145. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_pr_risk.py +0 -0
  146. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_preflight.py +0 -0
  147. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_py_modern.py +0 -0
  148. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_py_types.py +0 -0
  149. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_pytest_fixtures.py +0 -0
  150. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_relate.py +0 -0
  151. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_report.py +0 -0
  152. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_reset.py +0 -0
  153. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_risk.py +0 -0
  154. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_rules.py +0 -0
  155. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_safe_delete.py +0 -0
  156. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_safe_zones.py +0 -0
  157. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_sbom.py +0 -0
  158. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_schema.py +0 -0
  159. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_search.py +0 -0
  160. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_search_semantic.py +0 -0
  161. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_secrets.py +0 -0
  162. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_semantic_diff.py +0 -0
  163. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_simulate.py +0 -0
  164. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_simulate_departure.py +0 -0
  165. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_sketch.py +0 -0
  166. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_smells.py +0 -0
  167. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_spectral.py +0 -0
  168. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_split.py +0 -0
  169. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
  170. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
  171. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_supply_chain.py +0 -0
  172. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_symbol.py +0 -0
  173. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_syntax_check.py +0 -0
  174. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_taint.py +0 -0
  175. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_test_gaps.py +0 -0
  176. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_test_scaffold.py +0 -0
  177. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_testmap.py +0 -0
  178. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_trace.py +0 -0
  179. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_trends.py +0 -0
  180. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_triage.py +0 -0
  181. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_understand.py +0 -0
  182. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_verify.py +0 -0
  183. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_verify_imports.py +0 -0
  184. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vibe_check.py +0 -0
  185. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_visualize.py +0 -0
  186. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vuln_map.py +0 -0
  187. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vuln_reach.py +0 -0
  188. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_vulns.py +0 -0
  189. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_watch.py +0 -0
  190. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_weather.py +0 -0
  191. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_why.py +0 -0
  192. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_workflow.py +0 -0
  193. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_ws.py +0 -0
  194. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/cmd_xlang.py +0 -0
  195. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/codeowners_helpers.py +0 -0
  196. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/context_helpers.py +0 -0
  197. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/gate_presets.py +0 -0
  198. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/graph_helpers.py +0 -0
  199. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/metrics_history.py +0 -0
  200. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/next_steps.py +0 -0
  201. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/resolve.py +0 -0
  202. {roam_code-12.12.8 → roam_code-12.13}/src/roam/commands/suppression.py +0 -0
  203. {roam_code-12.12.8 → roam_code-12.13}/src/roam/config.py +0 -0
  204. {roam_code-12.12.8 → roam_code-12.13}/src/roam/coverage_reports.py +0 -0
  205. {roam_code-12.12.8 → roam_code-12.13}/src/roam/critique/__init__.py +0 -0
  206. {roam_code-12.12.8 → roam_code-12.13}/src/roam/critique/aggregator.py +0 -0
  207. {roam_code-12.12.8 → roam_code-12.13}/src/roam/critique/checks.py +0 -0
  208. {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/__init__.py +0 -0
  209. {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/connection.py +0 -0
  210. {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/queries.py +0 -0
  211. {roam_code-12.12.8 → roam_code-12.13}/src/roam/db/schema.py +0 -0
  212. {roam_code-12.12.8 → roam_code-12.13}/src/roam/eval/__init__.py +0 -0
  213. {roam_code-12.12.8 → roam_code-12.13}/src/roam/eval/harness.py +0 -0
  214. {roam_code-12.12.8 → roam_code-12.13}/src/roam/exit_codes.py +0 -0
  215. {roam_code-12.12.8 → roam_code-12.13}/src/roam/fleet/__init__.py +0 -0
  216. {roam_code-12.12.8 → roam_code-12.13}/src/roam/fleet/adapters.py +0 -0
  217. {roam_code-12.12.8 → roam_code-12.13}/src/roam/fleet/manifest.py +0 -0
  218. {roam_code-12.12.8 → roam_code-12.13}/src/roam/git_utils.py +0 -0
  219. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/__init__.py +0 -0
  220. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/anomaly.py +0 -0
  221. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/builder.py +0 -0
  222. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/clone_detect.py +0 -0
  223. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/clusters.py +0 -0
  224. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/cycles.py +0 -0
  225. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/dark_matter.py +0 -0
  226. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/diff.py +0 -0
  227. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/fingerprint.py +0 -0
  228. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/layers.py +0 -0
  229. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/pagerank.py +0 -0
  230. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/partition.py +0 -0
  231. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/pathfinding.py +0 -0
  232. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/propagation.py +0 -0
  233. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/simulate.py +0 -0
  234. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/spectral.py +0 -0
  235. {roam_code-12.12.8 → roam_code-12.13}/src/roam/graph/stats.py +0 -0
  236. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/__init__.py +0 -0
  237. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/complexity.py +0 -0
  238. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/discovery.py +0 -0
  239. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/django_post.py +0 -0
  240. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/file_roles.py +0 -0
  241. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/git_stats.py +0 -0
  242. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/gitignore.py +0 -0
  243. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/incremental.py +0 -0
  244. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/indexer.py +0 -0
  245. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/parser.py +0 -0
  246. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/pytest_fixtures.py +0 -0
  247. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/registry_dispatch.py +0 -0
  248. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/relations.py +0 -0
  249. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/symbols.py +0 -0
  250. {roam_code-12.12.8 → roam_code-12.13}/src/roam/index/test_conventions.py +0 -0
  251. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/__init__.py +0 -0
  252. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/apex_lang.py +0 -0
  253. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/aura_lang.py +0 -0
  254. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/base.py +0 -0
  255. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/c_lang.py +0 -0
  256. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/csharp_lang.py +0 -0
  257. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/extractor_schema.py +0 -0
  258. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/extractors/kotlin.yaml +0 -0
  259. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/foxpro_lang.py +0 -0
  260. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/generic_lang.py +0 -0
  261. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/go_lang.py +0 -0
  262. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/hcl_lang.py +0 -0
  263. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/java_lang.py +0 -0
  264. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/javascript_lang.py +0 -0
  265. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/kotlin_lang.py +0 -0
  266. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/php_lang.py +0 -0
  267. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/python_lang.py +0 -0
  268. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/query_engine.py +0 -0
  269. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/registry.py +0 -0
  270. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/ruby_lang.py +0 -0
  271. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/rust_lang.py +0 -0
  272. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/scala_lang.py +0 -0
  273. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/sfxml_lang.py +0 -0
  274. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/sql_lang.py +0 -0
  275. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/swift_lang.py +0 -0
  276. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/typescript_lang.py +0 -0
  277. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/visualforce_lang.py +0 -0
  278. {roam_code-12.12.8 → roam_code-12.13}/src/roam/languages/yaml_lang.py +0 -0
  279. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/__init__.py +0 -0
  280. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/completions.py +0 -0
  281. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/concurrency.py +0 -0
  282. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/progress.py +0 -0
  283. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/sampling.py +0 -0
  284. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/session.py +0 -0
  285. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_extras/watcher.py +0 -0
  286. {roam_code-12.12.8 → roam_code-12.13}/src/roam/mcp_server.py +0 -0
  287. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/__init__.py +0 -0
  288. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/confidence.py +0 -0
  289. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/errors.py +0 -0
  290. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/file_role_hints.py +0 -0
  291. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/formatter.py +0 -0
  292. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/framework_filter.py +0 -0
  293. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/mermaid.py +0 -0
  294. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/project_shape.py +0 -0
  295. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/sarif.py +0 -0
  296. {roam_code-12.12.8 → roam_code-12.13}/src/roam/output/schema_registry.py +0 -0
  297. {roam_code-12.12.8 → roam_code-12.13}/src/roam/plugins.py +0 -0
  298. {roam_code-12.12.8 → roam_code-12.13}/src/roam/refactor/__init__.py +0 -0
  299. {roam_code-12.12.8 → roam_code-12.13}/src/roam/refactor/codegen.py +0 -0
  300. {roam_code-12.12.8 → roam_code-12.13}/src/roam/refactor/transforms.py +0 -0
  301. {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/__init__.py +0 -0
  302. {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/learned_ranker.py +0 -0
  303. {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/pipeline.py +0 -0
  304. {roam_code-12.12.8 → roam_code-12.13}/src/roam/retrieve/semantic.py +0 -0
  305. {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/__init__.py +0 -0
  306. {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/ast_match.py +0 -0
  307. {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/builtin.py +0 -0
  308. {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/dataflow.py +0 -0
  309. {roam_code-12.12.8 → roam_code-12.13}/src/roam/rules/engine.py +0 -0
  310. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/__init__.py +0 -0
  311. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/daemon.py +0 -0
  312. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/graph_backend.py +0 -0
  313. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/hotspots.py +0 -0
  314. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/lock_modes.py +0 -0
  315. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/lockmgr.py +0 -0
  316. {roam_code-12.12.8 → roam_code-12.13}/src/roam/runtime/trace_ingest.py +0 -0
  317. {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/__init__.py +0 -0
  318. {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/framework_packs.py +0 -0
  319. {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/index_embeddings.py +0 -0
  320. {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/onnx_embeddings.py +0 -0
  321. {roam_code-12.12.8 → roam_code-12.13}/src/roam/search/tfidf.py +0 -0
  322. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/__init__.py +0 -0
  323. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/aibom_extension.py +0 -0
  324. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_classifier.py +0 -0
  325. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_engine.py +0 -0
  326. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/api_error_leak.yaml +0 -0
  327. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/java_fileupload_path_traversal.yaml +0 -0
  328. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_insecure_jwt_decode.yaml +0 -0
  329. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_localstorage_secrets.yaml +0 -0
  330. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_prototype_pollution.yaml +0 -0
  331. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_ssrf.yaml +0 -0
  332. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/js_xss.yaml +0 -0
  333. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_basic.yaml +0 -0
  334. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_deserialization.yaml +0 -0
  335. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_path_traversal.yaml +0 -0
  336. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_socketio_remote_source.yaml +0 -0
  337. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_sqli.yaml +0 -0
  338. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/python_urllib_open_redirect.yaml +0 -0
  339. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/taint_rules/vue_v_html.yaml +0 -0
  340. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/vuln_reach.py +0 -0
  341. {roam_code-12.12.8 → roam_code-12.13}/src/roam/security/vuln_store.py +0 -0
  342. {roam_code-12.12.8 → roam_code-12.13}/src/roam/surface_counts.py +0 -0
  343. {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/__init__.py +0 -0
  344. {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/Jenkinsfile +0 -0
  345. {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/__init__.py +0 -0
  346. {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/azure-pipelines.yml +0 -0
  347. {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/bitbucket-pipelines.yml +0 -0
  348. {roam_code-12.12.8 → roam_code-12.13}/src/roam/templates/ci/gitlab-ci.yml +0 -0
  349. {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/__init__.py +0 -0
  350. {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/aggregator.py +0 -0
  351. {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/api_scanner.py +0 -0
  352. {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/config.py +0 -0
  353. {roam_code-12.12.8 → roam_code-12.13}/src/roam/workspace/db.py +0 -0
  354. {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/SOURCES.txt +0 -0
  355. {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/dependency_links.txt +0 -0
  356. {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/entry_points.txt +0 -0
  357. {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/requires.txt +0 -0
  358. {roam_code-12.12.8 → roam_code-12.13}/src/roam_code.egg-info/top_level.txt +0 -0
  359. {roam_code-12.12.8 → roam_code-12.13}/tests/test_adrs.py +0 -0
  360. {roam_code-12.12.8 → roam_code-12.13}/tests/test_adversarial.py +0 -0
  361. {roam_code-12.12.8 → roam_code-12.13}/tests/test_affected.py +0 -0
  362. {roam_code-12.12.8 → roam_code-12.13}/tests/test_agent_export.py +0 -0
  363. {roam_code-12.12.8 → roam_code-12.13}/tests/test_agent_mode.py +0 -0
  364. {roam_code-12.12.8 → roam_code-12.13}/tests/test_agent_plan_context.py +0 -0
  365. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ai_ratio.py +0 -0
  366. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ai_readiness.py +0 -0
  367. {roam_code-12.12.8 → roam_code-12.13}/tests/test_alerts_cmd.py +0 -0
  368. {roam_code-12.12.8 → roam_code-12.13}/tests/test_annotations.py +0 -0
  369. {roam_code-12.12.8 → roam_code-12.13}/tests/test_anomaly.py +0 -0
  370. {roam_code-12.12.8 → roam_code-12.13}/tests/test_api_changes.py +0 -0
  371. {roam_code-12.12.8 → roam_code-12.13}/tests/test_api_drift.py +0 -0
  372. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ask.py +0 -0
  373. {roam_code-12.12.8 → roam_code-12.13}/tests/test_attest.py +0 -0
  374. {roam_code-12.12.8 → roam_code-12.13}/tests/test_auth_gaps.py +0 -0
  375. {roam_code-12.12.8 → roam_code-12.13}/tests/test_backend_fixes_round2.py +0 -0
  376. {roam_code-12.12.8 → roam_code-12.13}/tests/test_backend_fixes_round3.py +0 -0
  377. {roam_code-12.12.8 → roam_code-12.13}/tests/test_basic.py +0 -0
  378. {roam_code-12.12.8 → roam_code-12.13}/tests/test_batch_mcp.py +0 -0
  379. {roam_code-12.12.8 → roam_code-12.13}/tests/test_bisect.py +0 -0
  380. {roam_code-12.12.8 → roam_code-12.13}/tests/test_bridge_django.py +0 -0
  381. {roam_code-12.12.8 → roam_code-12.13}/tests/test_bridges.py +0 -0
  382. {roam_code-12.12.8 → roam_code-12.13}/tests/test_bridges_extended.py +0 -0
  383. {roam_code-12.12.8 → roam_code-12.13}/tests/test_budget.py +0 -0
  384. {roam_code-12.12.8 → roam_code-12.13}/tests/test_budget_flag.py +0 -0
  385. {roam_code-12.12.8 → roam_code-12.13}/tests/test_budget_phase2.py +0 -0
  386. {roam_code-12.12.8 → roam_code-12.13}/tests/test_bus_factor.py +0 -0
  387. {roam_code-12.12.8 → roam_code-12.13}/tests/test_capsule.py +0 -0
  388. {roam_code-12.12.8 → roam_code-12.13}/tests/test_cga.py +0 -0
  389. {roam_code-12.12.8 → roam_code-12.13}/tests/test_check_rules.py +0 -0
  390. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ci_gate_eval.py +0 -0
  391. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ci_sarif_guard.py +0 -0
  392. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ci_setup.py +0 -0
  393. {roam_code-12.12.8 → roam_code-12.13}/tests/test_clones.py +0 -0
  394. {roam_code-12.12.8 → roam_code-12.13}/tests/test_closure.py +0 -0
  395. {roam_code-12.12.8 → roam_code-12.13}/tests/test_codeowners.py +0 -0
  396. {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_architecture.py +0 -0
  397. {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_exploration.py +0 -0
  398. {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_health.py +0 -0
  399. {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_refactoring.py +0 -0
  400. {roam_code-12.12.8 → roam_code-12.13}/tests/test_commands_workflow.py +0 -0
  401. {roam_code-12.12.8 → roam_code-12.13}/tests/test_competitor_site_data.py +0 -0
  402. {roam_code-12.12.8 → roam_code-12.13}/tests/test_comprehensive.py +0 -0
  403. {roam_code-12.12.8 → roam_code-12.13}/tests/test_config.py +0 -0
  404. {roam_code-12.12.8 → roam_code-12.13}/tests/test_congestion.py +0 -0
  405. {roam_code-12.12.8 → roam_code-12.13}/tests/test_context_propagation.py +0 -0
  406. {roam_code-12.12.8 → roam_code-12.13}/tests/test_conventions_cmd.py +0 -0
  407. {roam_code-12.12.8 → roam_code-12.13}/tests/test_coverage_gaps_cmd.py +0 -0
  408. {roam_code-12.12.8 → roam_code-12.13}/tests/test_coverage_ingestion.py +0 -0
  409. {roam_code-12.12.8 → roam_code-12.13}/tests/test_critique.py +0 -0
  410. {roam_code-12.12.8 → roam_code-12.13}/tests/test_cut.py +0 -0
  411. {roam_code-12.12.8 → roam_code-12.13}/tests/test_dark_matter.py +0 -0
  412. {roam_code-12.12.8 → roam_code-12.13}/tests/test_dark_matter_helpers.py +0 -0
  413. {roam_code-12.12.8 → roam_code-12.13}/tests/test_dashboard.py +0 -0
  414. {roam_code-12.12.8 → roam_code-12.13}/tests/test_dataflow_dead.py +0 -0
  415. {roam_code-12.12.8 → roam_code-12.13}/tests/test_dead_aging.py +0 -0
  416. {roam_code-12.12.8 → roam_code-12.13}/tests/test_defer_loading.py +0 -0
  417. {roam_code-12.12.8 → roam_code-12.13}/tests/test_demo_gif_asset.py +0 -0
  418. {roam_code-12.12.8 → roam_code-12.13}/tests/test_describe.py +0 -0
  419. {roam_code-12.12.8 → roam_code-12.13}/tests/test_detail_flag_hints.py +0 -0
  420. {roam_code-12.12.8 → roam_code-12.13}/tests/test_detector_precision.py +0 -0
  421. {roam_code-12.12.8 → roam_code-12.13}/tests/test_deterministic_output.py +0 -0
  422. {roam_code-12.12.8 → roam_code-12.13}/tests/test_dev_profile.py +0 -0
  423. {roam_code-12.12.8 → roam_code-12.13}/tests/test_difficulty_scoring.py +0 -0
  424. {roam_code-12.12.8 → roam_code-12.13}/tests/test_doc_consistency.py +0 -0
  425. {roam_code-12.12.8 → roam_code-12.13}/tests/test_doc_staleness.py +0 -0
  426. {roam_code-12.12.8 → roam_code-12.13}/tests/test_docker_assets.py +0 -0
  427. {roam_code-12.12.8 → roam_code-12.13}/tests/test_docs_coverage.py +0 -0
  428. {roam_code-12.12.8 → roam_code-12.13}/tests/test_docs_site_quality.py +0 -0
  429. {roam_code-12.12.8 → roam_code-12.13}/tests/test_doctor.py +0 -0
  430. {roam_code-12.12.8 → roam_code-12.13}/tests/test_drift.py +0 -0
  431. {roam_code-12.12.8 → roam_code-12.13}/tests/test_drift_by_team.py +0 -0
  432. {roam_code-12.12.8 → roam_code-12.13}/tests/test_duplicates.py +0 -0
  433. {roam_code-12.12.8 → roam_code-12.13}/tests/test_effects.py +0 -0
  434. {roam_code-12.12.8 → roam_code-12.13}/tests/test_effects_propagation.py +0 -0
  435. {roam_code-12.12.8 → roam_code-12.13}/tests/test_endpoints.py +0 -0
  436. {roam_code-12.12.8 → roam_code-12.13}/tests/test_entry_points_cmd.py +0 -0
  437. {roam_code-12.12.8 → roam_code-12.13}/tests/test_eval_retrieve.py +0 -0
  438. {roam_code-12.12.8 → roam_code-12.13}/tests/test_except_pass_narrow.py +0 -0
  439. {roam_code-12.12.8 → roam_code-12.13}/tests/test_exclude_patterns.py +0 -0
  440. {roam_code-12.12.8 → roam_code-12.13}/tests/test_exit_codes.py +0 -0
  441. {roam_code-12.12.8 → roam_code-12.13}/tests/test_extractor_grammar_drift.py +0 -0
  442. {roam_code-12.12.8 → roam_code-12.13}/tests/test_fallback_contracts.py +0 -0
  443. {roam_code-12.12.8 → roam_code-12.13}/tests/test_file_roles.py +0 -0
  444. {roam_code-12.12.8 → roam_code-12.13}/tests/test_fingerprint.py +0 -0
  445. {roam_code-12.12.8 → roam_code-12.13}/tests/test_fixes.py +0 -0
  446. {roam_code-12.12.8 → roam_code-12.13}/tests/test_flag_dead.py +0 -0
  447. {roam_code-12.12.8 → roam_code-12.13}/tests/test_fleet.py +0 -0
  448. {roam_code-12.12.8 → roam_code-12.13}/tests/test_fn_coupling.py +0 -0
  449. {roam_code-12.12.8 → roam_code-12.13}/tests/test_forecast.py +0 -0
  450. {roam_code-12.12.8 → roam_code-12.13}/tests/test_formatters.py +0 -0
  451. {roam_code-12.12.8 → roam_code-12.13}/tests/test_foxpro.py +0 -0
  452. {roam_code-12.12.8 → roam_code-12.13}/tests/test_framework_detection.py +0 -0
  453. {roam_code-12.12.8 → roam_code-12.13}/tests/test_gate_presets.py +0 -0
  454. {roam_code-12.12.8 → roam_code-12.13}/tests/test_git_utils.py +0 -0
  455. {roam_code-12.12.8 → roam_code-12.13}/tests/test_guard.py +0 -0
  456. {roam_code-12.12.8 → roam_code-12.13}/tests/test_health_gate.py +0 -0
  457. {roam_code-12.12.8 → roam_code-12.13}/tests/test_hooks.py +0 -0
  458. {roam_code-12.12.8 → roam_code-12.13}/tests/test_hotspots.py +0 -0
  459. {roam_code-12.12.8 → roam_code-12.13}/tests/test_hover.py +0 -0
  460. {roam_code-12.12.8 → roam_code-12.13}/tests/test_index.py +0 -0
  461. {roam_code-12.12.8 → roam_code-12.13}/tests/test_index_bundle.py +0 -0
  462. {roam_code-12.12.8 → roam_code-12.13}/tests/test_init_cmd.py +0 -0
  463. {roam_code-12.12.8 → roam_code-12.13}/tests/test_install_check.py +0 -0
  464. {roam_code-12.12.8 → roam_code-12.13}/tests/test_intent.py +0 -0
  465. {roam_code-12.12.8 → roam_code-12.13}/tests/test_invariants.py +0 -0
  466. {roam_code-12.12.8 → roam_code-12.13}/tests/test_json_contracts.py +0 -0
  467. {roam_code-12.12.8 → roam_code-12.13}/tests/test_json_error_envelope.py +0 -0
  468. {roam_code-12.12.8 → roam_code-12.13}/tests/test_kotlin_swift_extractors.py +0 -0
  469. {roam_code-12.12.8 → roam_code-12.13}/tests/test_language_corpus.py +0 -0
  470. {roam_code-12.12.8 → roam_code-12.13}/tests/test_languages.py +0 -0
  471. {roam_code-12.12.8 → roam_code-12.13}/tests/test_library_api.py +0 -0
  472. {roam_code-12.12.8 → roam_code-12.13}/tests/test_math.py +0 -0
  473. {roam_code-12.12.8 → roam_code-12.13}/tests/test_math_tips.py +0 -0
  474. {roam_code-12.12.8 → roam_code-12.13}/tests/test_mcp_extras.py +0 -0
  475. {roam_code-12.12.8 → roam_code-12.13}/tests/test_mcp_server.py +0 -0
  476. {roam_code-12.12.8 → roam_code-12.13}/tests/test_mcp_setup.py +0 -0
  477. {roam_code-12.12.8 → roam_code-12.13}/tests/test_mermaid.py +0 -0
  478. {roam_code-12.12.8 → roam_code-12.13}/tests/test_metrics_cmd.py +0 -0
  479. {roam_code-12.12.8 → roam_code-12.13}/tests/test_migration_safety.py +0 -0
  480. {roam_code-12.12.8 → roam_code-12.13}/tests/test_minimap.py +0 -0
  481. {roam_code-12.12.8 → roam_code-12.13}/tests/test_missing_index.py +0 -0
  482. {roam_code-12.12.8 → roam_code-12.13}/tests/test_mutate.py +0 -0
  483. {roam_code-12.12.8 → roam_code-12.13}/tests/test_n1.py +0 -0
  484. {roam_code-12.12.8 → roam_code-12.13}/tests/test_next_steps.py +0 -0
  485. {roam_code-12.12.8 → roam_code-12.13}/tests/test_onboard.py +0 -0
  486. {roam_code-12.12.8 → roam_code-12.13}/tests/test_oracle.py +0 -0
  487. {roam_code-12.12.8 → roam_code-12.13}/tests/test_orchestrate.py +0 -0
  488. {roam_code-12.12.8 → roam_code-12.13}/tests/test_orphan_routes.py +0 -0
  489. {roam_code-12.12.8 → roam_code-12.13}/tests/test_oss_bench_harness.py +0 -0
  490. {roam_code-12.12.8 → roam_code-12.13}/tests/test_over_fetch.py +0 -0
  491. {roam_code-12.12.8 → roam_code-12.13}/tests/test_pagerank_truncation.py +0 -0
  492. {roam_code-12.12.8 → roam_code-12.13}/tests/test_partition.py +0 -0
  493. {roam_code-12.12.8 → roam_code-12.13}/tests/test_path_coverage.py +0 -0
  494. {roam_code-12.12.8 → roam_code-12.13}/tests/test_patterns_cmd.py +0 -0
  495. {roam_code-12.12.8 → roam_code-12.13}/tests/test_performance.py +0 -0
  496. {roam_code-12.12.8 → roam_code-12.13}/tests/test_personalized_pagerank.py +0 -0
  497. {roam_code-12.12.8 → roam_code-12.13}/tests/test_plan.py +0 -0
  498. {roam_code-12.12.8 → roam_code-12.13}/tests/test_plugin_discovery.py +0 -0
  499. {roam_code-12.12.8 → roam_code-12.13}/tests/test_pr_comment_script.py +0 -0
  500. {roam_code-12.12.8 → roam_code-12.13}/tests/test_pr_diff.py +0 -0
  501. {roam_code-12.12.8 → roam_code-12.13}/tests/test_pr_risk_author.py +0 -0
  502. {roam_code-12.12.8 → roam_code-12.13}/tests/test_progress.py +0 -0
  503. {roam_code-12.12.8 → roam_code-12.13}/tests/test_progressive_disclosure.py +0 -0
  504. {roam_code-12.12.8 → roam_code-12.13}/tests/test_properties.py +0 -0
  505. {roam_code-12.12.8 → roam_code-12.13}/tests/test_pytest_fixtures.py +0 -0
  506. {roam_code-12.12.8 → roam_code-12.13}/tests/test_python_extractor_v2.py +0 -0
  507. {roam_code-12.12.8 → roam_code-12.13}/tests/test_python_idioms_e2e.py +0 -0
  508. {roam_code-12.12.8 → roam_code-12.13}/tests/test_python_pivot.py +0 -0
  509. {roam_code-12.12.8 → roam_code-12.13}/tests/test_readme_surface_consistency.py +0 -0
  510. {roam_code-12.12.8 → roam_code-12.13}/tests/test_realworld_feedback.py +0 -0
  511. {roam_code-12.12.8 → roam_code-12.13}/tests/test_refactoring_intelligence.py +0 -0
  512. {roam_code-12.12.8 → roam_code-12.13}/tests/test_registry_dispatch.py +0 -0
  513. {roam_code-12.12.8 → roam_code-12.13}/tests/test_relate.py +0 -0
  514. {roam_code-12.12.8 → roam_code-12.13}/tests/test_report.py +0 -0
  515. {roam_code-12.12.8 → roam_code-12.13}/tests/test_reset_clean.py +0 -0
  516. {roam_code-12.12.8 → roam_code-12.13}/tests/test_resolve.py +0 -0
  517. {roam_code-12.12.8 → roam_code-12.13}/tests/test_retrieve_cross_repo.py +0 -0
  518. {roam_code-12.12.8 → roam_code-12.13}/tests/test_retrieve_seeds.py +0 -0
  519. {roam_code-12.12.8 → roam_code-12.13}/tests/test_risk.py +0 -0
  520. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ruby.py +0 -0
  521. {roam_code-12.12.8 → roam_code-12.13}/tests/test_rule_profiles.py +0 -0
  522. {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules.py +0 -0
  523. {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_ast_match.py +0 -0
  524. {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_community_pack.py +0 -0
  525. {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_dataflow.py +0 -0
  526. {roam_code-12.12.8 → roam_code-12.13}/tests/test_rules_symbol_requirements.py +0 -0
  527. {roam_code-12.12.8 → roam_code-12.13}/tests/test_runtime.py +0 -0
  528. {roam_code-12.12.8 → roam_code-12.13}/tests/test_runtime_score.py +0 -0
  529. {roam_code-12.12.8 → roam_code-12.13}/tests/test_salesforce.py +0 -0
  530. {roam_code-12.12.8 → roam_code-12.13}/tests/test_sarif_flag.py +0 -0
  531. {roam_code-12.12.8 → roam_code-12.13}/tests/test_sbom.py +0 -0
  532. {roam_code-12.12.8 → roam_code-12.13}/tests/test_scala.py +0 -0
  533. {roam_code-12.12.8 → roam_code-12.13}/tests/test_schema_versioning.py +0 -0
  534. {roam_code-12.12.8 → roam_code-12.13}/tests/test_search_explain.py +0 -0
  535. {roam_code-12.12.8 → roam_code-12.13}/tests/test_secrets.py +0 -0
  536. {roam_code-12.12.8 → roam_code-12.13}/tests/test_secrets_v2.py +0 -0
  537. {roam_code-12.12.8 → roam_code-12.13}/tests/test_semantic_diff.py +0 -0
  538. {roam_code-12.12.8 → roam_code-12.13}/tests/test_semantic_onnx.py +0 -0
  539. {roam_code-12.12.8 → roam_code-12.13}/tests/test_semantic_search.py +0 -0
  540. {roam_code-12.12.8 → roam_code-12.13}/tests/test_simulate.py +0 -0
  541. {roam_code-12.12.8 → roam_code-12.13}/tests/test_simulate_departure.py +0 -0
  542. {roam_code-12.12.8 → roam_code-12.13}/tests/test_sketch.py +0 -0
  543. {roam_code-12.12.8 → roam_code-12.13}/tests/test_smells.py +0 -0
  544. {roam_code-12.12.8 → roam_code-12.13}/tests/test_smoke.py +0 -0
  545. {roam_code-12.12.8 → roam_code-12.13}/tests/test_sna_metrics.py +0 -0
  546. {roam_code-12.12.8 → roam_code-12.13}/tests/test_spectral.py +0 -0
  547. {roam_code-12.12.8 → roam_code-12.13}/tests/test_split_cmd.py +0 -0
  548. {roam_code-12.12.8 → roam_code-12.13}/tests/test_sql.py +0 -0
  549. {roam_code-12.12.8 → roam_code-12.13}/tests/test_suggest_reviewers.py +0 -0
  550. {roam_code-12.12.8 → roam_code-12.13}/tests/test_supply_chain.py +0 -0
  551. {roam_code-12.12.8 → roam_code-12.13}/tests/test_surface_counts.py +0 -0
  552. {roam_code-12.12.8 → roam_code-12.13}/tests/test_syntax_check.py +0 -0
  553. {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint.py +0 -0
  554. {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint_analysis.py +0 -0
  555. {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint_classifier.py +0 -0
  556. {roam_code-12.12.8 → roam_code-12.13}/tests/test_taint_intraprocedural.py +0 -0
  557. {roam_code-12.12.8 → roam_code-12.13}/tests/test_test_conventions.py +0 -0
  558. {roam_code-12.12.8 → roam_code-12.13}/tests/test_test_gaps.py +0 -0
  559. {roam_code-12.12.8 → roam_code-12.13}/tests/test_test_scaffold.py +0 -0
  560. {roam_code-12.12.8 → roam_code-12.13}/tests/test_testmap.py +0 -0
  561. {roam_code-12.12.8 → roam_code-12.13}/tests/test_top_flag_consistency.py +0 -0
  562. {roam_code-12.12.8 → roam_code-12.13}/tests/test_tour_cmd.py +0 -0
  563. {roam_code-12.12.8 → roam_code-12.13}/tests/test_trends.py +0 -0
  564. {roam_code-12.12.8 → roam_code-12.13}/tests/test_trends_cohort.py +0 -0
  565. {roam_code-12.12.8 → roam_code-12.13}/tests/test_triage.py +0 -0
  566. {roam_code-12.12.8 → roam_code-12.13}/tests/test_uses_cmd.py +0 -0
  567. {roam_code-12.12.8 → roam_code-12.13}/tests/test_v12_2.py +0 -0
  568. {roam_code-12.12.8 → roam_code-12.13}/tests/test_v6_features.py +0 -0
  569. {roam_code-12.12.8 → roam_code-12.13}/tests/test_v71_features.py +0 -0
  570. {roam_code-12.12.8 → roam_code-12.13}/tests/test_v7_features.py +0 -0
  571. {roam_code-12.12.8 → roam_code-12.13}/tests/test_v82_features.py +0 -0
  572. {roam_code-12.12.8 → roam_code-12.13}/tests/test_verify.py +0 -0
  573. {roam_code-12.12.8 → roam_code-12.13}/tests/test_verify_imports.py +0 -0
  574. {roam_code-12.12.8 → roam_code-12.13}/tests/test_vibe_check.py +0 -0
  575. {roam_code-12.12.8 → roam_code-12.13}/tests/test_visualize.py +0 -0
  576. {roam_code-12.12.8 → roam_code-12.13}/tests/test_vuln.py +0 -0
  577. {roam_code-12.12.8 → roam_code-12.13}/tests/test_vulns_cmd.py +0 -0
  578. {roam_code-12.12.8 → roam_code-12.13}/tests/test_watch.py +0 -0
  579. {roam_code-12.12.8 → roam_code-12.13}/tests/test_why.py +0 -0
  580. {roam_code-12.12.8 → roam_code-12.13}/tests/test_workspace.py +0 -0
  581. {roam_code-12.12.8 → roam_code-12.13}/tests/test_ws_resolve_fixes.py +0 -0
  582. {roam_code-12.12.8 → roam_code-12.13}/tests/test_xlang.py +0 -0
  583. {roam_code-12.12.8 → roam_code-12.13}/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.12.8
3
+ Version: 12.13
4
4
  Summary: Instant codebase comprehension for AI coding agents
5
5
  Author: CosmoHac
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "roam-code"
7
- version = "12.12.8"
7
+ version = "12.13"
8
8
  description = "Instant codebase comprehension for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -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
- cmd = self.get_command(ctx, cmd_name)
519
- if cmd is None:
520
- continue
521
- help_text = cmd.get_short_help_str(limit=60) if cmd else ""
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("Provide --gate <names> or --gate-pattern <regex>")
440
- raise SystemExit(1)
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
- click.echo(f"\nAffected files ({len(affected_files)}):")
225
- for fp in sorted(affected_files)[:20]:
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 _retrieve_confidence(candidates: list[dict], task: str = "") -> str:
28
- """Classify the confidence of a retrieve result.
29
-
30
- Returns ``"low"`` when the top result probably doesn't match the
31
- query, ``"ok"`` otherwise. Heuristic (dogfood notes 2026-05-01,
32
- two iterations):
33
-
34
- * **Token coverage** count distinct query tokens that appear
35
- across the top-5 candidate paths. If only 1 token is covered
36
- across all 5 (e.g. "trace login flow" → only "trace" matches
37
- anywhere), the answer is almost certainly junk: the lexical
38
- hits are tracking one common word.
39
- * **Score signals** also flag when top score is < 0.30 AND
40
- top-vs-fifth spread is < 0.10 (scores bunched at the noise
41
- floor).
42
-
43
- Either signal trips low-confidence; the token-coverage check
44
- catches the original "trace the login flow" failure mode that
45
- the score-only heuristic missed (top was 1.1 but covered just
46
- one query token).
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
- if top < 0.30 and (top - fifth) < 0.10:
69
- return "low"
70
-
71
- # Token-coverage check across top-10 path+name. Match against both
72
- # path AND symbol name — a test like ``test_implements_edge`` in
73
- # ``test_comprehensive.py`` covers "implements" via name even though
74
- # the path doesn't. Trip low-confidence when ≥3 query tokens were
75
- # supplied but ≤1 of them surfaces *anywhere* in the top-10. That
76
- # catches "trace the login flow" (top-10 has "trace" everywhere
77
- # but never "login" or "flow") while letting "AST clone detection
78
- # implemented" pass (clone, implements, detect all surface).
79
- if task and candidates:
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
- 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:
101
- # Prefix match for plurals/derivations: "detection"
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
- # Trip when ≥2 query tokens were supplied but ≤1 covered
108
- # in top-10. Catches "trace login flow" (only "trace"
109
- # matches, "login"/"flow" never appear) without firing
110
- # on "AST clone detection implemented" where "clone" and
111
- # "implemented" both surface in top-10.
112
- if len(lowered) >= 2 and len(covered) <= 1:
113
- return "low"
114
- return "ok"
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 = _retrieve_confidence(candidates, task_str)
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
- lines.append(f"{s['name']:<40} {s['kind']:<6} {s['role']:<14} {s['fan_in']:<8} {s['location']}")
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
- rows.extend(
126
- _test_text_consumers(
127
- conn,
128
- name,
129
- {r["path"] for r in rows if is_test_file(r["path"])},
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.12.8",
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.12.8",
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",