roam-code 8.2.0__tar.gz → 9.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. {roam_code-8.2.0/src/roam_code.egg-info → roam_code-9.1.0}/PKG-INFO +45 -21
  2. {roam_code-8.2.0 → roam_code-9.1.0}/README.md +44 -20
  3. {roam_code-8.2.0 → roam_code-9.1.0}/pyproject.toml +1 -1
  4. roam_code-9.1.0/src/roam/catalog/detectors.py +959 -0
  5. roam_code-9.1.0/src/roam/catalog/tasks.py +246 -0
  6. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/cli.py +2 -1
  7. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_affected_tests.py +30 -3
  8. roam_code-9.1.0/src/roam/commands/cmd_clusters.py +315 -0
  9. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_dead.py +80 -87
  10. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_describe.py +82 -79
  11. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_health.py +11 -3
  12. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_impact.py +62 -68
  13. roam_code-9.1.0/src/roam/commands/cmd_layers.py +248 -0
  14. roam_code-9.1.0/src/roam/commands/cmd_math.py +130 -0
  15. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_module.py +55 -57
  16. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_pr_risk.py +85 -26
  17. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_understand.py +156 -98
  18. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_why.py +112 -112
  19. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/metrics_history.py +86 -50
  20. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/db/connection.py +6 -0
  21. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/db/schema.py +16 -0
  22. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/complexity.py +361 -5
  23. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/indexer.py +229 -246
  24. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/parser.py +2 -0
  25. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/relations.py +52 -39
  26. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/test_conventions.py +155 -0
  27. roam_code-9.1.0/src/roam/languages/csharp_lang.py +1126 -0
  28. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/foxpro_lang.py +129 -117
  29. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/generic_lang.py +107 -117
  30. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/javascript_lang.py +74 -91
  31. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/php_lang.py +31 -46
  32. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/python_lang.py +70 -49
  33. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/registry.py +5 -1
  34. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/mcp_server.py +28 -0
  35. roam_code-9.1.0/src/roam/output/__init__.py +0 -0
  36. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/workspace/db.py +0 -35
  37. {roam_code-8.2.0 → roam_code-9.1.0/src/roam_code.egg-info}/PKG-INFO +45 -21
  38. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam_code.egg-info/SOURCES.txt +7 -0
  39. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_anomaly.py +3 -3
  40. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_commands_health.py +26 -0
  41. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_commands_workflow.py +35 -0
  42. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_comprehensive.py +42 -25
  43. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_fixes.py +14 -14
  44. roam_code-9.1.0/tests/test_framework_detection.py +277 -0
  45. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_languages.py +641 -1
  46. roam_code-9.1.0/tests/test_math.py +853 -0
  47. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_pr_risk_author.py +31 -0
  48. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_python_extractor_v2.py +23 -0
  49. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_resolve.py +13 -13
  50. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_salesforce.py +4 -4
  51. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_test_conventions.py +76 -1
  52. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_v6_features.py +2 -2
  53. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_v7_features.py +4 -4
  54. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_visualize.py +4 -4
  55. roam_code-8.2.0/src/roam/commands/cmd_clusters.py +0 -320
  56. roam_code-8.2.0/src/roam/commands/cmd_layers.py +0 -244
  57. {roam_code-8.2.0 → roam_code-9.1.0}/LICENSE +0 -0
  58. {roam_code-8.2.0 → roam_code-9.1.0}/setup.cfg +0 -0
  59. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/__init__.py +0 -0
  60. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/__main__.py +0 -0
  61. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/bridges/__init__.py +0 -0
  62. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/bridges/base.py +0 -0
  63. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/bridges/bridge_protobuf.py +0 -0
  64. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/bridges/bridge_salesforce.py +0 -0
  65. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/bridges/registry.py +0 -0
  66. {roam_code-8.2.0/src/roam/commands → roam_code-9.1.0/src/roam/catalog}/__init__.py +0 -0
  67. {roam_code-8.2.0/src/roam/db → roam_code-9.1.0/src/roam/commands}/__init__.py +0 -0
  68. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/changed_files.py +0 -0
  69. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_alerts.py +0 -0
  70. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_breaking.py +0 -0
  71. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_bus_factor.py +0 -0
  72. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_complexity.py +0 -0
  73. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_context.py +0 -0
  74. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_conventions.py +0 -0
  75. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_coupling.py +0 -0
  76. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_coverage_gaps.py +0 -0
  77. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_debt.py +0 -0
  78. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_deps.py +0 -0
  79. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_diagnose.py +0 -0
  80. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_diff.py +0 -0
  81. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_digest.py +0 -0
  82. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_doc_staleness.py +0 -0
  83. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_entry_points.py +0 -0
  84. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_fan.py +0 -0
  85. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_file.py +0 -0
  86. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_fitness.py +0 -0
  87. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_fn_coupling.py +0 -0
  88. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_grep.py +0 -0
  89. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_index.py +0 -0
  90. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_init.py +0 -0
  91. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_map.py +0 -0
  92. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_owner.py +0 -0
  93. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_patterns.py +0 -0
  94. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_preflight.py +0 -0
  95. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_report.py +0 -0
  96. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_risk.py +0 -0
  97. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_safe_delete.py +0 -0
  98. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_safe_zones.py +0 -0
  99. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_search.py +0 -0
  100. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_sketch.py +0 -0
  101. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_snapshot.py +0 -0
  102. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_split.py +0 -0
  103. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_symbol.py +0 -0
  104. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_testmap.py +0 -0
  105. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_tour.py +0 -0
  106. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_trace.py +0 -0
  107. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_trend.py +0 -0
  108. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_uses.py +0 -0
  109. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_visualize.py +0 -0
  110. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_weather.py +0 -0
  111. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_ws.py +0 -0
  112. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/cmd_xlang.py +0 -0
  113. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/context_helpers.py +0 -0
  114. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/gate_presets.py +0 -0
  115. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/graph_helpers.py +0 -0
  116. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/commands/resolve.py +0 -0
  117. {roam_code-8.2.0/src/roam/output → roam_code-9.1.0/src/roam/db}/__init__.py +0 -0
  118. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/db/queries.py +0 -0
  119. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/__init__.py +0 -0
  120. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/anomaly.py +0 -0
  121. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/builder.py +0 -0
  122. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/clusters.py +0 -0
  123. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/cycles.py +0 -0
  124. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/layers.py +0 -0
  125. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/pagerank.py +0 -0
  126. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/graph/pathfinding.py +0 -0
  127. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/__init__.py +0 -0
  128. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/discovery.py +0 -0
  129. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/file_roles.py +0 -0
  130. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/git_stats.py +0 -0
  131. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/incremental.py +0 -0
  132. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/index/symbols.py +0 -0
  133. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/__init__.py +0 -0
  134. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/apex_lang.py +0 -0
  135. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/aura_lang.py +0 -0
  136. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/base.py +0 -0
  137. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/c_lang.py +0 -0
  138. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/go_lang.py +0 -0
  139. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/java_lang.py +0 -0
  140. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/rust_lang.py +0 -0
  141. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/sfxml_lang.py +0 -0
  142. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/typescript_lang.py +0 -0
  143. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/languages/visualforce_lang.py +0 -0
  144. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/output/formatter.py +0 -0
  145. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/output/sarif.py +0 -0
  146. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/workspace/__init__.py +0 -0
  147. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/workspace/aggregator.py +0 -0
  148. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/workspace/api_scanner.py +0 -0
  149. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam/workspace/config.py +0 -0
  150. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam_code.egg-info/dependency_links.txt +0 -0
  151. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam_code.egg-info/entry_points.txt +0 -0
  152. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam_code.egg-info/requires.txt +0 -0
  153. {roam_code-8.2.0 → roam_code-9.1.0}/src/roam_code.egg-info/top_level.txt +0 -0
  154. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_basic.py +0 -0
  155. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_bridges.py +0 -0
  156. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_commands_architecture.py +0 -0
  157. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_commands_exploration.py +0 -0
  158. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_commands_refactoring.py +0 -0
  159. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_dead_aging.py +0 -0
  160. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_file_roles.py +0 -0
  161. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_formatters.py +0 -0
  162. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_foxpro.py +0 -0
  163. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_gate_presets.py +0 -0
  164. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_json_contracts.py +0 -0
  165. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_performance.py +0 -0
  166. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_smoke.py +0 -0
  167. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_v71_features.py +0 -0
  168. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_v82_features.py +0 -0
  169. {roam_code-8.2.0 → roam_code-9.1.0}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roam-code
