cov-loupe 3.0.0 → 4.0.0.pre

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 (281) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +230 -0
  3. data/CLAUDE.md +5 -0
  4. data/CODE_OF_CONDUCT.md +62 -0
  5. data/CONTRIBUTING.md +102 -0
  6. data/GEMINI.md +5 -0
  7. data/README.md +154 -51
  8. data/RELEASE_NOTES.md +452 -0
  9. data/dev/images/cov-loupe-icon-lores.png +0 -0
  10. data/dev/images/cov-loupe-icon-square.png +0 -0
  11. data/dev/images/cov-loupe-icon.png +0 -0
  12. data/dev/images/cov-loupe-logo.png +0 -0
  13. data/dev/prompts/README.md +74 -0
  14. data/dev/prompts/archive/architectural-review-and-actions-prompt.md +53 -0
  15. data/dev/prompts/archive/investigate-and-report-issues-prompt.md +33 -0
  16. data/dev/prompts/archive/produce-action-items-prompt.md +25 -0
  17. data/dev/prompts/guidelines/ai-code-evaluator-guidelines.md +337 -0
  18. data/dev/prompts/improve/refactor-test-suite.md +18 -0
  19. data/dev/prompts/improve/simplify-code-logic.md +133 -0
  20. data/dev/prompts/improve/update-documentation.md +21 -0
  21. data/dev/prompts/review/comprehensive-codebase-review.md +176 -0
  22. data/dev/prompts/review/identify-action-items.md +143 -0
  23. data/dev/prompts/review/verify-code-changes.md +54 -0
  24. data/dev/prompts/validate/create-screencast-outline.md +234 -0
  25. data/dev/prompts/validate/test-documentation-examples.md +180 -0
  26. data/docs/QUICKSTART.md +63 -0
  27. data/docs/assets/images/cov-loupe-logo-lores.png +0 -0
  28. data/docs/assets/images/cov-loupe-logo.png +0 -0
  29. data/docs/assets/images/favicon.png +0 -0
  30. data/docs/assets/stylesheets/branding.css +16 -0
  31. data/docs/assets/stylesheets/extra.css +15 -0
  32. data/docs/code_of_conduct.md +1 -0
  33. data/docs/contributing.md +1 -0
  34. data/docs/dev/ARCHITECTURE.md +56 -11
  35. data/docs/dev/DEVELOPMENT.md +116 -12
  36. data/docs/dev/FUTURE_ENHANCEMENTS.md +14 -0
  37. data/docs/dev/README.md +3 -2
  38. data/docs/dev/RELEASING.md +2 -0
  39. data/docs/dev/arch-decisions/README.md +10 -7
  40. data/docs/dev/arch-decisions/application-architecture.md +259 -0
  41. data/docs/dev/arch-decisions/coverage-data-quality.md +193 -0
  42. data/docs/dev/arch-decisions/output-character-mode.md +217 -0
  43. data/docs/dev/arch-decisions/path-resolution.md +90 -0
  44. data/docs/dev/arch-decisions/{004-x-arch-decision.md → policy-validation.md} +32 -28
  45. data/docs/dev/arch-decisions/{005-x-arch-decision.md → simplecov-integration.md} +47 -44
  46. data/docs/dev/presentations/cov-loupe-presentation.md +15 -13
  47. data/docs/examples/mcp-inputs.md +3 -0
  48. data/docs/examples/prompts.md +3 -0
  49. data/docs/examples/success_predicates.md +3 -0
  50. data/docs/fixtures/demo_project/.resultset.json +170 -0
  51. data/docs/fixtures/demo_project/README.md +6 -0
  52. data/docs/fixtures/demo_project/app/controllers/admin/audit_logs_controller.rb +19 -0
  53. data/docs/fixtures/demo_project/app/controllers/orders_controller.rb +26 -0
  54. data/docs/fixtures/demo_project/app/models/order.rb +20 -0
  55. data/docs/fixtures/demo_project/app/models/user.rb +19 -0
  56. data/docs/fixtures/demo_project/lib/api/client.rb +22 -0
  57. data/docs/fixtures/demo_project/lib/ops/jobs/cleanup_job.rb +16 -0
  58. data/docs/fixtures/demo_project/lib/ops/jobs/report_job.rb +17 -0
  59. data/docs/fixtures/demo_project/lib/payments/processor.rb +15 -0
  60. data/docs/fixtures/demo_project/lib/payments/refund_service.rb +15 -0
  61. data/docs/fixtures/demo_project/lib/payments/reporting/exporter.rb +16 -0
  62. data/docs/index.md +1 -0
  63. data/docs/license.md +3 -0
  64. data/docs/release_notes.md +3 -0
  65. data/docs/user/ADVANCED_USAGE.md +208 -115
  66. data/docs/user/CLI_FALLBACK_FOR_LLMS.md +2 -0
  67. data/docs/user/CLI_USAGE.md +276 -101
  68. data/docs/user/ERROR_HANDLING.md +4 -4
  69. data/docs/user/EXAMPLES.md +121 -128
  70. data/docs/user/INSTALLATION.md +9 -28
  71. data/docs/user/LIBRARY_API.md +227 -122
  72. data/docs/user/MCP_INTEGRATION.md +114 -203
  73. data/docs/user/README.md +5 -1
  74. data/docs/user/TROUBLESHOOTING.md +49 -27
  75. data/docs/user/installing-a-prelease-version-of-covloupe.md +43 -0
  76. data/docs/user/{V2-BREAKING-CHANGES.md → migrations/MIGRATING_TO_V2.md} +62 -72
  77. data/docs/user/migrations/MIGRATING_TO_V3.md +72 -0
  78. data/docs/user/migrations/MIGRATING_TO_V4.md +591 -0
  79. data/docs/user/migrations/README.md +22 -0
  80. data/docs/user/prompts/README.md +9 -0
  81. data/docs/user/prompts/non-web-coverage-analysis-prompt.md +103 -0
  82. data/docs/user/prompts/rails-coverage-analysis-prompt.md +94 -0
  83. data/docs/user/prompts/use-cli-not-mcp-prompt.md +53 -0
  84. data/examples/cli_demo.sh +77 -0
  85. data/examples/filter_and_table_demo-output.md +114 -0
  86. data/examples/filter_and_table_demo.rb +174 -0
  87. data/examples/fixtures/demo_project/coverage/.resultset.json +10 -0
  88. data/examples/mcp-inputs/README.md +66 -0
  89. data/examples/mcp-inputs/coverage_detailed.json +1 -0
  90. data/examples/mcp-inputs/coverage_raw.json +1 -0
  91. data/examples/mcp-inputs/coverage_summary.json +1 -0
  92. data/examples/mcp-inputs/list.json +1 -0
  93. data/examples/mcp-inputs/uncovered_lines.json +1 -0
  94. data/examples/prompts/README.md +27 -0
  95. data/examples/prompts/custom_resultset.txt +2 -0
  96. data/examples/prompts/detailed_with_source.txt +2 -0
  97. data/examples/prompts/list_lowest.txt +2 -0
  98. data/examples/prompts/summary.txt +2 -0
  99. data/examples/prompts/uncovered.txt +2 -0
  100. data/examples/success_predicates/README.md +198 -0
  101. data/examples/success_predicates/all_files_above_threshold_predicate.rb +21 -0
  102. data/examples/success_predicates/directory_specific_thresholds_predicate.rb +30 -0
  103. data/examples/success_predicates/project_coverage_minimum_predicate.rb +6 -0
  104. data/lib/cov_loupe/base_tool.rb +229 -20
  105. data/lib/cov_loupe/cli.rb +132 -23
  106. data/lib/cov_loupe/commands/base_command.rb +25 -6
  107. data/lib/cov_loupe/commands/command_factory.rb +0 -1
  108. data/lib/cov_loupe/commands/detailed_command.rb +10 -5
  109. data/lib/cov_loupe/commands/list_command.rb +2 -1
  110. data/lib/cov_loupe/commands/raw_command.rb +7 -5
  111. data/lib/cov_loupe/commands/summary_command.rb +12 -7
  112. data/lib/cov_loupe/commands/totals_command.rb +74 -10
  113. data/lib/cov_loupe/commands/uncovered_command.rb +7 -5
  114. data/lib/cov_loupe/commands/validate_command.rb +11 -3
  115. data/lib/cov_loupe/commands/version_command.rb +6 -4
  116. data/lib/cov_loupe/{app_config.rb → config/app_config.rb} +13 -5
  117. data/lib/cov_loupe/config/app_context.rb +43 -0
  118. data/lib/cov_loupe/config/boolean_type.rb +91 -0
  119. data/lib/cov_loupe/config/logger.rb +92 -0
  120. data/lib/cov_loupe/{option_normalizers.rb → config/option_normalizers.rb} +55 -24
  121. data/lib/cov_loupe/{option_parser_builder.rb → config/option_parser_builder.rb} +46 -24
  122. data/lib/cov_loupe/coverage/coverage_calculator.rb +53 -0
  123. data/lib/cov_loupe/coverage/coverage_reporter.rb +63 -0
  124. data/lib/cov_loupe/coverage/coverage_table_formatter.rb +133 -0
  125. data/lib/cov_loupe/{error_handler.rb → errors/error_handler.rb} +21 -33
  126. data/lib/cov_loupe/{errors.rb → errors/errors.rb} +48 -71
  127. data/lib/cov_loupe/formatters/formatters.rb +75 -0
  128. data/lib/cov_loupe/formatters/source_formatter.rb +18 -7
  129. data/lib/cov_loupe/formatters/table_formatter.rb +80 -0
  130. data/lib/cov_loupe/loaders/all.rb +15 -0
  131. data/lib/cov_loupe/loaders/all_cli.rb +10 -0
  132. data/lib/cov_loupe/loaders/all_mcp.rb +23 -0
  133. data/lib/cov_loupe/loaders/resultset_loader.rb +147 -0
  134. data/lib/cov_loupe/mcp_server.rb +3 -2
  135. data/lib/cov_loupe/model/model.rb +520 -0
  136. data/lib/cov_loupe/model/model_data.rb +13 -0
  137. data/lib/cov_loupe/model/model_data_cache.rb +116 -0
  138. data/lib/cov_loupe/option_parsers/env_options_parser.rb +17 -6
  139. data/lib/cov_loupe/option_parsers/error_helper.rb +16 -10
  140. data/lib/cov_loupe/output_chars.rb +192 -0
  141. data/lib/cov_loupe/paths/glob_utils.rb +100 -0
  142. data/lib/cov_loupe/{path_relativizer.rb → paths/path_relativizer.rb} +5 -13
  143. data/lib/cov_loupe/paths/path_utils.rb +265 -0
  144. data/lib/cov_loupe/paths/volume_case_sensitivity.rb +173 -0
  145. data/lib/cov_loupe/presenters/base_coverage_presenter.rb +9 -13
  146. data/lib/cov_loupe/presenters/coverage_payload_presenter.rb +21 -0
  147. data/lib/cov_loupe/presenters/payload_caching.rb +23 -0
  148. data/lib/cov_loupe/presenters/project_coverage_presenter.rb +73 -21
  149. data/lib/cov_loupe/presenters/project_totals_presenter.rb +16 -10
  150. data/lib/cov_loupe/repositories/coverage_repository.rb +149 -0
  151. data/lib/cov_loupe/resolvers/coverage_line_resolver.rb +90 -76
  152. data/lib/cov_loupe/resolvers/{resolver_factory.rb → resolver_helpers.rb} +6 -5
  153. data/lib/cov_loupe/resolvers/resultset_path_resolver.rb +40 -12
  154. data/lib/cov_loupe/scripts/command_execution.rb +113 -0
  155. data/lib/cov_loupe/scripts/latest_ci_status.rb +97 -0
  156. data/lib/cov_loupe/scripts/pre_release_check.rb +164 -0
  157. data/lib/cov_loupe/scripts/setup_doc_server.rb +23 -0
  158. data/lib/cov_loupe/scripts/start_doc_server.rb +24 -0
  159. data/lib/cov_loupe/staleness/stale_status.rb +23 -0
  160. data/lib/cov_loupe/staleness/staleness_checker.rb +328 -0
  161. data/lib/cov_loupe/staleness/staleness_message_formatter.rb +91 -0
  162. data/lib/cov_loupe/tools/coverage_detailed_tool.rb +14 -15
  163. data/lib/cov_loupe/tools/coverage_raw_tool.rb +14 -14
  164. data/lib/cov_loupe/tools/coverage_summary_tool.rb +16 -16
  165. data/lib/cov_loupe/tools/coverage_table_tool.rb +139 -21
  166. data/lib/cov_loupe/tools/coverage_totals_tool.rb +31 -13
  167. data/lib/cov_loupe/tools/help_tool.rb +16 -20
  168. data/lib/cov_loupe/tools/list_tool.rb +65 -0
  169. data/lib/cov_loupe/tools/uncovered_lines_tool.rb +14 -14
  170. data/lib/cov_loupe/tools/validate_tool.rb +18 -24
  171. data/lib/cov_loupe/tools/version_tool.rb +8 -3
  172. data/lib/cov_loupe/version.rb +1 -1
  173. data/lib/cov_loupe.rb +83 -55
  174. metadata +184 -154
  175. data/docs/dev/BRANCH_ONLY_COVERAGE.md +0 -158
  176. data/docs/dev/arch-decisions/001-x-arch-decision.md +0 -95
  177. data/docs/dev/arch-decisions/002-x-arch-decision.md +0 -159
  178. data/docs/dev/arch-decisions/003-x-arch-decision.md +0 -165
  179. data/lib/cov_loupe/app_context.rb +0 -26
  180. data/lib/cov_loupe/constants.rb +0 -22
  181. data/lib/cov_loupe/coverage_reporter.rb +0 -31
  182. data/lib/cov_loupe/formatters.rb +0 -51
  183. data/lib/cov_loupe/mode_detector.rb +0 -56
  184. data/lib/cov_loupe/model.rb +0 -339
  185. data/lib/cov_loupe/presenters/coverage_detailed_presenter.rb +0 -14
  186. data/lib/cov_loupe/presenters/coverage_raw_presenter.rb +0 -14
  187. data/lib/cov_loupe/presenters/coverage_summary_presenter.rb +0 -14
  188. data/lib/cov_loupe/presenters/coverage_uncovered_presenter.rb +0 -14
  189. data/lib/cov_loupe/resultset_loader.rb +0 -131
  190. data/lib/cov_loupe/staleness_checker.rb +0 -247
  191. data/lib/cov_loupe/table_formatter.rb +0 -64
  192. data/lib/cov_loupe/tools/all_files_coverage_tool.rb +0 -51
  193. data/lib/cov_loupe/util.rb +0 -88
  194. data/spec/MCP_INTEGRATION_TESTS_README.md +0 -111
  195. data/spec/TIMESTAMPS.md +0 -48
  196. data/spec/all_files_coverage_tool_spec.rb +0 -53
  197. data/spec/app_config_spec.rb +0 -142
  198. data/spec/base_tool_spec.rb +0 -62
  199. data/spec/cli/show_default_report_spec.rb +0 -33
  200. data/spec/cli_enumerated_options_spec.rb +0 -90
  201. data/spec/cli_error_spec.rb +0 -184
  202. data/spec/cli_format_spec.rb +0 -123
  203. data/spec/cli_json_options_spec.rb +0 -50
  204. data/spec/cli_source_spec.rb +0 -44
  205. data/spec/cli_spec.rb +0 -192
  206. data/spec/cli_table_spec.rb +0 -28
  207. data/spec/cli_usage_spec.rb +0 -42
  208. data/spec/commands/base_command_spec.rb +0 -107
  209. data/spec/commands/command_factory_spec.rb +0 -76
  210. data/spec/commands/detailed_command_spec.rb +0 -34
  211. data/spec/commands/list_command_spec.rb +0 -28
  212. data/spec/commands/raw_command_spec.rb +0 -69
  213. data/spec/commands/summary_command_spec.rb +0 -34
  214. data/spec/commands/totals_command_spec.rb +0 -34
  215. data/spec/commands/uncovered_command_spec.rb +0 -55
  216. data/spec/commands/validate_command_spec.rb +0 -213
  217. data/spec/commands/version_command_spec.rb +0 -38
  218. data/spec/constants_spec.rb +0 -61
  219. data/spec/cov_loupe/formatters/source_formatter_spec.rb +0 -267
  220. data/spec/cov_loupe/formatters_spec.rb +0 -76
  221. data/spec/cov_loupe/presenters/base_coverage_presenter_spec.rb +0 -79
  222. data/spec/cov_loupe_model_spec.rb +0 -454
  223. data/spec/cov_loupe_module_spec.rb +0 -37
  224. data/spec/cov_loupe_opts_spec.rb +0 -185
  225. data/spec/coverage_reporter_spec.rb +0 -102
  226. data/spec/coverage_table_tool_spec.rb +0 -59
  227. data/spec/coverage_totals_tool_spec.rb +0 -37
  228. data/spec/error_handler_spec.rb +0 -197
  229. data/spec/error_mode_spec.rb +0 -139
  230. data/spec/errors_edge_cases_spec.rb +0 -312
  231. data/spec/errors_stale_spec.rb +0 -83
  232. data/spec/file_based_mcp_tools_spec.rb +0 -99
  233. data/spec/help_tool_spec.rb +0 -26
  234. data/spec/integration_spec.rb +0 -789
  235. data/spec/logging_fallback_spec.rb +0 -128
  236. data/spec/mcp_logging_spec.rb +0 -44
  237. data/spec/mcp_server_integration_spec.rb +0 -23
  238. data/spec/mcp_server_spec.rb +0 -106
  239. data/spec/mode_detector_spec.rb +0 -153
  240. data/spec/model_error_handling_spec.rb +0 -269
  241. data/spec/model_staleness_spec.rb +0 -79
  242. data/spec/option_normalizers_spec.rb +0 -203
  243. data/spec/option_parsers/env_options_parser_spec.rb +0 -221
  244. data/spec/option_parsers/error_helper_spec.rb +0 -222
  245. data/spec/path_relativizer_spec.rb +0 -98
  246. data/spec/presenters/coverage_detailed_presenter_spec.rb +0 -19
  247. data/spec/presenters/coverage_raw_presenter_spec.rb +0 -15
  248. data/spec/presenters/coverage_summary_presenter_spec.rb +0 -15
  249. data/spec/presenters/coverage_uncovered_presenter_spec.rb +0 -16
  250. data/spec/presenters/project_coverage_presenter_spec.rb +0 -87
  251. data/spec/presenters/project_totals_presenter_spec.rb +0 -144
  252. data/spec/resolvers/coverage_line_resolver_spec.rb +0 -282
  253. data/spec/resolvers/resolver_factory_spec.rb +0 -61
  254. data/spec/resolvers/resultset_path_resolver_spec.rb +0 -60
  255. data/spec/resultset_loader_spec.rb +0 -167
  256. data/spec/shared_examples/README.md +0 -115
  257. data/spec/shared_examples/coverage_presenter_examples.rb +0 -66
  258. data/spec/shared_examples/file_based_mcp_tools.rb +0 -179
  259. data/spec/shared_examples/formatted_command_examples.rb +0 -64
  260. data/spec/shared_examples/mcp_tool_text_json_response.rb +0 -16
  261. data/spec/spec_helper.rb +0 -127
  262. data/spec/staleness_checker_spec.rb +0 -374
  263. data/spec/staleness_more_spec.rb +0 -42
  264. data/spec/support/cli_helpers.rb +0 -22
  265. data/spec/support/control_flow_helpers.rb +0 -20
  266. data/spec/support/fake_mcp.rb +0 -40
  267. data/spec/support/io_helpers.rb +0 -29
  268. data/spec/support/mcp_helpers.rb +0 -35
  269. data/spec/support/mcp_runner.rb +0 -66
  270. data/spec/support/mocking_helpers.rb +0 -30
  271. data/spec/table_format_spec.rb +0 -70
  272. data/spec/tools/validate_tool_spec.rb +0 -132
  273. data/spec/tools_error_handling_spec.rb +0 -130
  274. data/spec/util_spec.rb +0 -154
  275. data/spec/version_spec.rb +0 -123
  276. data/spec/version_tool_spec.rb +0 -141
  277. /data/{spec/fixtures/project1 → examples/fixtures/demo_project}/lib/bar.rb +0 -0
  278. /data/{spec/fixtures/project1 → examples/fixtures/demo_project}/lib/foo.rb +0 -0
  279. /data/lib/cov_loupe/{config_parser.rb → config/config_parser.rb} +0 -0
  280. /data/lib/cov_loupe/{predicate_evaluator.rb → config/predicate_evaluator.rb} +0 -0
  281. /data/lib/cov_loupe/{error_handler_factory.rb → errors/error_handler_factory.rb} +0 -0
