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
@@ -1,158 +1,54 @@
1
1
  # MCP Integration Guide
2
2
 
3
- [Back to main README](../README.md)
3
+ [Back to main README](../index.md)
4
+
5
+ > **⚠️ BREAKING CHANGE (v4.0.0+):** The `-m/--mode mcp` flag is now **required** to run cov-loupe as an MCP server.
6
+ > Automatic mode detection based on TTY/stdin has been removed. If you're upgrading from an earlier version, you **must** update your MCP server configuration to include `-m mcp` or `--mode mcp` or the server will run in CLI mode and hang. See [Migration Guide](migrations/MIGRATING_TO_V4.md) for details.
4
7
 
5
8
  ## Table of Contents
6
9
 
7
- - [What is MCP?](#what-is-mcp)
8
- - [Prerequisites](#prerequisites)
9
- - [Quick Start](#quick-start)
10
10
  - [Setup by Client](#setup-by-client)
11
- - [Available MCP Tools](#available-mcp-tools)
11
+ - [Available MCP Tools](#available-mcp-tools-functions)
12
12
  - [Testing Your Setup](#testing-your-setup)
13
13
  - [Troubleshooting](#troubleshooting)
14
14
 
15
- ## What is MCP?
16
-
17
- The Model Context Protocol (MCP) is a standard for integrating tools and data sources with AI assistants. By running cov-loupe as an MCP server, you enable AI coding assistants to:
18
-
19
- - Query coverage data for files
20
- - Identify uncovered code
21
- - Analyze coverage gaps
22
- - Suggest improvements based on coverage data
23
-
24
- ### Why Use MCP with Coverage Tools?
25
-
26
- AI assistants can help you:
27
- - **Prioritize testing** - "Which files need coverage most urgently?"
28
- - **Understand gaps** - "Why is this file's coverage low?"
29
- - **Generate tests** - "Write tests for uncovered lines in this file"
30
- - **Track progress** - "Has coverage improved since last commit?"
31
-
32
- ## Prerequisites
33
-
34
- - **Ruby >= 3.2** (required by MCP gem dependency)
35
- - **cov-loupe installed** - See [Installation Guide](INSTALLATION.md)
36
- - **simplecov gem >= 0.21** - Needed when a resultset contains multiple suites (loaded lazily)
37
- - **Coverage data** - Run tests to generate `coverage/.resultset.json`
38
- - **MCP-compatible client** - Claude Code, Cursor, Codex, etc.
39
-
40
- ## Quick Start
41
-
42
- ### 1. Install cov-loupe
43
-
44
- ```sh
45
- gem install cov-loupe
46
- ```
47
-
48
- ### 2. Verify Installation
49
-
50
- ```sh
51
- # Find the executable path (needed for MCP configuration)
52
- which cov-loupe
53
-
54
- # Test it works
55
- cov-loupe version
56
- ```
57
-
58
- ### 3. Configure Your AI Assistant
59
-
60
- See [Setup by Client](#setup-by-client) below for specific instructions.
61
-
62
- ### 4. Generate Coverage Data
63
-
64
- ```sh
65
- # Run your test suite
66
- bundle exec rspec # or your test command
67
-
68
- # Verify coverage file exists
69
- ls coverage/.resultset.json
70
- ```
71
-
72
- > **Multi-suite note:** If the resultset contains several suites (e.g., `RSpec` and `Cucumber`), cov-loupe lazily loads the `simplecov` gem and merges them before answering coverage queries. Staleness checks currently use the newest suite’s timestamp, so treat multi-suite freshness warnings as advisory until per-file timestamps are introduced.
73
- >
74
- > Only suites stored in a *single* `.resultset.json` are merged automatically. If your test runs produce multiple resultset files, merge them (e.g., via `SimpleCov::ResultMerger.merge_and_store`) and point cov-loupe at the combined file.
75
-
76
- > Multifile support may be added in a future version (post an issue if you want this).
77
-
78
- ### 5. Test the MCP Server
79
-
80
- ```sh
81
- # Test manually
82
- echo '''{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"version_tool","arguments":{}}}''' | cov-loupe
83
- ```
84
-
85
- You should see a JSON-RPC response with version information.
86
-
87
15
  ## Setup by Client
88
16
 
89
- ### Claude Code
17
+ For the `mcp add` commands, the executable path comes after the server name. You can optionally pass arguments to the executable after that (e.g., `-- --error-mode debug`).
90
18
 
91
- **Current Status:** Claude Code has a bug in its MCP client that prevents it from working with spec-compliant MCP servers like cov-loupe. Claude Code will automatically fall back to using the CLI interface.
92
-
93
- **Bug Report:** [Claude Code Issue #8239](https://github.com/anthropics/claude-code/issues/8239)
94
-
95
- **Workaround:** Use the CLI interface, which provides the same functionality:
96
- ```sh
97
- # Instead of MCP tools, use CLI
98
- cov-loupe list
99
- cov-loupe summary lib/cov_loupe/cli.rb
100
- ```
19
+ **Note:** If you change which Ruby version you use, you will need to `bundle install` or `gem install cov-loupe` again with the new version active. Additionally, if your MCP server configuration uses an absolute path, that configuration will need to be updated as well.
101
20
 
102
- **Configuration (for when bug is fixed):**
103
-
104
- Using the Claude CLI tool:
21
+ ### Claude Code
105
22
 
106
23
  ```sh
107
- # Basic setup (if cov-loupe is in default PATH)
108
- claude mcp add cov-loupe cov-loupe
109
-
110
- # With rbenv/asdf (use absolute path)
111
- claude mcp add cov-loupe /Users/yourname/.rbenv/shims/cov-loupe
24
+ # Add the MCP server; equivalent to ...--scope local...
25
+ claude mcp add cov-loupe cov-loupe -- -m mcp
112
26
 
113
- # With RVM wrapper (recommended for stability)
114
- rvm wrapper ruby-3.3.8 cov-loupe cov-loupe
115
- claude mcp add cov-loupe /Users/yourname/.rvm/wrappers/ruby-3.3.8/cov-loupe
27
+ # For user-wide configuration
28
+ claude mcp add --scope user cov-loupe cov-loupe -- -m mcp
116
29
 
117
- # For user-wide configuration (default is local)
118
- claude mcp add --scope user cov-loupe cov-loupe
119
-
120
- # For project-specific configuration
121
- claude mcp add --scope project cov-loupe cov-loupe
122
- ```
30
+ # For project-specific configuration.
31
+ claude mcp add --scope project cov-loupe cov-loupe -- -m mcp
123
32
 
124
- **Verify configuration:**
125
- ```sh
126
33
  # List configured MCP servers
127
34
  claude mcp list
128
35
 
129
36
  # Get server details
130
37
  claude mcp get cov-loupe
131
38
 
132
- # Remove if needed
133
- claude mcp remove cov-loupe
39
+ # Remove if needed (use --scope to match where it was added)
40
+ claude mcp remove cov-loupe # Removes from local scope (default)
41
+ claude mcp remove --scope user cov-loupe # Removes from user scope
42
+ claude mcp remove --scope project cov-loupe # Removes from project scope
134
43
  ```
135
44
 
136
- **Important Notes:**
137
- - Default scope is `local` (current project)
138
- - Use `--scope user` for global config, `--scope project` for project-specific
139
- - The executable path is tied to Ruby version with version managers
140
- - If you change Ruby versions, remove and re-add the configuration
141
-
142
- ### Cursor / Codex
45
+ ### Codex
143
46
 
144
47
  Using the Codex CLI:
145
48
 
146
49
  ```sh
147
- # Basic setup (if cov-loupe is in default PATH)
148
- codex mcp add cov-loupe --command cov-loupe
149
-
150
- # With rbenv/asdf (use absolute path)
151
- codex mcp add cov-loupe --command /Users/yourname/.rbenv/shims/cov-loupe
152
-
153
- # With RVM wrapper (recommended for stability)
154
- rvm wrapper ruby-3.3.8 cov-loupe cov-loupe
155
- codex mcp add cov-loupe --command /Users/yourname/.rvm/wrappers/ruby-3.3.8/cov-loupe
50
+ # Add the MCP server
51
+ codex mcp add cov-loupe cov-loupe -m mcp
156
52
 
157
53
  # List configured servers
158
54
  codex mcp list
@@ -160,56 +56,45 @@ codex mcp list
160
56
  # Show server details
161
57
  codex mcp get cov-loupe
162
58
 
163
- # Remove if needed
59
+ # Remove if needed (check codex documentation for scope options if applicable)
164
60
  codex mcp remove cov-loupe
165
61
  ```
166
62
 
167
- **Find your executable path:**
168
- ```sh
169
- which cov-loupe
63
+ **Important:** Codex does not pass environment variables like `GEM_HOME`/`GEM_PATH` to MCP servers
64
+ by default. After adding the server, you **must** manually edit `~/.codex/config.toml` to add the 'env_vars' setting:
65
+
66
+ ```toml
67
+ [mcp_servers.cov-loupe]
68
+ command = "cov-loupe"
69
+ args = ["-m", "mcp"]
70
+ env_vars = ["GEM_HOME", "GEM_PATH"] # Add this line manually
170
71
  ```
171
72
 
73
+ **Warning:** If you run `codex mcp remove cov-loupe`, the `env_vars` line will be deleted along with the rest of the section.
74
+ You'll need to manually add it back after running `codex mcp add` again.
75
+ To avoid this, consider editing `~/.codex/config.toml` directly instead of using `remove`/`add` commands.
76
+
172
77
  ### Gemini
173
78
 
174
79
  Using the Gemini CLI:
175
80
 
176
81
  ```sh
177
- # Add MCP server
178
- gemini mcp add cov-loupe /Users/yourname/.rbenv/shims/cov-loupe
179
-
180
- # Or with RVM
181
- gemini mcp add cov-loupe /Users/yourname/.rvm/wrappers/ruby-3.3.8/cov-loupe
82
+ # Add the MCP server
83
+ gemini mcp add cov-loupe cov-loupe -- -m mcp
182
84
 
183
85
  # List configured servers
184
86
  gemini mcp list
185
87
 
186
- # Remove if needed
88
+ # Remove if needed (check gemini documentation for scope options if applicable)
187
89
  gemini mcp remove cov-loupe
188
90
  ```
189
91
 
190
- ### Generic MCP Client
191
-
192
- For any MCP client that uses JSON configuration:
193
-
194
- ```json
195
- {
196
- "mcpServers": {
197
- "cov-loupe": {
198
- "command": "/path/to/cov-loupe",
199
- "args": [],
200
- "env": {
201
- "COV_LOUPE_OPTS": "--resultset coverage"
202
- }
203
- }
204
- }
205
- }
206
- ```
207
92
 
208
93
  **Environment variables you can set:**
209
94
 
210
95
  - `COV_LOUPE_OPTS` - Default CLI options (though less useful for MCP mode)
211
96
 
212
- ## Available MCP Tools
97
+ ## Available MCP Tools (Functions)
213
98
 
214
99
  ### Tool Catalog
215
100
 
@@ -221,7 +106,7 @@ cov-loupe exposes 10 MCP tools:
221
106
  | `coverage_detailed_tool` | Per-line coverage | `path` |
222
107
  | `coverage_raw_tool` | Raw SimpleCov array | `path` |
223
108
  | `uncovered_lines_tool` | List uncovered lines | `path` |
224
- | `all_files_coverage_tool` | Project-wide coverage | `sort_order`, `tracked_globs` |
109
+ | `list_tool` | Project-wide coverage | `sort_order`, `tracked_globs` |
225
110
  | `coverage_totals_tool` | Aggregated line totals | `tracked_globs` |
226
111
  | `coverage_table_tool` | Formatted coverage table | `sort_order` |
227
112
  | `validate_tool` | Validate coverage policies | `code` or `file` |
@@ -236,7 +121,7 @@ For tools that return structured data, `cov-loupe` serializes the data as a JSON
236
121
  ```json
237
122
  {
238
123
  "type": "text",
239
- "text": "{"coverage_summary":{"covered":10,"total":20,"percentage":50.0}}"
124
+ "text": "{\"file\":\"lib/foo.rb\",\"summary\":{\"covered\":10,\"total\":20,\"percentage\":50.0},\"stale\":false}"
240
125
  }
241
126
  ```
242
127
 
@@ -250,15 +135,45 @@ This decision was informed by discussions with multiple AI models. For more deta
250
135
  - [Perplexity AI Discussion](https://www.perplexity.ai/search/title-resolving-a-model-contex-IfpFWU1FR5WQXQ8HcQctyg#0)
251
136
  - [ChatGPT Discussion](https://chatgpt.com/share/68e4d7e1-cad4-800f-80c2-58b33bfc31cb)
252
137
 
138
+ ### CLI Options in MCP Mode
139
+
140
+ When the MCP server starts, you can pass CLI options via the startup command. These options become the default config for MCP tools. **Per-request JSON parameters still win over CLI defaults.**
141
+
142
+ | CLI Option | Affects MCP Server? | JSON Parameter | Notes |
143
+ |------------|-------------------|----------------|-------|
144
+ | `-R`, `--root` | ✅ Default | `root` | Request param overrides; CLI sets default |
145
+ | `-r`, `--resultset` | ✅ Default | `resultset` | Request param overrides; CLI sets default |
146
+ | `-S`, `--raise-on-stale` | ✅ Default | `raise_on_stale` | Request param overrides; CLI sets default (`false` or `true`) |
147
+ | `-g`, `--tracked-globs` | ✅ Default | `tracked_globs` | Request param overrides; CLI sets default (array) |
148
+ | `--error-mode` | ✅ Yes | `error_mode` | Sets server-wide error handling; can override per tool |
149
+ | `-l`, `--log-file` | ✅ Yes | N/A | Sets server log location (cannot override per tool) |
150
+ | `-f`, `--format` | ❌ No | N/A | CLI-only presentation flag (not used by MCP) |
151
+ | `-o`, `--sort-order` | ❌ No | `sort_order` | CLI flag ignored in MCP; pass per tool call (`\"ascending\"` or `\"descending\"`) |
152
+ | `-s`, `--source` | ❌ No | N/A | CLI-only presentation flag (not used by MCP) |
153
+ | `-c`, `--context-lines` | ❌ No | N/A | CLI-only presentation flag (not used by MCP) |
154
+ | `-C`, `--color BOOLEAN` | ❌ No | N/A | CLI-only presentation flag (not used by MCP) |
155
+ | `-m`, `--mode` | ✅ Required | N/A | **Required for MCP mode:** `-m mcp` or `--mode mcp`. Default: `cli`. |
156
+
157
+ **Key Takeaways:**
158
+ - **Server-level options** (`--error-mode`, `--log-file`): Set once when server starts, apply to all tool calls
159
+ - **Tool-level options** (`root`, `resultset`, `raise_on_stale`, `tracked_globs`): CLI args provide defaults; per-tool JSON params override when provided
160
+ - **CLI-only options** (`--format`, `--source`, etc.): Not applicable to MCP mode
161
+
162
+ **Precedence for MCP tool config:** `JSON request param` > `CLI args used to start MCP` (including `COV_LOUPE_OPTS`) > built-in defaults (`root: '.'`, `raise_on_stale: false`, `resultset: nil`, `tracked_globs: []` - no filtering, no tracking).
163
+
164
+ CLI-only presentation flags (`-f/--format`, `-s/--source`, `-c/--context-lines`, `-C/--color`, and CLI `-o/--sort-order` defaults) never flow into MCP. Pass `sort_order` explicitly in each tool request when you need non-default ordering.
165
+
166
+ **Data caching:** Coverage data is cached in a global singleton (`ModelDataCache`) and shared across all `CoverageModel` instances. When the resultset file changes (based on file signature and MD5 digest), the cache automatically reloads fresh data. Model instances themselves are lightweight and created fresh for each tool request.
167
+
253
168
  ### Common Parameters
254
169
 
255
- All file-specific tools accept these parameters:
170
+ All file-specific tools accept these parameters in the JSON request:
256
171
 
257
172
  - `path` (required for file tools) - File path (relative or absolute)
258
173
  - `root` (optional) - Project root directory (default: `.`)
259
- - `resultset` (optional) - Path to the `.resultset.json` file. See [Configuring the Resultset](../README.md#configuring-the-resultset) for details.
260
- - `staleness` (optional) - Staleness mode: `"off"` (default) or `"error"`
261
- - `error_mode` (optional) - Error handling: `"off"`, `"log"` (default), `"debug"`
174
+ - `resultset` (optional) - Path to the `.resultset.json` file. See [Configuring the Resultset](../index.md#configuring-the-resultset) for details.
175
+ - `raise_on_stale` (optional) - Raise error on staleness: `false` (default) or `true`
176
+ - `error_mode` (optional) - Error handling: `"off"`, `"log"` (default), `"debug"` (overrides server-level setting)
262
177
 
263
178
  ### Tool Details
264
179
 
@@ -268,46 +183,49 @@ These tools analyze individual files. All require `path` parameter.
268
183
 
269
184
  **`coverage_summary_tool`** - Covered/total/percentage summary
270
185
  ```json
271
- {"file": "...", "summary": {"covered": 12, "total": 14, "percentage": 85.71}, "stale": false}
186
+ {"file": "...", "summary": {"covered": 12, "total": 14, "percentage": 85.71}, "stale": "ok"}
272
187
  ```
273
188
 
274
189
  **`uncovered_lines_tool`** - List uncovered line numbers
275
190
  ```json
276
- {"file": "...", "uncovered": [5, 9, 12], "summary": {...}, "stale": false}
191
+ {"file": "...", "uncovered": [5, 9, 12], "summary": {...}, "stale": "ok"}
277
192
  ```
278
193
 
279
194
  **`coverage_detailed_tool`** - Per-line hit counts
280
195
  ```json
281
- {"file": "...", "lines": [{"line": 1, "hits": 1, "covered": true}, ...], "summary": {...}, "stale": false}
196
+ {"file": "...", "lines": [{"line": 1, "hits": 1, "covered": true}, ...], "summary": {...}, "stale": "ok"}
282
197
  ```
283
198
 
284
199
  **`coverage_raw_tool`** - Raw SimpleCov lines array
285
200
  ```json
286
- {"file": "...", "lines": [1, 0, null, 5, 2, null, 1], "stale": false}
201
+ {"file": "...", "lines": [1, 0, null, 5, 2, null, 1], "stale": "ok"}
287
202
  ```
288
203
 
204
+ **Staleness values:** `"ok"` (fresh), `"missing"` (missing), `"newer"` (timestamp), `"length_mismatch"` (length), `"error"` (staleness check error)
205
+
289
206
  #### Project-Wide Tools
290
207
 
291
- **`all_files_coverage_tool`** - Coverage for all files
208
+ **`list_tool`** - Coverage for all files
292
209
  - Parameters: `sort_order` (`ascending`|`descending`), `tracked_globs` (array)
293
- - Returns: `{"files": [...], "counts": {"total": N, "ok": N, "stale": N}}`
210
+ - Returns: `{"files": [...], "counts": {"total": N, "ok": N, "stale": N}, "skipped_files": [...], "missing_tracked_files": [...], "newer_files": [...], "deleted_files": [...], "length_mismatch_files": [...], "unreadable_files": [...], "timestamp_status": "ok|missing"}`
294
211
 
295
212
  **`coverage_totals_tool`** - Aggregated line totals
296
- - Parameters: `tracked_globs` (array), `staleness`
297
- - Returns: `{"lines":{"total":N,"covered":N,"uncovered":N},"percentage":Float,"files":{"total":N,"ok":N,"stale":N}}`
213
+ - Parameters: `tracked_globs` (array), `raise_on_stale`
214
+ - Returns: `{"lines":{"total":N,"covered":N,"uncovered":N,"percent_covered":Float},"tracking":{"enabled":Boolean,"globs":[String]},"files":{"total":N,"with_coverage":{"total":N,"ok":N,"stale":{"total":N,"by_type":{"missing_from_disk":N,"newer":N,"length_mismatch":N,"unreadable":N}}},"without_coverage":{"total":N,"by_type":{"missing_from_coverage":N,"unreadable":N,"skipped":N}}}}`
215
+ - `without_coverage` is only present when tracking is enabled (tracked globs provided).
298
216
 
299
- **`coverage_table_tool`** - Formatted ASCII table
217
+ **`coverage_table_tool`** - Formatted table with box-drawing characters
300
218
  - Parameters: `sort_order` (`ascending`|`descending`)
301
219
  - Returns: Plain text table
302
220
 
303
221
  #### Policy Validation Tools
304
222
 
305
223
  **`validate_tool`** - Validate coverage against custom policies
306
- - Parameters: Either `code` (Ruby string) OR `file` (path to Ruby file), plus optional `root`, `resultset`, `staleness`, `error_mode`
224
+ - Parameters: Either `code` (Ruby string) OR `file` (path to Ruby file), plus optional `root`, `resultset`, `raise_on_stale`, `error_mode`
307
225
  - Returns: `{"result": Boolean}` where `true` means policy passed, `false` means failed
308
226
  - Security Warning: Predicates execute as arbitrary Ruby code with full system privileges. Only use predicate files from trusted sources.
309
227
  - Examples:
310
- - Check if all files have at least 80% coverage: `{"code": "->(m) { m.all_files.all? { |f| f['percentage'] >= 80 } }"}`
228
+ - Check if all files have at least 80% coverage: `{"code": "->(m) { m.list.all? { |f| f['percentage'] >= 80 } }"}`
311
229
  - Run coverage policy from file: `{"file": "coverage_policy.rb"}`
312
230
 
313
231
  #### Utility Tools
@@ -317,6 +235,8 @@ These tools analyze individual files. All require `path` parameter.
317
235
 
318
236
  ## Example Prompts for AI Assistants
319
237
 
238
+ (Hopefully, your AI agent will not need you to explicilty specify "Using cov-loupe",
239
+ but this is included here because we have seen cases where it does not know to use cov-loupe.)
320
240
  ### Coverage Analysis
321
241
 
322
242
  ```
@@ -344,7 +264,7 @@ Using cov-loupe, find the most important uncovered code in lib/cov_loupe/tools/c
344
264
  ### Test Generation
345
265
 
346
266
  ```
347
- Using cov-loupe, find uncovered lines in lib/cov_loupe/staleness_checker.rb and write RSpec tests for them.
267
+ Using cov-loupe, find uncovered lines in lib/cov_loupe/staleness_checker.rb and write *meaningful* RSpec tests for them.
348
268
  ```
349
269
 
350
270
  ```
@@ -367,17 +287,23 @@ Using cov-loupe, create a markdown report of:
367
287
  Test the MCP server responds to JSON-RPC:
368
288
 
369
289
  ```sh
370
- # Test version tool (simplest)
371
- echo '''{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"version_tool","arguments":{}}}''' | cov-loupe
290
+ # Test version tool (simplest, no parameters needed)
291
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"version_tool","arguments":{}}}' | cov-loupe -m mcp
292
+
293
+ # Test help tool (no parameters needed)
294
+ echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"help_tool","arguments":{}}}' | cov-loupe -m mcp
372
295
 
373
- # Test summary tool
374
- echo '''{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/cov_loupe/model.rb"}}}''' | cov-loupe
296
+ # Test summary tool (use root param if needed)
297
+ echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/cov_loupe/model.rb","root":"."}}}' | cov-loupe -m mcp
375
298
 
376
- # Test help tool
377
- echo '''{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"help_tool","arguments":{}}}''' | cov-loupe
299
+ # Test with a project-specific root
300
+ echo '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"app/models/order.rb","root":"docs/fixtures/demo_project"}}}' | cov-loupe -m mcp
378
301
  ```
379
302
 
380
- **Important:** JSON-RPC messages must be on a single line. Multi-line JSON will cause parse errors.
303
+ **Important Notes:**
304
+ - JSON-RPC messages must be on a single line. Multi-line JSON will cause parse errors.
305
+ - CLI flags like `-R` set server defaults, but per-request JSON parameters still win.
306
+ - The `root` parameter is optional and defaults to `.` (current directory).
381
307
 
382
308
  ### Testing in AI Assistant
383
309
 
@@ -412,7 +338,9 @@ tail -f cov_loupe.log
412
338
  grep ERROR cov_loupe.log | tail -20
413
339
  ```
414
340
 
415
- To override the default log file location, specify the `--log-file` argument wherever and however you configure your MCP server. For example, to log to a different file path, include `--log-file /path/to/logfile.log` in your server configuration. To log to standard error, use `--log-file stderr`.
341
+ To override the default log file location, specify the `--log-file` (or `-l`) argument wherever and however you configure your MCP server. For example, to log to a different file path, include `-l /path/to/logfile.log` in your server configuration. To log to standard error, use `-l stderr`.
342
+
343
+ **Warning:** Log files may grow unbounded in long-running or CI usage. Consider using a log rotation tool or periodically cleaning up the log file if this is a concern.
416
344
 
417
345
  **Note:** Logging to `stdout` is not permitted in MCP mode.
418
346
 
@@ -420,7 +348,7 @@ To override the default log file location, specify the `--log-file` argument whe
420
348
 
421
349
  ### CLI Fallback
422
350
 
423
- **Important:** If the MCP server doesn't work, you can use the CLI directly with the `-fJ` flag.
351
+ **Important:** If the MCP server doesn't work, you can use the CLI directly with the `-fJ` (output in JSON format) flag.
424
352
 
425
353
  See the **[CLI Fallback for LLMs Guide](CLI_FALLBACK_FOR_LLMS.md)** for:
426
354
  - Complete command reference and MCP tool mappings
@@ -432,17 +360,11 @@ See the **[CLI Fallback for LLMs Guide](CLI_FALLBACK_FOR_LLMS.md)** for:
432
360
 
433
361
  **Server Won't Start**
434
362
  ```sh
435
- which cov-loupe # Verify executable exists
436
- ruby -v # Check Ruby >= 3.2
437
- cov-loupe version # Test basic functionality
363
+ which cov-loupe # Verify executable exists
364
+ ruby -v # Check Ruby >= 3.2
365
+ cov-loupe version # Test basic functionality
438
366
  ```
439
367
 
440
- **Path Issues with Version Managers**
441
- ```sh
442
- which cov-loupe # Use this absolute path in MCP config
443
- # RVM: Create wrapper for stability
444
- rvm wrapper ruby-3.3.8 cov-loupe cov-loupe
445
- ```
446
368
 
447
369
  **Tools Not Appearing**
448
370
  1. Restart AI assistant after config changes
@@ -462,26 +384,15 @@ For troubleshooting, add error mode when configuring the server:
462
384
 
463
385
  ```sh
464
386
  # Claude Code
465
- claude mcp add cov-loupe cov-loupe --error-mode debug
387
+ claude mcp add cov-loupe cov-loupe -- -m mcp --error-mode debug
466
388
 
467
389
  # Codex
468
- codex mcp add cov-loupe --command cov-loupe --args "--error-mode" --args "debug"
390
+ codex mcp add cov-loupe cov-loupe -m mcp --error-mode debug
469
391
 
470
392
  # Gemini
471
- gemini mcp add cov-loupe "$(which cov-loupe) --error-mode debug"
393
+ gemini mcp add cov-loupe cov-loupe -- -m mcp --error-mode debug
472
394
  ```
473
395
 
474
- ### Project-Specific vs. Global Configuration
475
-
476
- **Global configuration** (all projects):
477
- - Claude: `claude mcp add --scope user cov-loupe ...`
478
- - Codex: `codex mcp add` (uses global config by default)
479
- - Gemini: `gemini mcp add` (uses global config)
480
-
481
- **Project-specific** (one project):
482
- - Claude: `claude mcp add --scope project cov-loupe ...` (default is `local`)
483
- - Codex/Gemini: Create `.codex/config.toml` or `.gemini/config.toml` in project root (manual)
484
-
485
396
  ## Next Steps
486
397
 
487
398
  - **[CLI Fallback for LLMs](CLI_FALLBACK_FOR_LLMS.md)** - Using CLI when MCP isn't available
data/docs/user/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # User Documentation
2
2
 
3
- Guides for installing, configuring, and using SimpleCov MCP in day-to-day
3
+ [Back to main README](../index.md)
4
+
5
+ Guides for installing, configuring, and using cov-loupe in day-to-day
4
6
  workflows.
5
7
 
6
8
  - [Installation](INSTALLATION.md) – environment setup across platforms
@@ -12,3 +14,5 @@ workflows.
12
14
  - [CLI Fallback for LLMs](CLI_FALLBACK_FOR_LLMS.md) – when MCP isn't available
13
15
  - [Library API](LIBRARY_API.md) – embedding the gem in Ruby code
14
16
  - [Troubleshooting](TROUBLESHOOTING.md) – diagnostics for common issues
17
+ - [Migration Guides](migrations/README.md) – breaking change notes for v2 through v4
18
+ - [Prompt Library](prompts/README.md) – copy/paste instructions for MCP clients when you need coverage analyses fast
@@ -1,13 +1,12 @@
1
1
  # Troubleshooting Guide
2
2
 
3
- [Back to main README](../README.md)
3
+ [Back to main README](../index.md)
4
4
 
5
5
  ## Table of Contents
6
6
 
7
7
  - [Running Issues](#running-issues)
8
8
  - [Coverage Data Issues](#coverage-data-issues)
9
9
  - [MCP Server Issues](#mcp-server-issues)
10
- - [Development Issues](#development-issues)
11
10
  - [Diagnostic Commands](#diagnostic-commands)
12
11
 
13
12
  ## Running Issues
@@ -41,28 +40,48 @@ Codex's macOS sandbox forbids `/bin/ps`; RVM shells need it. When you run `bundl
41
40
  ```
42
41
  2. If your coverage lives elsewhere, point the tools at it:
43
42
  ```bash
44
- cov-loupe --resultset build/coverage/.resultset.json
43
+ cov-loupe -r build/coverage/.resultset.json # -r = --resultset
45
44
  # or
46
- export COV_LOUPE_OPTS="--resultset build/coverage"
45
+ export COV_LOUPE_OPTS="-r build/coverage"
47
46
  ```
48
47
 
49
48
  ### Stale Coverage Errors
50
49
 
51
- `--staleness error` (or `staleness: 'error'`) compares file mtimes and line counts to the coverage snapshot. When it fails:
50
+ `--raise-on-stale` (or `-S`, or `raise_on_stale: true`) compares file mtimes and line counts
51
+ to the coverage snapshot and raises if stale. When it fails:
52
52
 
53
53
  - Regenerate coverage (`bundle exec rspec`) so the snapshot matches current sources.
54
- - Or drop back to warning-only behaviour using `--staleness off` / `staleness: 'off'`.
54
+ - Or drop back to warning-only behaviour using `--no-raise-on-stale` / `raise_on_stale: false`.
55
55
 
56
- If you only care about a subset of files, supply `--tracked-globs` (CLI) or `tracked_globs:` (API) so new files outside those globs do not trigger staleness.
56
+ If you only care about a subset of files, supply `-g` / `--tracked-globs` (CLI) or `tracked_globs:`
57
+ (API) so new files outside those globs do not trigger staleness.
58
+
59
+ **Note:** If you see warnings about missing timestamps, time-based staleness checks may be skipped.
60
+ See [Timestamp Warnings](ADVANCED_USAGE.md#timestamp-warnings) for details.
57
61
 
58
62
  ### "No coverage data found for file"
59
63
 
60
- The model looks up files by absolute path, then cwd-relative path, then basename. If you still hit this error:
64
+ The model looks up files by absolute path, then by relative path (stripping the project root). If you still hit this error:
61
65
 
62
66
  1. Verify the file is listed in the coverage table (`cov-loupe list | grep model.rb`).
63
- 2. Use the exact project-relative path that SimpleCov recorded (case-sensitive, no symlinks).
67
+ 2. Use the exact project-relative path that SimpleCov recorded (no symlinks; case-sensitivity
68
+ depends on your volume - see note below).
64
69
  3. If the file truly never executes under tests, add coverage or exclude it from your workflow.
65
70
 
71
+ **Note on case-sensitivity:** `cov-loupe` auto-detects volume case-sensitivity at startup.
72
+ On case-insensitive volumes (most macOS/Windows), `lib/Foo.rb` and `lib/foo.rb` are treated
73
+ as the same file. On case-sensitive volumes (most Linux, some macOS), they are different files.
74
+
75
+ ### SimpleCov path consistency (merged resultsets)
76
+
77
+ When SimpleCov merges resultsets from multiple suites or environments, it can record the same file
78
+ under different path forms (for example, absolute vs relative, or with different roots). This is a
79
+ SimpleCov output issue, not a cov-loupe issue. Downstream tools will normalize paths and may treat
80
+ one entry as overriding another if two keys map to the same file.
81
+
82
+ **Recommendation:** Keep `SimpleCov.root` consistent across suites and avoid manual path rewriting
83
+ when merging resultsets.
84
+
66
85
  ## MCP Server Issues
67
86
 
68
87
  ### MCP Integration Not Working
@@ -89,6 +108,7 @@ The model looks up files by absolute path, then cwd-relative path, then basename
89
108
  ```bash
90
109
  claude mcp list # For Claude Code
91
110
  codex mcp list # For Codex
111
+ gemini mcp list # For Gemini
92
112
  tail -f cov_loupe.log # Check logs
93
113
  ```
94
114
 
@@ -107,35 +127,37 @@ The model looks up files by absolute path, then cwd-relative path, then basename
107
127
  If MCP still isn't working, you can use the CLI with `-fJ` flag instead.
108
128
  See **[CLI Fallback for LLMs](CLI_FALLBACK_FOR_LLMS.md)** for complete guidance.
109
129
 
130
+ 7. **Check for Codex environment variable issues:**
131
+ If you are using Codex and the server fails to start due to missing gems, you need to manually add
132
+ `env_vars = ["GEM_HOME", "GEM_PATH"]` to your `~/.codex/config.toml`.
133
+ See the [MCP Integration - Codex section](MCP_INTEGRATION.md#codex) for complete setup instructions.
134
+
110
135
  ### Path Issues with Version Managers
111
136
 
112
- **Symptom:** Works in terminal but not in MCP client.
137
+ **Symptom:** `cov-loupe` works in terminal but not in MCP client.
113
138
 
114
139
  **Cause:** MCP client doesn't have your shell environment (PATH, RVM, etc.).
115
140
 
116
141
  **Solution:** Use absolute paths in MCP configuration:
117
142
 
118
143
  ```bash
119
- # For rbenv/asdf
144
+ # For rbenv/asdf - get the full absolute path
120
145
  which cov-loupe
121
- # Use this path in MCP config
146
+ # Example output: /home/username/.rbenv/shims/cov-loupe
147
+ # Use this exact path in your MCP config
122
148
 
123
- # For RVM, create wrapper
149
+ # For RVM you may need to create a wrapper and specify its absolute path
150
+ # (Replace ruby-3.3.8 with your rvm Ruby label)
124
151
  rvm wrapper ruby-3.3.8 cov-loupe cov-loupe
125
- # Use: ~/.rvm/wrappers/ruby-3.3.8/cov-loupe
126
- ```
127
-
128
- ## Development Issues
129
-
130
- ### Test Suite Failures
131
152
 
132
- **Symptom:** `bundle exec rspec` fails with coverage errors.
153
+ # Get the full path (expands ~ to your home directory)
154
+ realpath ~/.rvm/wrappers/ruby-3.3.8/cov-loupe
155
+ # Example output: /home/username/.rvm/wrappers/ruby-3.3.8/cov-loupe
133
156
 
134
- **Common causes:**
135
-
136
- 1. **Stale coverage data** - Delete `coverage/` directory and re-run
137
- 2. **SimpleCov not loaded** - Check `spec/spec_helper.rb` requires SimpleCov
138
- 3. **Wrong Ruby version** - Verify Ruby >= 3.2
157
+ # Use the FULL path in MCP config (NOT the ~ version):
158
+ # Good: /home/username/.rvm/wrappers/ruby-3.3.8/cov-loupe
159
+ # Bad: ~/.rvm/wrappers/ruby-3.3.8/cov-loupe (~ may not expand)
160
+ ```
139
161
 
140
162
  ## Diagnostic Commands
141
163
 
@@ -178,8 +200,8 @@ If the above doesn't solve your problem:
178
200
  # MCP server logs
179
201
  tail -50 cov_loupe.log
180
202
 
181
- # Or specify custom log location
182
- cov-loupe --log-file /tmp/debug.log summary lib/cov_loupe/cli.rb
203
+ # Or specify custom log location (--log-file or -l)
204
+ cov-loupe -l /tmp/debug.log summary lib/cov_loupe/cli.rb
183
205
  ```
184
206
 
185
207
  3. **Search existing issues:**