3
- Version: 8.2.0
3
+ Version: 9.1.0
4
4
  Summary: Instant codebase comprehension for AI coding agents
5
5
  Author: CosmoHac
6
6
  License-Expression: MIT
@@ -37,9 +37,9 @@ Dynamic: license-file
37
37
 
38
38
  # roam
39
39
 
40
- **Roam pre-indexes your codebase into a semantic graph so AI agents can query structure instead of grepping files.**
40
+ **Instant codebase comprehension for AI coding agents. Semantic graph, algorithm anti-pattern detection, architecture health -- one CLI, zero API keys.**
41
41
 
42
- *5 core commands · advanced tools when you need them*
42
+ *56 commands · 22 languages · algorithm catalog · 100% local*
43
43
 
44
44
  [![PyPI version](https://img.shields.io/pypi/v/roam-code?style=flat-square&color=blue)](https://pypi.org/project/roam-code/)
45
45
  [![GitHub stars](https://img.shields.io/github/stars/Cranot/roam-code?style=flat-square)](https://github.com/Cranot/roam-code/stargazers)
@@ -57,7 +57,7 @@ Roam pre-indexes your codebase into a semantic graph -- symbols, dependencies, c
57
57
 
58
58
  Unlike LSPs (editor-bound and language-specific) or Sourcegraph (hosted search), Roam provides architecture-level graph queries -- offline, cross-language, and compact.
59
59
 
60
- A semantic graph means Roam understands what functions call what, how modules depend on each other, which tests cover which code, and the overall architecture structure.
60
+ A semantic graph means Roam understands what functions call what, how modules depend on each other, which tests cover which code, the overall architecture structure, and where algorithms can be improved. The built-in algorithm catalog detects 23 anti-patterns (O(n^2) loops, N+1 queries, quadratic string building, branching recursion) and suggests better approaches with Big-O improvements.
61
61
 
62
62
  ```
63
63
  Codebase ──> [Index] ──> Semantic Graph ──> CLI ──> AI Agent
@@ -100,6 +100,7 @@ $ roam diff # blast radius of uncommitted changes
100
100
  - **Large codebases (100+ files)** -- graph queries beat linear search at scale
101
101
  - **Architecture governance** -- health scores, CI quality gates, dependency cycle detection
102
102
  - **Safe refactoring** -- blast radius, affected tests, pre-change safety checks
103
+ - **Algorithm optimization** -- detect O(n^2) loops, N+1 queries, and 21 other anti-patterns with suggested fixes
103
104
  - **Multi-repo projects** -- cross-repo API edge detection between frontend and backend
104
105
 
105
106
  ### When NOT to use Roam
@@ -119,6 +120,8 @@ $ roam diff # blast radius of uncommitted changes
119
120
 
120
121
  **Fully local.** No API keys, telemetry, or network calls. Works in air-gapped environments.
121
122
 
123
+ **Algorithm-aware.** Built-in catalog of 23 anti-patterns. Detects suboptimal algorithms (quadratic loops, N+1 queries, unbounded recursion) and suggests fixes with Big-O improvements and confidence scores.
124
+
122
125
  **CI-ready.** `--json` output, `--gate` quality gates, GitHub Action, SARIF 2.1.0.
123
126
 
124
127
  | | Without Roam | With Roam |
@@ -211,7 +214,7 @@ roam health
211
214
 
212
215
  ## Commands
213
216
 
214
- The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. 55 total commands are organized into 7 categories.
217
+ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. 56 commands are organized into 7 categories.
215
218
 
216
219
  <details>
217
220
  <summary><strong>Full command reference</strong></summary>
@@ -252,6 +255,7 @@ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows.
252
255
  |---------|-------------|
253
256
  | `roam health [--no-framework]` | Composite health score (0-100): weighted geometric mean of tangle ratio, god components, bottlenecks, layer violations. Includes propagation cost and algebraic connectivity |
254
257
  | `roam complexity [--bumpy-road]` | Per-function cognitive complexity (SonarSource-compatible, triangular nesting penalty) + Halstead metrics (volume, difficulty, effort, bugs) + cyclomatic density |
258
+ | `roam math [--task T] [--confidence C]` | Algorithm anti-pattern detection: 23-pattern catalog detects suboptimal algorithms (O(n^2) loops, N+1 queries, quadratic string building, branching recursion, loop-invariant calls) and suggests better approaches with Big-O improvements. Confidence calibration via caller-count and bounded-loop analysis |
255
259
  | `roam weather [-n N]` | Hotspots ranked by geometric mean of churn x complexity (percentile-normalized) |
256
260
  | `roam debt` | Hotspot-weighted tech debt prioritization with SQALE remediation cost estimates |
257
261
  | `roam fitness [--explain]` | Architectural fitness functions from `.roam/fitness.yaml` |
@@ -563,7 +567,7 @@ pip install fastmcp
563
567
  fastmcp run roam.mcp_server:mcp
564
568
  ```
565
569
 
566
- 19 read-only tools and 2 resources. All tools query the index -- they never modify your code.
570
+ 20 read-only tools and 2 resources. All tools query the index -- they never modify your code.
567
571
 
568
572
  <details>
569
573
  <summary><strong>MCP tool list</strong></summary>
@@ -587,6 +591,7 @@ fastmcp run roam.mcp_server:mcp
587
591
  | `tour` | Auto-generated onboarding guide |
588
592
  | `diagnose` | Root cause analysis for debugging |
589
593
  | `visualize` | Generate Mermaid or DOT architecture diagrams |
594
+ | `math` | Algorithm anti-pattern detection with confidence calibration |
590
595
  | `ws_understand` | Unified multi-repo workspace overview |
591
596
  | `ws_context` | Cross-repo augmented symbol context |
592
597
 
@@ -808,6 +813,7 @@ Zero infrastructure, zero vendor lock-in, zero data leaving your network.
808
813
  | Go | `.go` | structs, interfaces, functions, methods, fields | imports, calls | embedded structs |
809
814
  | Rust | `.rs` | structs, traits, impls, enums, functions | use, calls | impl Trait for Struct |
810
815
  | C / C++ | `.c` `.h` `.cpp` `.hpp` `.cc` | structs, classes, functions, namespaces, templates | includes, calls | extends |
816
+ | C# | `.cs` | classes, interfaces, structs, enums, records, methods, constructors, properties, delegates, events, fields | using directives, calls, `new`, attributes | extends, implements |
811
817
  | PHP | `.php` | classes, interfaces, traits, enums, methods, properties | namespace use, calls, static calls, `new` | extends, implements, use (traits) |
812
818
  | Visual FoxPro | `.prg` | functions, procedures, classes, methods, properties, constants | DO, SET PROCEDURE/CLASSLIB, CREATEOBJECT, `=func()`, `obj.method()` | DEFINE CLASS ... AS |
813
819
  | Vue | `.vue` | via `<script>` block extraction (TS/JS) | imports, calls, type refs | extends, implements |
@@ -830,7 +836,7 @@ Cross-language edges mean `roam impact AccountService` shows blast radius across
830
836
 
831
837
  ### Tier 2 -- Generic extraction
832
838
 
833
- Ruby (`.rb`), C# (`.cs`), Kotlin (`.kt` `.kts`), Swift (`.swift`), Scala (`.scala` `.sc`)
839
+ Ruby (`.rb`), Kotlin (`.kt` `.kts`), Swift (`.swift`), Scala (`.scala` `.sc`)
834
840
 
835
841
  Tier 2 languages get symbol extraction and basic inheritance via a generic tree-sitter walker.
836
842
 
@@ -892,13 +898,15 @@ Codebase
892
898
  |
893
899
  [5] Metrics ────── adaptive PageRank, betweenness, cognitive complexity, Halstead
894
900
  |
895
- [6] Git ────────── churn, co-change matrix, authorship, Renyi entropy
901
+ [6] Algorithms ── 23-pattern anti-pattern catalog (O(n^2) loops, N+1, recursion)
902
+ |
903
+ [7] Git ────────── churn, co-change matrix, authorship, Renyi entropy
896
904
  |
897
- [7] Clusters ───── Louvain community detection
905
+ [8] Clusters ───── Louvain community detection
898
906
  |
899
- [8] Health ─────── per-file scores (7-factor) + composite score (0-100)
907
+ [9] Health ─────── per-file scores (7-factor) + composite score (0-100)
900
908
  |
901
- [9] Store ──────── .roam/index.db (SQLite, WAL mode)
909
+ [10] Store ─────── .roam/index.db (SQLite, WAL mode)
902
910
  ```
903
911
 
904
912
  After the first full index, `roam index` only re-processes changed files (mtime + SHA-256 hash). Incremental updates are near-instant.
@@ -925,6 +933,7 @@ After the first full index, `roam index` only re-processes changed files (mtime
925
933
  - **Lift** -- association rule mining metric for co-change statistical significance (Agrawal & Srikant, 1994)
926
934
  - **Halstead metrics** -- volume, difficulty, effort, and predicted bugs from operator/operand counts (Halstead, 1977)
927
935
  - **SQALE remediation cost** -- time-to-fix estimates per issue type for tech debt prioritization (Letouzey, 2012)
936
+ - **Algorithm anti-pattern catalog** -- 23 patterns detecting suboptimal algorithms (quadratic loops, N+1 queries, quadratic string building, branching recursion, manual top-k, loop-invariant calls) with confidence calibration via caller-count and bounded-loop analysis
928
937
 
929
938
  </details>
930
939
 
@@ -986,7 +995,7 @@ Static analysis trade-offs:
986
995
  - **No runtime analysis** -- can't trace dynamic dispatch, reflection, or eval'd code
987
996
  - **Import resolution is heuristic** -- complex re-exports or conditional imports may not resolve
988
997
  - **Limited cross-language edges** -- Salesforce and multi-repo API edges are supported, but not arbitrary FFI
989
- - **Tier 2 languages** (Ruby, C#, Kotlin, Swift, Scala) get basic symbol extraction only
998
+ - **Tier 2 languages** (Ruby, Kotlin, Swift, Scala) get basic symbol extraction only
990
999
  - **Large monorepos** (100k+ files) may have slow initial indexing
991
1000
 
992
1001
  ## Troubleshooting
@@ -1023,7 +1032,7 @@ Delete `.roam/` from your project root to clean up local data.
1023
1032
  git clone https://github.com/Cranot/roam-code.git
1024
1033
  cd roam-code
1025
1034
  pip install -e ".[dev]" # includes pytest, ruff
1026
- pytest tests/ # 1729 tests, Python 3.9-3.13
1035
+ pytest tests/ # 1847 tests, Python 3.9-3.13
1027
1036
 
1028
1037
  # Or use Make targets:
1029
1038
  make dev # install with dev extras
@@ -1038,11 +1047,10 @@ make lint # ruff check
1038
1047
  roam-code/
1039
1048
  ├── pyproject.toml
1040
1049
  ├── action.yml # Reusable GitHub Action
1041
- ├── CHANGELOG.md
1042
1050
  ├── src/roam/
1043
1051
  │ ├── __init__.py # Version (from pyproject.toml)
1044
- │ ├── cli.py # Click CLI (55 commands, 7 categories)
1045
- │ ├── mcp_server.py # MCP server (19 tools, 2 resources)
1052
+ │ ├── cli.py # Click CLI (56 commands, 7 categories)
1053
+ │ ├── mcp_server.py # MCP server (20 tools, 2 resources)
1046
1054
  │ ├── db/
1047
1055
  │ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
1048
1056
  │ │ ├── schema.py # Tables, indexes, migrations
@@ -1055,12 +1063,21 @@ roam-code/
1055
1063
  │ │ ├── relations.py # Reference resolution -> edges
1056
1064
  │ │ ├── complexity.py # Cognitive complexity (SonarSource) + Halstead metrics
1057
1065
  │ │ ├── git_stats.py # Churn, co-change, blame, Renyi entropy
1058
- │ │ └── incremental.py # mtime + hash change detection
1066
+ │ │ ├── incremental.py # mtime + hash change detection
1067
+ │ │ ├── file_roles.py # Smart file role classifier
1068
+ │ │ └── test_conventions.py # Pluggable test naming adapters
1059
1069
  │ ├── languages/
1060
1070
  │ │ ├── base.py # Abstract LanguageExtractor
1061
1071
  │ │ ├── registry.py # Language detection + aliasing
1062
- │ │ ├── *_lang.py # One file per language (13 Tier 1)
1072
+ │ │ ├── *_lang.py # One file per language (14 Tier 1)
1063
1073
  │ │ └── generic_lang.py # Tier 2 fallback
1074
+ │ ├── bridges/
1075
+ │ │ ├── base.py, registry.py # Cross-language bridge framework
1076
+ │ │ ├── bridge_salesforce.py # Apex <-> Aura/LWC/Visualforce
1077
+ │ │ └── bridge_protobuf.py # .proto -> Go/Java/Python stubs
1078
+ │ ├── catalog/
1079
+ │ │ ├── tasks.py # Universal algorithm catalog (23 patterns)
1080
+ │ │ └── detectors.py # Anti-pattern detectors with confidence calibration
1064
1081
  │ ├── workspace/
1065
1082
  │ │ ├── config.py # .roam-workspace.json
1066
1083
  │ │ ├── db.py # Workspace overlay DB
@@ -1071,15 +1088,17 @@ roam-code/
1071
1088
  │ │ ├── cycles.py, clusters.py # Tarjan SCC, propagation cost, Louvain, modularity Q
1072
1089
  │ │ ├── layers.py, pathfinding.py # Topo layers, k-shortest paths
1073
1090
  │ │ ├── split.py, why.py # Decomposition, role classification
1091
+ │ │ └── anomaly.py # Statistical anomaly detection
1074
1092
  │ ├── commands/
1075
1093
  │ │ ├── resolve.py # Shared symbol resolution
1076
1094
  │ │ ├── graph_helpers.py # Shared graph utilities (adj builders, BFS)
1077
1095
  │ │ ├── context_helpers.py # Data-gathering helpers for context command
1096
+ │ │ ├── gate_presets.py # Framework-specific gate rules
1078
1097
  │ │ └── cmd_*.py # One module per command
1079
1098
  │ └── output/
1080
1099
  │ ├── formatter.py # Token-efficient formatting
1081
1100
  │ └── sarif.py # SARIF 2.1.0 output
1082
- └── tests/ # 1729 tests across 30 test files
1101
+ └── tests/ # Test suite across 30+ test files
1083
1102
  ```
1084
1103
 
1085
1104
  </details>
@@ -1107,9 +1126,14 @@ Optional: [fastmcp](https://github.com/jlowin/fastmcp) (MCP server)
1107
1126
  - [x] Multi-repo workspace support (v7.4)
1108
1127
  - [x] Research-backed algorithms: adaptive PageRank, Personalized PageRank, Mann-Kendall, NPMI, Sen's slope, sigmoid-bounded health, Gini layer balance (v7.4)
1109
1128
  - [x] Advanced math: Halstead metrics, Renyi entropy, propagation cost, algebraic connectivity, modularity Q-score, conductance, edge betweenness, SQALE remediation cost, multiplicative PR risk, weighted geometric mean health, dead code confidence scoring, cyclomatic density (v7.5)
1129
+ - [x] C# Tier 1 support (v8.0)
1130
+ - [x] Deep Python extractor: instance attrs, assignment type refs, forward refs (v8.1)
1131
+ - [x] Internal complexity reduction: 50+ functions refactored below CC=25 (v9.0)
1132
+ - [x] Scoring math audit: fixed boolean-op double-counting, unified percentile implementations (v9.0)
1133
+ - [x] Test speed optimization: in-process indexing for fixtures (v9.0)
1134
+ - [x] Algorithm anti-pattern detection: 23-pattern catalog, AST signal extraction, confidence calibration (v9.0)
1110
1135
  - [ ] Terminal demo GIF
1111
1136
  - [ ] Ruby Tier 1 support
1112
- - [ ] C# Tier 1 support
1113
1137
  - [ ] `--sarif` CLI flag for direct SARIF export
1114
1138
  - [ ] Docker image for CI
1115
1139
  - [ ] VS Code extension
@@ -1120,7 +1144,7 @@ Optional: [fastmcp](https://github.com/jlowin/fastmcp) (MCP server)
1120
1144
  git clone https://github.com/Cranot/roam-code.git
1121
1145
  cd roam-code
1122
1146
  pip install -e .
1123
- pytest tests/ # All 1729 tests must pass
1147
+ pytest tests/ # All 1847 tests must pass
1124
1148
  ```
1125
1149
 
1126
1150
  Good first contributions: add a [Tier 1 language](src/roam/languages/) (see `go_lang.py` or `php_lang.py` as templates), improve reference resolution, add benchmark repos, extend SARIF converters, add MCP tools.
@@ -2,9 +2,9 @@
2
2
 
3
3
  # roam
4
4
 
5
- **Roam pre-indexes your codebase into a semantic graph so AI agents can query structure instead of grepping files.**
5
+ **Instant codebase comprehension for AI coding agents. Semantic graph, algorithm anti-pattern detection, architecture health -- one CLI, zero API keys.**
6
6
 
7
- *5 core commands · advanced tools when you need them*
7
+ *56 commands · 22 languages · algorithm catalog · 100% local*
8
8
 
9
9
  [![PyPI version](https://img.shields.io/pypi/v/roam-code?style=flat-square&color=blue)](https://pypi.org/project/roam-code/)
10
10
  [![GitHub stars](https://img.shields.io/github/stars/Cranot/roam-code?style=flat-square)](https://github.com/Cranot/roam-code/stargazers)
@@ -22,7 +22,7 @@ Roam pre-indexes your codebase into a semantic graph -- symbols, dependencies, c
22
22
 
23
23
  Unlike LSPs (editor-bound and language-specific) or Sourcegraph (hosted search), Roam provides architecture-level graph queries -- offline, cross-language, and compact.
24
24
 
25
- A semantic graph means Roam understands what functions call what, how modules depend on each other, which tests cover which code, and the overall architecture structure.
25
+ A semantic graph means Roam understands what functions call what, how modules depend on each other, which tests cover which code, the overall architecture structure, and where algorithms can be improved. The built-in algorithm catalog detects 23 anti-patterns (O(n^2) loops, N+1 queries, quadratic string building, branching recursion) and suggests better approaches with Big-O improvements.
26
26
 
27
27
  ```
28
28
  Codebase ──> [Index] ──> Semantic Graph ──> CLI ──> AI Agent
@@ -65,6 +65,7 @@ $ roam diff # blast radius of uncommitted changes
65
65
  - **Large codebases (100+ files)** -- graph queries beat linear search at scale
66
66
  - **Architecture governance** -- health scores, CI quality gates, dependency cycle detection
67
67
  - **Safe refactoring** -- blast radius, affected tests, pre-change safety checks
68
+ - **Algorithm optimization** -- detect O(n^2) loops, N+1 queries, and 21 other anti-patterns with suggested fixes
68
69
  - **Multi-repo projects** -- cross-repo API edge detection between frontend and backend
69
70
 
70
71
  ### When NOT to use Roam
@@ -84,6 +85,8 @@ $ roam diff # blast radius of uncommitted changes
84
85
 
85
86
  **Fully local.** No API keys, telemetry, or network calls. Works in air-gapped environments.
86
87
 
88
+ **Algorithm-aware.** Built-in catalog of 23 anti-patterns. Detects suboptimal algorithms (quadratic loops, N+1 queries, unbounded recursion) and suggests fixes with Big-O improvements and confidence scores.
89
+
87
90
  **CI-ready.** `--json` output, `--gate` quality gates, GitHub Action, SARIF 2.1.0.
88
91
 
89
92
  | | Without Roam | With Roam |
@@ -176,7 +179,7 @@ roam health
176
179
 
177
180
  ## Commands
178
181
 
179
- The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. 55 total commands are organized into 7 categories.
182
+ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. 56 commands are organized into 7 categories.
180
183
 
181
184
  <details>
182
185
  <summary><strong>Full command reference</strong></summary>
@@ -217,6 +220,7 @@ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows.
217
220
  |---------|-------------|
218
221
  | `roam health [--no-framework]` | Composite health score (0-100): weighted geometric mean of tangle ratio, god components, bottlenecks, layer violations. Includes propagation cost and algebraic connectivity |
219
222
  | `roam complexity [--bumpy-road]` | Per-function cognitive complexity (SonarSource-compatible, triangular nesting penalty) + Halstead metrics (volume, difficulty, effort, bugs) + cyclomatic density |
223
+ | `roam math [--task T] [--confidence C]` | Algorithm anti-pattern detection: 23-pattern catalog detects suboptimal algorithms (O(n^2) loops, N+1 queries, quadratic string building, branching recursion, loop-invariant calls) and suggests better approaches with Big-O improvements. Confidence calibration via caller-count and bounded-loop analysis |
220
224
  | `roam weather [-n N]` | Hotspots ranked by geometric mean of churn x complexity (percentile-normalized) |
221
225
  | `roam debt` | Hotspot-weighted tech debt prioritization with SQALE remediation cost estimates |
222
226
  | `roam fitness [--explain]` | Architectural fitness functions from `.roam/fitness.yaml` |
@@ -528,7 +532,7 @@ pip install fastmcp
528
532
  fastmcp run roam.mcp_server:mcp
529
533
  ```
530
534
 
531
- 19 read-only tools and 2 resources. All tools query the index -- they never modify your code.
535
+ 20 read-only tools and 2 resources. All tools query the index -- they never modify your code.
532
536
 
533
537
  <details>
534
538
  <summary><strong>MCP tool list</strong></summary>
@@ -552,6 +556,7 @@ fastmcp run roam.mcp_server:mcp
552
556
  | `tour` | Auto-generated onboarding guide |
553
557
  | `diagnose` | Root cause analysis for debugging |
554
558
  | `visualize` | Generate Mermaid or DOT architecture diagrams |
559
+ | `math` | Algorithm anti-pattern detection with confidence calibration |
555
560
  | `ws_understand` | Unified multi-repo workspace overview |
556
561
  | `ws_context` | Cross-repo augmented symbol context |
557
562
 
@@ -773,6 +778,7 @@ Zero infrastructure, zero vendor lock-in, zero data leaving your network.
773
778
  | Go | `.go` | structs, interfaces, functions, methods, fields | imports, calls | embedded structs |
774
779
  | Rust | `.rs` | structs, traits, impls, enums, functions | use, calls | impl Trait for Struct |
775
780
  | C / C++ | `.c` `.h` `.cpp` `.hpp` `.cc` | structs, classes, functions, namespaces, templates | includes, calls | extends |
781
+ | C# | `.cs` | classes, interfaces, structs, enums, records, methods, constructors, properties, delegates, events, fields | using directives, calls, `new`, attributes | extends, implements |
776
782
  | PHP | `.php` | classes, interfaces, traits, enums, methods, properties | namespace use, calls, static calls, `new` | extends, implements, use (traits) |
777
783
  | Visual FoxPro | `.prg` | functions, procedures, classes, methods, properties, constants | DO, SET PROCEDURE/CLASSLIB, CREATEOBJECT, `=func()`, `obj.method()` | DEFINE CLASS ... AS |
778
784
  | Vue | `.vue` | via `<script>` block extraction (TS/JS) | imports, calls, type refs | extends, implements |
@@ -795,7 +801,7 @@ Cross-language edges mean `roam impact AccountService` shows blast radius across
795
801
 
796
802
  ### Tier 2 -- Generic extraction
797
803
 
798
- Ruby (`.rb`), C# (`.cs`), Kotlin (`.kt` `.kts`), Swift (`.swift`), Scala (`.scala` `.sc`)
804
+ Ruby (`.rb`), Kotlin (`.kt` `.kts`), Swift (`.swift`), Scala (`.scala` `.sc`)
799
805
 
800
806
  Tier 2 languages get symbol extraction and basic inheritance via a generic tree-sitter walker.
801
807
 
@@ -857,13 +863,15 @@ Codebase
857
863
  |
858
864
  [5] Metrics ────── adaptive PageRank, betweenness, cognitive complexity, Halstead
859
865
  |
860
- [6] Git ────────── churn, co-change matrix, authorship, Renyi entropy
866
+ [6] Algorithms ── 23-pattern anti-pattern catalog (O(n^2) loops, N+1, recursion)
867
+ |
868
+ [7] Git ────────── churn, co-change matrix, authorship, Renyi entropy
861
869
  |
862
- [7] Clusters ───── Louvain community detection
870
+ [8] Clusters ───── Louvain community detection
863
871
  |
864
- [8] Health ─────── per-file scores (7-factor) + composite score (0-100)
872
+ [9] Health ─────── per-file scores (7-factor) + composite score (0-100)
865
873
  |
866
- [9] Store ──────── .roam/index.db (SQLite, WAL mode)
874
+ [10] Store ─────── .roam/index.db (SQLite, WAL mode)
867
875
  ```
868
876
 
869
877
  After the first full index, `roam index` only re-processes changed files (mtime + SHA-256 hash). Incremental updates are near-instant.
@@ -890,6 +898,7 @@ After the first full index, `roam index` only re-processes changed files (mtime
890
898
  - **Lift** -- association rule mining metric for co-change statistical significance (Agrawal & Srikant, 1994)
891
899
  - **Halstead metrics** -- volume, difficulty, effort, and predicted bugs from operator/operand counts (Halstead, 1977)
892
900
  - **SQALE remediation cost** -- time-to-fix estimates per issue type for tech debt prioritization (Letouzey, 2012)
901
+ - **Algorithm anti-pattern catalog** -- 23 patterns detecting suboptimal algorithms (quadratic loops, N+1 queries, quadratic string building, branching recursion, manual top-k, loop-invariant calls) with confidence calibration via caller-count and bounded-loop analysis
893
902
 
894
903
  </details>
895
904
 
@@ -951,7 +960,7 @@ Static analysis trade-offs:
951
960
  - **No runtime analysis** -- can't trace dynamic dispatch, reflection, or eval'd code
952
961
  - **Import resolution is heuristic** -- complex re-exports or conditional imports may not resolve
953
962
  - **Limited cross-language edges** -- Salesforce and multi-repo API edges are supported, but not arbitrary FFI
954
- - **Tier 2 languages** (Ruby, C#, Kotlin, Swift, Scala) get basic symbol extraction only
963
+ - **Tier 2 languages** (Ruby, Kotlin, Swift, Scala) get basic symbol extraction only
955
964
  - **Large monorepos** (100k+ files) may have slow initial indexing
956
965
 
957
966
  ## Troubleshooting
@@ -988,7 +997,7 @@ Delete `.roam/` from your project root to clean up local data.
988
997
  git clone https://github.com/Cranot/roam-code.git
989
998
  cd roam-code
990
999
  pip install -e ".[dev]" # includes pytest, ruff
991
- pytest tests/ # 1729 tests, Python 3.9-3.13
1000
+ pytest tests/ # 1847 tests, Python 3.9-3.13
992
1001
 
993
1002
  # Or use Make targets:
994
1003
  make dev # install with dev extras
@@ -1003,11 +1012,10 @@ make lint # ruff check
1003
1012
  roam-code/
1004
1013
  ├── pyproject.toml
1005
1014
  ├── action.yml # Reusable GitHub Action
1006
- ├── CHANGELOG.md
1007
1015
  ├── src/roam/
1008
1016
  │ ├── __init__.py # Version (from pyproject.toml)
1009
- │ ├── cli.py # Click CLI (55 commands, 7 categories)
1010
- │ ├── mcp_server.py # MCP server (19 tools, 2 resources)
1017
+ │ ├── cli.py # Click CLI (56 commands, 7 categories)
1018
+ │ ├── mcp_server.py # MCP server (20 tools, 2 resources)
1011
1019
  │ ├── db/
1012
1020
  │ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
1013
1021
  │ │ ├── schema.py # Tables, indexes, migrations
@@ -1020,12 +1028,21 @@ roam-code/
1020
1028
  │ │ ├── relations.py # Reference resolution -> edges
1021
1029
  │ │ ├── complexity.py # Cognitive complexity (SonarSource) + Halstead metrics
1022
1030
  │ │ ├── git_stats.py # Churn, co-change, blame, Renyi entropy
1023
- │ │ └── incremental.py # mtime + hash change detection
1031
+ │ │ ├── incremental.py # mtime + hash change detection
1032
+ │ │ ├── file_roles.py # Smart file role classifier
1033
+ │ │ └── test_conventions.py # Pluggable test naming adapters
1024
1034
  │ ├── languages/
1025
1035
  │ │ ├── base.py # Abstract LanguageExtractor
1026
1036
  │ │ ├── registry.py # Language detection + aliasing
1027
- │ │ ├── *_lang.py # One file per language (13 Tier 1)
1037
+ │ │ ├── *_lang.py # One file per language (14 Tier 1)
1028
1038
  │ │ └── generic_lang.py # Tier 2 fallback
1039
+ │ ├── bridges/
1040
+ │ │ ├── base.py, registry.py # Cross-language bridge framework
1041
+ │ │ ├── bridge_salesforce.py # Apex <-> Aura/LWC/Visualforce
1042
+ │ │ └── bridge_protobuf.py # .proto -> Go/Java/Python stubs
1043
+ │ ├── catalog/
1044
+ │ │ ├── tasks.py # Universal algorithm catalog (23 patterns)
1045
+ │ │ └── detectors.py # Anti-pattern detectors with confidence calibration
1029
1046
  │ ├── workspace/
1030
1047
  │ │ ├── config.py # .roam-workspace.json
1031
1048
  │ │ ├── db.py # Workspace overlay DB
@@ -1036,15 +1053,17 @@ roam-code/
1036
1053
  │ │ ├── cycles.py, clusters.py # Tarjan SCC, propagation cost, Louvain, modularity Q
1037
1054
  │ │ ├── layers.py, pathfinding.py # Topo layers, k-shortest paths
1038
1055
  │ │ ├── split.py, why.py # Decomposition, role classification
1056
+ │ │ └── anomaly.py # Statistical anomaly detection
1039
1057
  │ ├── commands/
1040
1058
  │ │ ├── resolve.py # Shared symbol resolution
1041
1059
  │ │ ├── graph_helpers.py # Shared graph utilities (adj builders, BFS)
1042
1060
  │ │ ├── context_helpers.py # Data-gathering helpers for context command
1061
+ │ │ ├── gate_presets.py # Framework-specific gate rules
1043
1062
  │ │ └── cmd_*.py # One module per command
1044
1063
  │ └── output/
1045
1064
  │ ├── formatter.py # Token-efficient formatting
1046
1065
  │ └── sarif.py # SARIF 2.1.0 output
1047
- └── tests/ # 1729 tests across 30 test files
1066
+ └── tests/ # Test suite across 30+ test files
1048
1067
  ```
1049
1068
 
1050
1069
  </details>
@@ -1072,9 +1091,14 @@ Optional: [fastmcp](https://github.com/jlowin/fastmcp) (MCP server)
1072
1091
  - [x] Multi-repo workspace support (v7.4)
1073
1092
  - [x] Research-backed algorithms: adaptive PageRank, Personalized PageRank, Mann-Kendall, NPMI, Sen's slope, sigmoid-bounded health, Gini layer balance (v7.4)
1074
1093
  - [x] Advanced math: Halstead metrics, Renyi entropy, propagation cost, algebraic connectivity, modularity Q-score, conductance, edge betweenness, SQALE remediation cost, multiplicative PR risk, weighted geometric mean health, dead code confidence scoring, cyclomatic density (v7.5)
1094
+ - [x] C# Tier 1 support (v8.0)
1095
+ - [x] Deep Python extractor: instance attrs, assignment type refs, forward refs (v8.1)
1096
+ - [x] Internal complexity reduction: 50+ functions refactored below CC=25 (v9.0)
1097
+ - [x] Scoring math audit: fixed boolean-op double-counting, unified percentile implementations (v9.0)
1098
+ - [x] Test speed optimization: in-process indexing for fixtures (v9.0)
1099
+ - [x] Algorithm anti-pattern detection: 23-pattern catalog, AST signal extraction, confidence calibration (v9.0)
1075
1100
  - [ ] Terminal demo GIF
1076
1101
  - [ ] Ruby Tier 1 support
1077
- - [ ] C# Tier 1 support
1078
1102
  - [ ] `--sarif` CLI flag for direct SARIF export
1079
1103
  - [ ] Docker image for CI
1080
1104
  - [ ] VS Code extension
@@ -1085,7 +1109,7 @@ Optional: [fastmcp](https://github.com/jlowin/fastmcp) (MCP server)
1085
1109
  git clone https://github.com/Cranot/roam-code.git
1086
1110
  cd roam-code
1087
1111
  pip install -e .
1088
- pytest tests/ # All 1729 tests must pass
1112
+ pytest tests/ # All 1847 tests must pass
1089
1113
  ```
1090
1114
 
1091
1115
  Good first contributions: add a [Tier 1 language](src/roam/languages/) (see `go_lang.py` or `php_lang.py` as templates), improve reference resolution, add benchmark repos, extend SARIF converters, add MCP tools.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "roam-code"
7
- version = "8.2.0"
7
+ version = "9.1.0"
8
8
  description = "Instant codebase comprehension for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"