data/README.md CHANGED
@@ -4,14 +4,19 @@
4
4
  </h1>
5
5
 
6
6
  <p style="text-align:center; margin-bottom:-36px;">
7
- <img src="dev/images/cov-loupe-logo.png" alt="CovLoupe logo" width="560">
7
+ <img src="https://raw.githubusercontent.com/keithrbennett/cov-loupe/main/dev/images/cov-loupe-logo.png" alt="CovLoupe logo" width="560">
8
8
  </p>
9
9
 
10
10
  <p style="text-align:center;">
11
11
  An MCP server, command line utility, and library for Ruby SimpleCov test coverage analysis.
12
+ </p>
12
13
 
14
+ <p style="text-align:center;">
15
+ <strong><a href="https://keithrbennett.github.io/cov-loupe/">Documentation Website</a></strong>
16
+ </p>
13
17
 
14
18
  [![Gem Version](https://badge.fury.io/rb/cov-loupe.svg)](https://badge.fury.io/rb/cov-loupe)
19
+ [![Documentation](https://img.shields.io/badge/docs-online-blue.svg)](https://keithrbennett.github.io/cov-loupe/)
15
20
 
16
21
  ## What is cov-loupe?
17
22
 
@@ -26,12 +31,11 @@ Works with any SimpleCov-generated `.resultset.json` file—no runtime dependenc
26
31
  ### Key Features
27
32
 
28
33
  - ✅ **Multiple interfaces** - MCP server, CLI, and Ruby API
29
- - **Annotated source code** - `--source full|uncovered` with `--context-lines N` for context lines
34
+ - **Annotated source code** - `-s full|uncovered` / `--source full|uncovered` with `-c N` / `--context-lines N` for context lines
30
35
  - ✅ **Staleness detection** - Identify outdated coverage (missing files, timestamp mismatches, line count changes)
31
36
  - ✅ **Multi-suite support** - Automatic merging of multiple test suites (RSpec + Cucumber, etc.)
32
37
  - ✅ **Flexible path resolution** - Works with absolute or relative paths
33
38
  - ✅ **Comprehensive error handling** - Context-aware messages for each mode
34
- - ⚠️ **Branch coverage limitation** - Branch-level metrics are collapsed to per-line totals. Use native SimpleCov reports for branch-by-branch analysis.
35
39
 
36
40
  ### Practical Use Cases
37
41
 
@@ -51,6 +55,10 @@ Works with any SimpleCov-generated `.resultset.json` file—no runtime dependenc
51
55
  gem install cov-loupe
52
56
  ```
53
57
 
58
+ ### Upgrading
59
+
60
+ If you are upgrading from a previous version, please refer to the [Migration Guides](docs/user/migrations/README.md).
61
+
54
62
  ### Generate Coverage Data
55
63
 
56
64
  ```sh
@@ -86,49 +94,67 @@ Repository: https://github.com/keithrbennett/cov-loupe # <--- Project URL ---
86
94
  require "cov_loupe"
87
95
 
88
96
  model = CovLoupe::CoverageModel.new
89
- files = model.all_files
97
+ list_result = model.list
98
+ files = list_result["files"]
90
99
  # => [{ "file" => "lib/cov_loupe/model.rb", "covered" => 114, "total" => 118, "percentage" => 96.61, "stale" => false }, ...]
91
100
 
92
101
  summary = model.summary_for("lib/cov_loupe/model.rb")
93
- # => { "file" => "lib/cov_loupe/model.rb", "summary" => { "covered" => 114, "total" => 118, "percentage" => 96.61 }, "stale" => false }
102
+ # => { "file" => "lib/cov_loupe/model.rb", "summary" => { "covered" => 114, "total" => 118, "percentage" => 96.61 } }
94
103
  ```
95
104
 
105
+ For advanced use cases, multiple models can each have their own data source and log file. See [Library API](docs/user/LIBRARY_API.md#per-model-context-advanced) for details.
106
+
96
107
  **MCP Server:**
97
108
  See [MCP Integration Guide](docs/user/MCP_INTEGRATION.md) for AI assistant setup.
98
109
 
99
- ## Multi-Suite Coverage Merging
100
-
101
- ### How It Works
110
+ ## Multi-Suite Coverage
102
111
 
103
- When a `.resultset.json` file contains multiple test suites (e.g., RSpec + Cucumber), `cov-loupe` automatically merges them using SimpleCov's combine logic. All covered files from every suite become available to the CLI, library, and MCP tools.
112
+ Projects with multiple test suites (RSpec + Cucumber, etc.) are automatically merged. See [Multi-Suite Coverage Merging](docs/user/ADVANCED_USAGE.md#multi-suite-coverage-merging) for details and current limitations.
104
113
 
105
- **Performance:** Single-suite projects avoid loading SimpleCov at runtime. Multi-suite resultsets trigger a lazy SimpleCov load only when needed, keeping the tool fast for the simpler coverage configurations.
114
+ ## Documentation Index
106
115
 
107
- ### Current Limitations
116
+ Full documentation is available at **[https://keithrbennett.github.io/cov-loupe/](https://keithrbennett.github.io/cov-loupe/)**.
108
117
 
109
- **Staleness checks:** When suites are merged, we keep a single "latest suite" timestamp. This matches prior behavior but may under-report stale files if only some suites were re-run after a change. A per-file timestamp refinement is planned. Until then, consider multi-suite staleness checks advisory rather than definitive.
118
+ **User Guides:**
110
119
 
111
- **Multiple resultset files:** Only suites stored inside a *single* `.resultset.json` are merged automatically. If your project produces separate resultset files (e.g., different CI jobs writing `coverage/job1/.resultset.json`, `coverage/job2/.resultset.json`), you must merge them yourself before pointing `cov-loupe` at the combined file.
112
-
113
- ## Documentation
114
-
115
- **Getting Started:**
120
+ - [Quick Start](docs/QUICKSTART.md) - Get up and running in 3 steps
121
+ - [User Docs Overview](docs/user/README.md) - Map of all end-user guides
116
122
  - [Installation](docs/user/INSTALLATION.md) - Setup for different environments
117
123
  - [CLI Usage](docs/user/CLI_USAGE.md) - Command-line reference
118
124
  - [Examples](docs/user/EXAMPLES.md) - Common use cases
119
-
120
- **Advanced Usage:**
121
- - [MCP Integration](docs/user/MCP_INTEGRATION.md) - AI assistant configuration
122
- - [CLI Fallback for LLMs](docs/user/CLI_FALLBACK_FOR_LLMS.md) - Using CLI when MCP isn't available
123
- - [Library API](docs/user/LIBRARY_API.md) - Ruby API documentation
124
125
  - [Advanced Usage](docs/user/ADVANCED_USAGE.md) - Staleness detection, error modes, path resolution
126
+ - [Library API](docs/user/LIBRARY_API.md) - Ruby API documentation
125
127
  - [Error Handling](docs/user/ERROR_HANDLING.md) - Error modes and exceptions
128
+ - [MCP Integration](docs/user/MCP_INTEGRATION.md) - AI assistant configuration
129
+ - [Troubleshooting](docs/user/TROUBLESHOOTING.md) - Common issues
130
+
131
+ **Special Topics & Prompts:**
126
132
 
127
- **Reference:**
133
+ - [CLI Fallback for LLMs](docs/user/CLI_FALLBACK_FOR_LLMS.md) - When MCP isn't available
134
+ - [Sample MCP Prompts](docs/user/prompts/README.md) - Ready-to-use ChatGPT/Claude/Gemini prompts
135
+ - [Migration Guides](docs/user/migrations/README.md)
136
+ - [Migrate to v4](docs/user/migrations/MIGRATING_TO_V4.md)
137
+ - [Migrate to v3](docs/user/migrations/MIGRATING_TO_V3.md)
138
+ - [Migrate to v2](docs/user/migrations/MIGRATING_TO_V2.md)
139
+
140
+ **Developer Docs:**
141
+
142
+ - [Developer Docs Overview](docs/dev/README.md) - Entry point for contributors
128
143
  - [Architecture](docs/dev/ARCHITECTURE.md) - Design and internals
129
- - [Branch Coverage](docs/dev/BRANCH_ONLY_COVERAGE.md) - Branch coverage limitations
130
- - [Troubleshooting](docs/user/TROUBLESHOOTING.md) - Common issues
131
- - [Development](docs/dev/DEVELOPMENT.md) - Contributing guide
144
+ - [Development Guide](docs/dev/DEVELOPMENT.md) - Local dev workflow
145
+ - [Releasing](docs/dev/RELEASING.md) - Release checklist
146
+ - [Future Enhancements](docs/dev/FUTURE_ENHANCEMENTS.md) - Planned improvements
147
+ - [Architecture Decision Records](docs/dev/arch-decisions/README.md) - Design history
148
+
149
+ **Project Docs & Examples:**
150
+
151
+ - [Contributing](docs/contributing.md)
152
+ - [Code of Conduct](docs/code_of_conduct.md)
153
+ - [Release Notes](docs/release_notes.md)
154
+ - [License](docs/license.md)
155
+ - [MCP Input Examples](docs/examples/mcp-inputs.md)
156
+ - [Prompt Examples](docs/examples/prompts.md)
157
+ - [Predicate Examples](docs/examples/success_predicates.md)
132
158
 
133
159
  ## Requirements
134
160
 
@@ -141,18 +167,20 @@ When a `.resultset.json` file contains multiple test suites (e.g., RSpec + Cucum
141
167
  `cov-loupe` automatically searches for `.resultset.json` in standard locations (`coverage/.resultset.json`, `.resultset.json`, `tmp/.resultset.json`). For non-standard locations:
142
168
 
143
169
  ```sh
144
- # Command-line option (highest priority)
145
- cov-loupe --resultset /path/to/your/coverage
170
+ # Command-line option (highest priority) - use -r or --resultset
171
+ cov-loupe -r /path/to/your/coverage
146
172
 
147
173
  # Environment variable (project-wide default)
148
- export COV_LOUPE_OPTS="--resultset /path/to/your/coverage"
174
+ export COV_LOUPE_OPTS="-r /path/to/your/coverage"
149
175
 
150
176
  # MCP server configuration
151
- # Add to your MCP client config:
152
- # "args": ["--resultset", "/path/to/your/coverage"]
177
+ # Add to your MCP client config (used as defaults for MCP tools):
178
+ # "args": ["-r", "/path/to/your/coverage"]
153
179
  ```
154
180
 
155
- See [CLI Usage Guide](docs/user/CLI_USAGE.md#-r---resultset-path) for complete details.
181
+ **MCP precedence:** For MCP tool calls, per-request JSON parameters win over the CLI args used to start the server (including `COV_LOUPE_OPTS`). If neither is provided, built-in defaults are used (`root: '.'`, `raise_on_stale: false`, etc.). Coverage data is cached globally and automatically reloaded when the resultset file changes.
182
+
183
+ See [CLI Usage Guide](docs/user/CLI_USAGE.md) for complete details.
156
184
 
157
185
 
158
186
 
@@ -163,16 +191,38 @@ See [CLI Usage Guide](docs/user/CLI_USAGE.md#-r---resultset-path) for complete d
163
191
  ```sh
164
192
  # Files with worst coverage
165
193
  cov-loupe -o d list # -o = --sort-order, d = descending (worst at end)
166
- cov-loupe list | less # display table in pager, worst files first
194
+ cov-loupe list | less # display table in pager, best files first (worst at end)
167
195
  cov-loupe list | head -10 # truncate the table
168
196
 
169
- # Specific directory
197
+ # Filter to specific patterns (see COV_LOUPE_OPTS best practice below)
170
198
  cov-loupe -g "lib/cov_loupe/tools/**/*.rb" list # -g = --tracked-globs
171
199
 
172
200
  # Export for analysis
173
201
  cov-loupe -fJ list > coverage-report.json
174
202
  ```
175
203
 
204
+ ### Best Practice: Match SimpleCov Configuration
205
+
206
+ For accurate coverage tracking and validation, set `COV_LOUPE_OPTS` to match your SimpleCov `track_files` patterns:
207
+
208
+ ```ruby
209
+ # In spec_helper.rb or rails_helper.rb
210
+ SimpleCov.start do
211
+ add_filter '/spec/'
212
+ track_files 'lib/**/*.rb'
213
+ track_files 'app/**/*.rb'
214
+ end
215
+ ```
216
+
217
+ ```sh
218
+ # In your shell config (.bashrc, .zshrc, etc.)
219
+ export COV_LOUPE_OPTS="--tracked-globs lib/**/*.rb,app/**/*.rb"
220
+ ```
221
+
222
+ This ensures `list` and `totals` output matches SimpleCov's scope and `missing_tracked_files` (in `list`) / `missing_from_coverage` (in `totals`) report meaningful gaps.
223
+
224
+ **Note:** By default, `--tracked-globs` is empty (shows all files in the resultset). This prevents silently hiding coverage data that doesn't match assumed patterns.
225
+
176
226
  ### Working with JSON Output
177
227
 
178
228
  The `-fJ` flag enables programmatic processing of coverage data using command-line JSON tools.
@@ -204,21 +254,58 @@ cov-loupe -fJ list | rexe -ij -mb -oJ 'self["files"].select { |f| f["percentage"
204
254
  # Count files below threshold
205
255
  cov-loupe -fJ list | rexe -ij -mb -op 'self["files"].count { |f| f["percentage"] < 80 }'
206
256
 
207
- # Human-readable output with AwesomePrint
257
+ # Human-readable output with AmazingPrint
208
258
  cov-loupe -fJ list | rexe -ij -mb -oa 'self["files"].first(3)'
209
259
  ```
210
260
 
211
- With rexe's `-ij -mb` options, `self` automatically becomes the parsed JSON object. The same holds true for JSON output -- using `-oJ` produces pretty-printed JSON without explicit formatting calls. Rexe also supports YAML input/output (`-iy`, `-oy`) and AwesomePrint output (`-oa`) for human consumption.
261
+ With rexe's `-ij -mb` options, `self` automatically becomes the parsed JSON object. The same holds true for JSON output -- using `-oJ` produces pretty-printed JSON without explicit formatting calls. Rexe also supports YAML input/output (`-iy`, `-oy`) and AmazingPrint output (`-oa`) for human consumption.
262
+
263
+ ### When Coverage Rows Are Skipped
264
+
265
+ If a file in the resultset is missing on disk or has corrupt data, the CLI now logs and *warns* after rendering the report so operators immediately see that totals may be incomplete. Example table output:
266
+
267
+ ```text
268
+ $ cov-loupe list
269
+ ┌─────────────────────────────┬─────────┬─────────┬────────────┬───────┐
270
+ │ File │ Covered │ Total │ % Covered │ Stale │
271
+ ├─────────────────────────────┼─────────┼─────────┼────────────┼───────┤
272
+ │ lib/foo.rb │ 2 │ 3 │ 66.67% │ │
273
+ │ lib/bar.rb │ 1 │ 3 │ 33.33% │ │
274
+ └─────────────────────────────┴─────────┴─────────┴────────────┴───────┘
275
+
276
+ WARNING: 1 coverage row skipped due to errors:
277
+ - lib/deleted.rb: No coverage data found for file: lib/deleted.rb
278
+ Run again with --raise-on-stale to exit when rows are skipped.
279
+ ```
280
+
281
+ Pretty JSON (`-fJ`) reports still emit valid JSON to `stdout`; the warning continues to be printed on `stderr`:
282
+
283
+ ```text
284
+ $ cov-loupe -fJ list
285
+ {
286
+ "files": [
287
+ { "file": "lib/foo.rb", "covered": 2, "total": 3, "percentage": 66.67, "stale": null },
288
+ { "file": "lib/bar.rb", "covered": 1, "total": 3, "percentage": 33.33, "stale": null }
289
+ ],
290
+ "counts": { "total": 2, "ok": 2, "stale": 0 }
291
+ }
292
+
293
+ WARNING: 1 coverage row skipped due to errors:
294
+ - lib/deleted.rb: No coverage data found for file: lib/deleted.rb
295
+ Run again with --raise-on-stale to exit when rows are skipped.
296
+ ```
297
+
298
+ Use `--raise-on-stale true` (or `-S true`) to turn these warnings into hard failures for CI pipelines.
212
299
 
213
300
  Run `rexe -h` to see all available options, or visit the [rexe project page](https://github.com/keithrbennett/rexe) for more examples.
214
301
 
215
- For comprehensive JSON processing examples, see [docs/user/EXAMPLES.md](docs/user/EXAMPLES.md).
302
+ For comprehensive JSON processing examples, see [user/EXAMPLES.md](docs/user/EXAMPLES.md).
216
303
 
217
304
  ### CI/CD Integration
218
305
 
219
306
  ```sh
220
- # Fail build if coverage is stale
221
- cov-loupe --staleness error || exit 1
307
+ # Fail build if coverage is stale (--raise-on-stale or -S)
308
+ cov-loupe --raise-on-stale true list || exit 1
222
309
 
223
310
  # Generate coverage report artifact
224
311
  cov-loupe -fJ list > artifacts/coverage.json
@@ -244,19 +331,41 @@ cov-loupe totals
244
331
  cov-loupe -fJ totals
245
332
  ```
246
333
 
334
+ ### Boolean CLI Options
335
+
336
+ Boolean flags such as `--color` (short: `-C`) and `--raise-on-stale` (short: `-S`) require explicit boolean arguments. Recognized literals:
337
+
338
+ | | |
339
+ |--------|--------|
340
+ | `yes` | `no` |
341
+ | `y` | `n` |
342
+ | `true` | `false`|
343
+ | `t` | `f` |
344
+ | `on` | `off` |
345
+ | `+` | `-` |
346
+ | `1` | `0` |
347
+
348
+ Each row lists the equivalent `true` token (left) and `false` token (right).
349
+
350
+ ```sh
351
+ cov-loupe --color false # disable ANSI colors explicitly
352
+ cov-loupe -C false # short form
353
+ cov-loupe --raise-on-stale yes # enforce stale coverage failures
354
+ ```
355
+
247
356
  ## Commands and Tools
248
357
 
249
358
  **CLI Subcommands:** `list`, `summary`, `uncovered`, `detailed`, `raw`, `totals`, `validate`, `version`
250
359
 
251
- **MCP Tools:** `coverage_summary_tool`, `coverage_detailed_tool`, `coverage_raw_tool`, `uncovered_lines_tool`, `all_files_coverage_tool`, `coverage_totals_tool`, `coverage_table_tool`, `validate_tool`, `help_tool`, `version_tool`
360
+ **MCP Tools:** `coverage_summary_tool`, `coverage_detailed_tool`, `coverage_raw_tool`, `uncovered_lines_tool`, `list_tool`, `coverage_totals_tool`, `coverage_table_tool`, `validate_tool`, `help_tool`, `version_tool`
252
361
 
253
362
  📖 **See also:**
254
363
  - [CLI Usage Guide](docs/user/CLI_USAGE.md) - Complete command-line reference
255
- - [MCP Integration Guide](docs/user/MCP_INTEGRATION.md#available-mcp-tools) - MCP tools documentation
364
+ - [MCP Integration Guide](docs/user/MCP_INTEGRATION.md#available-mcp-tools-functions) - MCP tools documentation
256
365
 
257
366
  ## Troubleshooting
258
367
 
259
- - **"command not found"** - See [Installation Guide](docs/user/INSTALLATION.md#path-configuration)
368
+ - **"command not found"** - See [Installation Guide](docs/user/INSTALLATION.md#require-path)
260
369
  - **"cannot load such file -- mcp"** - Requires Ruby >= 3.2. Verify: `ruby -v`
261
370
  - **"Could not find .resultset.json"** - Ensure SimpleCov is configured in your test suite, then run tests to generate coverage. See the [Configuring the Resultset](#configuring-the-resultset) section for more details.
262
371
  - **MCP server won't connect** - Check PATH and Ruby version in [MCP Troubleshooting](docs/user/MCP_INTEGRATION.md#troubleshooting)
@@ -283,7 +392,7 @@ gem build cov-loupe.gemspec
283
392
  gem install cov-loupe-*.gem
284
393
  ```
285
394
 
286
- See [docs/dev/DEVELOPMENT.md](docs/dev/DEVELOPMENT.md) for more.
395
+ See [dev/DEVELOPMENT.md](docs/dev/DEVELOPMENT.md) for more.
287
396
 
288
397
  ## SimpleCov Dependency
289
398
 
@@ -301,20 +410,14 @@ Contributions are welcome! Please:
301
410
 
302
411
  ## License
303
412
 
304
- MIT License - see [LICENSE](LICENSE) file for details.
413
+ MIT License - see [LICENSE](docs/license.md) file for details.
305
414
 
306
415
  ## Links
307
416
 
308
417
  - **GitHub:** https://github.com/keithrbennett/cov-loupe
309
418
  - **RubyGems:** https://rubygems.org/gems/cov-loupe
310
419
  - **Issues:** https://github.com/keithrbennett/cov-loupe/issues
311
- - **Changelog:** [RELEASE_NOTES.md](RELEASE_NOTES.md)
312
-
313
- ## Related Files
314
-
315
- - [CLAUDE.md](CLAUDE.md) - Claude Code integration notes
316
- - [AGENTS.md](AGENTS.md) - AI agent configuration
317
- - [GEMINI.md](GEMINI.md) - Gemini-specific guidance
420
+ - **Changelog:** [RELEASE_NOTES.md](docs/release_notes.md)
318
421
 
319
422
  ---
320
423