simplecov-mcp 0.3.0 → 1.0.0

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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/README.md +173 -356
  4. data/docs/ADVANCED_USAGE.md +967 -0
  5. data/docs/ARCHITECTURE.md +79 -0
  6. data/docs/BRANCH_ONLY_COVERAGE.md +81 -0
  7. data/docs/CLI_USAGE.md +637 -0
  8. data/docs/DEVELOPMENT.md +82 -0
  9. data/docs/ERROR_HANDLING.md +93 -0
  10. data/docs/EXAMPLES.md +430 -0
  11. data/docs/INSTALLATION.md +352 -0
  12. data/docs/LIBRARY_API.md +635 -0
  13. data/docs/MCP_INTEGRATION.md +488 -0
  14. data/docs/TROUBLESHOOTING.md +276 -0
  15. data/docs/arch-decisions/001-x-arch-decision.md +93 -0
  16. data/docs/arch-decisions/002-x-arch-decision.md +157 -0
  17. data/docs/arch-decisions/003-x-arch-decision.md +163 -0
  18. data/docs/arch-decisions/004-x-arch-decision.md +199 -0
  19. data/docs/arch-decisions/005-x-arch-decision.md +187 -0
  20. data/docs/arch-decisions/README.md +60 -0
  21. data/docs/presentations/simplecov-mcp-presentation.md +249 -0
  22. data/exe/simplecov-mcp +4 -4
  23. data/lib/simplecov_mcp/app_context.rb +26 -0
  24. data/lib/simplecov_mcp/base_tool.rb +74 -0
  25. data/lib/simplecov_mcp/cli.rb +234 -0
  26. data/lib/simplecov_mcp/cli_config.rb +56 -0
  27. data/lib/simplecov_mcp/commands/base_command.rb +78 -0
  28. data/lib/simplecov_mcp/commands/command_factory.rb +39 -0
  29. data/lib/simplecov_mcp/commands/detailed_command.rb +24 -0
  30. data/lib/simplecov_mcp/commands/list_command.rb +13 -0
  31. data/lib/simplecov_mcp/commands/raw_command.rb +22 -0
  32. data/lib/simplecov_mcp/commands/summary_command.rb +24 -0
  33. data/lib/simplecov_mcp/commands/uncovered_command.rb +26 -0
  34. data/lib/simplecov_mcp/commands/version_command.rb +18 -0
  35. data/lib/simplecov_mcp/constants.rb +22 -0
  36. data/lib/simplecov_mcp/error_handler.rb +124 -0
  37. data/lib/simplecov_mcp/error_handler_factory.rb +31 -0
  38. data/lib/simplecov_mcp/errors.rb +179 -0
  39. data/lib/simplecov_mcp/formatters/source_formatter.rb +148 -0
  40. data/lib/simplecov_mcp/mcp_server.rb +40 -0
  41. data/lib/simplecov_mcp/mode_detector.rb +55 -0
  42. data/lib/simplecov_mcp/model.rb +300 -0
  43. data/lib/simplecov_mcp/option_normalizers.rb +92 -0
  44. data/lib/simplecov_mcp/option_parser_builder.rb +134 -0
  45. data/lib/simplecov_mcp/option_parsers/env_options_parser.rb +50 -0
  46. data/lib/simplecov_mcp/option_parsers/error_helper.rb +109 -0
  47. data/lib/simplecov_mcp/path_relativizer.rb +61 -0
  48. data/lib/simplecov_mcp/presenters/base_coverage_presenter.rb +44 -0
  49. data/lib/simplecov_mcp/presenters/coverage_detailed_presenter.rb +16 -0
  50. data/lib/simplecov_mcp/presenters/coverage_raw_presenter.rb +16 -0
  51. data/lib/simplecov_mcp/presenters/coverage_summary_presenter.rb +16 -0
  52. data/lib/simplecov_mcp/presenters/coverage_uncovered_presenter.rb +16 -0
  53. data/lib/simplecov_mcp/presenters/project_coverage_presenter.rb +52 -0
  54. data/lib/simplecov_mcp/resolvers/coverage_line_resolver.rb +126 -0
  55. data/lib/simplecov_mcp/resolvers/resolver_factory.rb +28 -0
  56. data/lib/simplecov_mcp/resolvers/resultset_path_resolver.rb +78 -0
  57. data/lib/simplecov_mcp/resultset_loader.rb +136 -0
  58. data/lib/simplecov_mcp/staleness_checker.rb +243 -0
  59. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/all_files_coverage_tool.rb +31 -13
  60. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/coverage_detailed_tool.rb +7 -7
  61. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/coverage_raw_tool.rb +7 -7
  62. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/coverage_summary_tool.rb +7 -7
  63. data/lib/simplecov_mcp/tools/coverage_table_tool.rb +90 -0
  64. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/help_tool.rb +13 -4
  65. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/uncovered_lines_tool.rb +7 -7
  66. data/lib/{simple_cov_mcp → simplecov_mcp}/tools/version_tool.rb +11 -3
  67. data/lib/simplecov_mcp/util.rb +82 -0
  68. data/lib/{simple_cov_mcp → simplecov_mcp}/version.rb +1 -1
  69. data/lib/simplecov_mcp.rb +144 -2
  70. data/spec/MCP_INTEGRATION_TESTS_README.md +111 -0
  71. data/spec/TIMESTAMPS.md +48 -0
  72. data/spec/all_files_coverage_tool_spec.rb +29 -25
  73. data/spec/base_tool_spec.rb +11 -10
  74. data/spec/cli/show_default_report_spec.rb +33 -0
  75. data/spec/cli_config_spec.rb +137 -0
  76. data/spec/cli_enumerated_options_spec.rb +68 -0
  77. data/spec/cli_error_spec.rb +105 -47
  78. data/spec/cli_source_spec.rb +82 -23
  79. data/spec/cli_spec.rb +140 -5
  80. data/spec/cli_success_predicate_spec.rb +141 -0
  81. data/spec/cli_table_spec.rb +1 -1
  82. data/spec/cli_usage_spec.rb +10 -26
  83. data/spec/commands/base_command_spec.rb +187 -0
  84. data/spec/commands/command_factory_spec.rb +72 -0
  85. data/spec/commands/detailed_command_spec.rb +48 -0
  86. data/spec/commands/raw_command_spec.rb +46 -0
  87. data/spec/commands/summary_command_spec.rb +47 -0
  88. data/spec/commands/uncovered_command_spec.rb +49 -0
  89. data/spec/constants_spec.rb +61 -0
  90. data/spec/coverage_table_tool_spec.rb +17 -33
  91. data/spec/error_handler_spec.rb +22 -13
  92. data/spec/error_mode_spec.rb +143 -0
  93. data/spec/errors_edge_cases_spec.rb +239 -0
  94. data/spec/errors_stale_spec.rb +2 -2
  95. data/spec/file_based_mcp_tools_spec.rb +99 -0
  96. data/spec/fixtures/project1/lib/bar.rb +0 -1
  97. data/spec/fixtures/project1/lib/foo.rb +0 -1
  98. data/spec/help_tool_spec.rb +11 -17
  99. data/spec/integration_spec.rb +845 -0
  100. data/spec/logging_fallback_spec.rb +128 -0
  101. data/spec/mcp_logging_spec.rb +44 -0
  102. data/spec/mcp_server_integration_spec.rb +23 -0
  103. data/spec/mcp_server_spec.rb +15 -4
  104. data/spec/mode_detector_spec.rb +148 -0
  105. data/spec/model_error_handling_spec.rb +210 -0
  106. data/spec/model_staleness_spec.rb +40 -10
  107. data/spec/option_normalizers_spec.rb +204 -0
  108. data/spec/option_parsers/env_options_parser_spec.rb +233 -0
  109. data/spec/option_parsers/error_helper_spec.rb +222 -0
  110. data/spec/path_relativizer_spec.rb +83 -0
  111. data/spec/presenters/coverage_detailed_presenter_spec.rb +19 -0
  112. data/spec/presenters/coverage_raw_presenter_spec.rb +15 -0
  113. data/spec/presenters/coverage_summary_presenter_spec.rb +15 -0
  114. data/spec/presenters/coverage_uncovered_presenter_spec.rb +16 -0
  115. data/spec/presenters/project_coverage_presenter_spec.rb +86 -0
  116. data/spec/resolvers/coverage_line_resolver_spec.rb +57 -0
  117. data/spec/resolvers/resolver_factory_spec.rb +61 -0
  118. data/spec/resolvers/resultset_path_resolver_spec.rb +55 -0
  119. data/spec/resultset_loader_spec.rb +167 -0
  120. data/spec/shared_examples/README.md +115 -0
  121. data/spec/shared_examples/coverage_presenter_examples.rb +66 -0
  122. data/spec/shared_examples/file_based_mcp_tools.rb +174 -0
  123. data/spec/shared_examples/mcp_tool_text_json_response.rb +16 -0
  124. data/spec/simple_cov_mcp_module_spec.rb +16 -0
  125. data/spec/simplecov_mcp_model_spec.rb +340 -9
  126. data/spec/simplecov_mcp_opts_spec.rb +182 -0
  127. data/spec/spec_helper.rb +147 -4
  128. data/spec/staleness_checker_spec.rb +373 -0
  129. data/spec/staleness_more_spec.rb +16 -13
  130. data/spec/support/mcp_runner.rb +64 -0
  131. data/spec/tools_error_handling_spec.rb +144 -0
  132. data/spec/util_spec.rb +109 -34
  133. data/spec/version_spec.rb +117 -9
  134. data/spec/version_tool_spec.rb +131 -10
  135. metadata +120 -63
  136. data/lib/simple_cov/mcp.rb +0 -9
  137. data/lib/simple_cov_mcp/base_tool.rb +0 -70
  138. data/lib/simple_cov_mcp/cli.rb +0 -390
  139. data/lib/simple_cov_mcp/error_handler.rb +0 -131
  140. data/lib/simple_cov_mcp/error_handler_factory.rb +0 -38
  141. data/lib/simple_cov_mcp/errors.rb +0 -176
  142. data/lib/simple_cov_mcp/mcp_server.rb +0 -30
  143. data/lib/simple_cov_mcp/model.rb +0 -104
  144. data/lib/simple_cov_mcp/staleness_checker.rb +0 -125
  145. data/lib/simple_cov_mcp/tools/coverage_table_tool.rb +0 -61
  146. data/lib/simple_cov_mcp/util.rb +0 -122
  147. data/lib/simple_cov_mcp.rb +0 -102
  148. data/spec/coverage_detailed_tool_spec.rb +0 -36
  149. data/spec/coverage_raw_tool_spec.rb +0 -32
  150. data/spec/coverage_summary_tool_spec.rb +0 -39
  151. data/spec/legacy_shim_spec.rb +0 -13
  152. data/spec/uncovered_lines_tool_spec.rb +0 -33
data/docs/CLI_USAGE.md ADDED
@@ -0,0 +1,637 @@
1
+ # CLI Usage Guide
2
+
3
+ Complete reference for using simplecov-mcp from the command line.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Quick Reference](#quick-reference)
8
+ - [Subcommands](#subcommands)
9
+ - [Global Options](#global-options)
10
+ - [Output Formats](#output-formats)
11
+ - [Environment Variables](#environment-variables)
12
+ - [Examples](#examples)
13
+
14
+ ## Quick Reference
15
+
16
+ ```sh
17
+ # Show coverage table for all files
18
+ simplecov-mcp
19
+ simplecov-mcp list
20
+
21
+ # Check specific file
22
+ simplecov-mcp summary lib/simplecov_mcp/model.rb
23
+
24
+ # Find uncovered lines
25
+ simplecov-mcp uncovered lib/simplecov_mcp/model.rb
26
+
27
+ # Get detailed per-line coverage
28
+ simplecov-mcp detailed lib/simplecov_mcp/model.rb
29
+
30
+ # Get raw SimpleCov data
31
+ simplecov-mcp raw lib/simplecov_mcp/model.rb
32
+
33
+ # Show version
34
+ simplecov-mcp version
35
+
36
+ # Get help
37
+ simplecov-mcp --help
38
+ ```
39
+
40
+ ## Subcommands
41
+
42
+ ### `list`
43
+
44
+ Show coverage summary for all files (default subcommand).
45
+
46
+ ```sh
47
+ simplecov-mcp list
48
+ simplecov-mcp list --sort-order descending
49
+ simplecov-mcp list --json
50
+ ```
51
+
52
+ **Options:**
53
+ - `--sort-order` - Sort by coverage percentage (ascending or descending)
54
+ - `--tracked-globs` - Filter to specific file patterns
55
+ - `--stale` - Check for stale coverage
56
+ - `--json` - Output as JSON
57
+
58
+ **Output (table format):**
59
+ ```
60
+ ┌──────────────────────────────────────────────────────────┬──────────┬──────────┬────────┬───────┐
61
+ │ File │ % │ Covered │ Total │ Stale │
62
+ ├──────────────────────────────────────────────────────────┼──────────┼──────────┼────────┼───────┤
63
+ │ lib/simplecov_mcp/tools/coverage_summary_tool.rb │ 85.71 │ 12 │ 14 │ │
64
+ │ lib/services/auth.rb │ 92.31 │ 12 │ 13 │ ! │
65
+ │ lib/controllers/api.rb │ 100.00 │ 8 │ 8 │ │
66
+ └──────────────────────────────────────────────────────────┴──────────┴──────────┴────────┴───────┘
67
+ Files: total 3, ok 2, stale 1
68
+ ```
69
+
70
+ ### `summary <path>`
71
+
72
+ Show covered/total/percentage for a specific file.
73
+
74
+ ```sh
75
+ simplecov-mcp summary lib/simplecov_mcp/model.rb
76
+ simplecov-mcp summary lib/simplecov_mcp/model.rb --json
77
+ simplecov-mcp summary lib/simplecov_mcp/model.rb --source
78
+ ```
79
+
80
+ **Arguments:**
81
+ - `<path>` - File path (relative to project root or absolute)
82
+
83
+ **Options:**
84
+ - `--json` - Output as JSON
85
+ - `--source[=MODE]` - Include source code (full or uncovered)
86
+
87
+ **Output (default format):**
88
+ ```
89
+ 85.71% 12/14 lib/simplecov_mcp/model.rb
90
+ ```
91
+
92
+ **Output (JSON format):**
93
+ ```json
94
+ {
95
+ "file": "lib/simplecov_mcp/model.rb",
96
+ "summary": {
97
+ "covered": 12,
98
+ "total": 14,
99
+ "pct": 85.71
100
+ },
101
+ "stale": false
102
+ }
103
+ ```
104
+
105
+ ### `uncovered <path>`
106
+
107
+ Show uncovered line numbers for a specific file.
108
+
109
+ ```sh
110
+ simplecov-mcp uncovered lib/simplecov_mcp/model.rb
111
+ simplecov-mcp uncovered lib/simplecov_mcp/model.rb --source=uncovered
112
+ simplecov-mcp uncovered lib/simplecov_mcp/model.rb --source=uncovered --source-context 3
113
+ ```
114
+
115
+ **Arguments:**
116
+ - `<path>` - File path (relative to project root or absolute)
117
+
118
+ **Options:**
119
+ - `--source=uncovered` - Show uncovered lines with context
120
+ - `--source-context N` - Lines of context around uncovered lines (default: 2)
121
+ - `--color` / `--no-color` - Enable/disable syntax coloring
122
+ - `--json` - Output as JSON
123
+
124
+ **Output (default format):**
125
+ ```
126
+ File: lib/simplecov_mcp/model.rb
127
+ Uncovered lines: 5, 9, 12, 18, 23
128
+ Summary: 85.71% 12/14
129
+ ```
130
+
131
+ **Output (with source):**
132
+ ```
133
+ File: lib/simplecov_mcp/model.rb
134
+ Uncovered lines: 5, 9, 12
135
+ Summary: 85.71% 12/14
136
+
137
+ Line | Source
138
+ ------+-----------------------------------------------------------
139
+ 3 ✓ | def initialize(name)
140
+ 4 ✓ | @name = name
141
+ 5 · | @validated = false # Uncovered
142
+ 6 ✓ | end
143
+ 7 |
144
+ 8 ✓ | def validate
145
+ 9 · | return if @validated # Uncovered
146
+ 10 ✓ | # ...
147
+ ```
148
+
149
+ **Legend:**
150
+ - `✓` - Line is covered
151
+ - `·` - Line is not covered
152
+ - ` ` - Line is not executable (comments, blank lines)
153
+
154
+ ### `detailed <path>`
155
+
156
+ Show per-line coverage with hit counts.
157
+
158
+ ```sh
159
+ simplecov-mcp detailed lib/simplecov_mcp/model.rb
160
+ simplecov-mcp detailed lib/simplecov_mcp/model.rb --json
161
+ simplecov-mcp detailed lib/simplecov_mcp/model.rb --source
162
+ ```
163
+
164
+ **Arguments:**
165
+ - `<path>` - File path (relative to project root or absolute)
166
+
167
+ **Options:**
168
+ - `--json` - Output as JSON
169
+ - `--source` - Include source code
170
+
171
+ **Output (default format):**
172
+ ```
173
+ File: lib/simplecov_mcp/model.rb
174
+ Line Hits Covered
175
+ ----- ---- -------
176
+ 1 1 yes
177
+ 2 0 no
178
+ 3 1 yes
179
+ 4 5 yes
180
+ ```
181
+
182
+ **Output (JSON format):**
183
+ ```json
184
+ {
185
+ "file": "lib/simplecov_mcp/model.rb",
186
+ "lines": [
187
+ { "line": 1, "hits": 1, "covered": true },
188
+ { "line": 2, "hits": 0, "covered": false },
189
+ { "line": 4, "hits": 5, "covered": true }
190
+ ],
191
+ "summary": {
192
+ "covered": 2,
193
+ "total": 3,
194
+ "pct": 66.67
195
+ },
196
+ "stale": false
197
+ }
198
+ ```
199
+
200
+ ### `raw <path>`
201
+
202
+ Show the raw SimpleCov lines array.
203
+
204
+ ```sh
205
+ simplecov-mcp raw lib/simplecov_mcp/model.rb
206
+ simplecov-mcp raw lib/simplecov_mcp/model.rb --json
207
+ ```
208
+
209
+ **Arguments:**
210
+ - `<path>` - File path (relative to project root or absolute)
211
+
212
+ **Output (default format):**
213
+ ```
214
+ File: lib/simplecov_mcp/model.rb
215
+ [1, 0, nil, 5, 2, nil, 1]
216
+ ```
217
+
218
+ **Output (JSON format):**
219
+ ```json
220
+ {
221
+ "file": "lib/simplecov_mcp/model.rb",
222
+ "lines": [1, 0, null, 5, 2, null, 1],
223
+ "stale": false
224
+ }
225
+ ```
226
+
227
+ **Array explanation:**
228
+ - Integer (e.g., `1`, `5`) - Number of times line was executed
229
+ - `0` - Line is executable but was not executed
230
+ - `null` - Line is not executable (comment, blank line)
231
+
232
+ ### `version`
233
+
234
+ Show version information.
235
+
236
+ ```sh
237
+ simplecov-mcp version
238
+ simplecov-mcp version --json
239
+ ```
240
+
241
+ **Output:**
242
+ ```
243
+ SimpleCovMcp version 1.0.0
244
+ ```
245
+
246
+ ## Global Options
247
+
248
+ These options work with all subcommands.
249
+
250
+ ### `-r, --resultset PATH`
251
+
252
+ Path to the `.resultset.json` file or a directory containing it.
253
+
254
+ For a detailed explanation of how to configure the resultset location, including the default search path, environment variables, and MCP configuration, see the [Configuring the Resultset](../README.md#configuring-the-resultset) section in the main README.
255
+
256
+ ### `-R, --root PATH`
257
+
258
+ Project root directory (default: current directory).
259
+
260
+ ```sh
261
+ simplecov-mcp --root /path/to/project
262
+ ```
263
+
264
+ ### `-j, --json`
265
+
266
+ Output as JSON instead of human-readable format.
267
+
268
+ ```sh
269
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb --json
270
+ ```
271
+
272
+ Useful for:
273
+ - Parsing in scripts
274
+ - Integration with other tools
275
+ - Machine consumption
276
+
277
+ ### `-o, --sort-order ORDER`
278
+
279
+ Sort order for `list` subcommand.
280
+
281
+ **Values:**
282
+ - `ascending`, `a` - Lowest coverage first (default)
283
+ - `descending`, `d` - Highest coverage first
284
+
285
+ ```sh
286
+ simplecov-mcp list --sort-order ascending
287
+ simplecov-mcp list --sort-order d # Short form
288
+ ```
289
+
290
+ ### `-s, --source[=MODE]`
291
+
292
+ Include source code in output.
293
+
294
+ **Modes:**
295
+ - `full`, `f` - Show all source lines (default if no MODE given)
296
+ - `uncovered`, `u` - Show only uncovered lines with context
297
+
298
+ ```sh
299
+ # Show full source
300
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb --source
301
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb --source=full
302
+
303
+ # Show only uncovered lines
304
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source=uncovered
305
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb -s=u # Short form
306
+ ```
307
+
308
+ ### `-c, --source-context N`
309
+
310
+ Number of context lines around uncovered code (for `--source=uncovered`).
311
+
312
+ ```sh
313
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source=uncovered --source-context 3
314
+ ```
315
+
316
+ **Default:** 2 lines
317
+
318
+ ### `--color` / `--no-color`
319
+
320
+ Enable or disable ANSI color codes in source output.
321
+
322
+ ```sh
323
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source --color
324
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source --no-color
325
+ ```
326
+
327
+ **Default:** Colors enabled if output is a TTY
328
+
329
+ ### `-S, --stale MODE`
330
+
331
+ Staleness checking mode.
332
+
333
+ **Modes:**
334
+ - `off`, `o` - No staleness checking (default)
335
+ - `error`, `e` - Raise error if coverage is stale
336
+
337
+ ```sh
338
+ # Exit with error if coverage is stale
339
+ simplecov-mcp --stale error
340
+ simplecov-mcp -S e # Short form
341
+ ```
342
+
343
+ **Staleness conditions:**
344
+ - **M** (Missing): Source file no longer exists on disk
345
+ - **T** (Timestamp): Source file modified after coverage was generated
346
+ - **L** (Length): Source file line count differs from coverage data
347
+ - Tracked files missing from coverage (with --tracked-globs)
348
+
349
+ ### `-g, --tracked-globs PATTERNS`
350
+
351
+ Comma-separated glob patterns for files that should be tracked.
352
+
353
+ ```sh
354
+ simplecov-mcp list --tracked-globs "lib/**/*.rb,app/**/*.rb"
355
+ ```
356
+
357
+ Used with `--stale error` to detect new files not yet in coverage.
358
+
359
+ ### `-l, --log-file PATH`
360
+
361
+ Log file location. Use 'stdout' or 'stderr' to log to standard streams.
362
+
363
+ ```sh
364
+ simplecov-mcp --log-file /var/log/simplecov.log
365
+ simplecov-mcp --log-file stdout # Log to standard output
366
+ simplecov-mcp --log-file stderr # Log to standard error
367
+ ```
368
+
369
+ **Default:** `./simplecov_mcp.log`
370
+
371
+ ### `--error-mode MODE`
372
+
373
+ Error handling verbosity.
374
+
375
+ **Modes:**
376
+ - `off` - Silent (no error logging)
377
+ - `on` - Log errors without stack traces (default)
378
+ - `trace`, `t` - Log errors with full stack traces
379
+
380
+ ```sh
381
+ simplecov-mcp --error-mode trace summary lib/simplecov_mcp/cli.rb
382
+ ```
383
+
384
+ ### `--force-cli`
385
+
386
+ Force CLI mode even when stdin is piped or when the process is running in a non-interactive shell (CI, Codex, etc.). Without it, the executable may fall back to MCP server mode.
387
+
388
+ ```sh
389
+ simplecov-mcp --force-cli list
390
+ ```
391
+
392
+ ### `--success-predicate FILE`
393
+
394
+ Run a custom success predicate for CI/CD coverage enforcement.
395
+
396
+ > **⚠️ SECURITY WARNING**
397
+ >
398
+ > Success predicates execute as **arbitrary Ruby code with full system privileges**. They have unrestricted access
399
+ > to file system, network, system commands, and environment variables.
400
+ >
401
+ > **Only use predicate files from trusted sources.**
402
+ > Review predicates before use, especially in CI/CD environments.
403
+
404
+ The predicate file must return a callable (lambda, proc, or object with `#call` method) that receives a `CoverageModel` and returns truthy (success) or falsy (failure).
405
+
406
+ **Exit codes:**
407
+ - `0` - Predicate returned truthy (pass)
408
+ - `1` - Predicate returned falsy (fail)
409
+ - `2` - Predicate raised an error
410
+
411
+ **Example usage:**
412
+ ```sh
413
+ # Use example predicate
414
+ simplecov-mcp --success-predicate examples/success_predicates/all_files_above_threshold.rb
415
+
416
+ # In CI/CD
417
+ bundle exec simplecov-mcp --success-predicate coverage_policy.rb
418
+ ```
419
+
420
+ **Example predicate file:**
421
+ ```ruby
422
+ # coverage_policy.rb
423
+ ->(model) do
424
+ model.all_files.all? { |f| f['percentage'] >= 80 }
425
+ end
426
+ ```
427
+
428
+ See [examples/success_predicates/](../../examples/success_predicates/) for more examples.
429
+
430
+ ## Output Formats
431
+
432
+ ### Table Format
433
+
434
+ Default for `list` subcommand. Uses Unicode box-drawing characters.
435
+
436
+ ```
437
+ ┌──────────────────────────┬──────────┬──────────┬────────┬───────┐
438
+ │ File │ % │ Covered │ Total │ Stale │
439
+ ├──────────────────────────┼──────────┼──────────┼────────┼───────┤
440
+ │ lib/simple_cov_mcp.rb │ 85.71 │ 12 │ 14 │ │
441
+ └──────────────────────────┴──────────┴──────────┴────────┴───────┘
442
+ ```
443
+
444
+ ### JSON Format
445
+
446
+ Machine-readable output. Paths are relative to project root.
447
+
448
+ ```json
449
+ {
450
+ "file": "lib/simplecov_mcp/util.rb",
451
+ "summary": {
452
+ "covered": 12,
453
+ "total": 14,
454
+ "pct": 85.71
455
+ },
456
+ "stale": false
457
+ }
458
+ ```
459
+
460
+ **Staleness values:**
461
+ - `false` - Coverage data is current
462
+ - `"M"` - File missing (no longer exists on disk)
463
+ - `"T"` - Timestamp mismatch (file modified after coverage)
464
+ - `"L"` - Length mismatch (line count differs)
465
+
466
+ ### Source Display
467
+
468
+ With `--source` flag, shows annotated source code:
469
+
470
+ ```
471
+ Line | Source
472
+ ------+-----------------------------------------------------------
473
+ 1 ✓ | class User
474
+ 2 · | def initialize # Not covered
475
+ 3 ✓ | # ...
476
+ ```
477
+
478
+ ## Environment Variables
479
+
480
+ ### `SIMPLECOV_MCP_OPTS`
481
+
482
+ Default command-line options applied to all invocations.
483
+
484
+ **Format:** Shell-style string containing any valid CLI options
485
+
486
+ ```sh
487
+ export SIMPLECOV_MCP_OPTS="--resultset coverage --json"
488
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb # Automatically uses options above
489
+ ```
490
+
491
+ **Precedence:** Command-line arguments override environment options
492
+
493
+ ```sh
494
+ # Environment sets --json, but --no-json on command line wins
495
+ export SIMPLECOV_MCP_OPTS="--json"
496
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb # Uses JSON (from env)
497
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb --json # Explicit, same result
498
+ ```
499
+
500
+ **Examples:**
501
+ ```sh
502
+ # Default resultset location
503
+ export SIMPLECOV_MCP_OPTS="--resultset build/coverage"
504
+
505
+ # Enable detailed error logging
506
+ export SIMPLECOV_MCP_OPTS="--error-mode trace"
507
+
508
+ # Paths with spaces
509
+ export SIMPLECOV_MCP_OPTS='--resultset "/path with spaces/coverage"'
510
+
511
+ # Multiple options
512
+ export SIMPLECOV_MCP_OPTS="--resultset coverage --stale error --json"
513
+ ```
514
+
515
+
516
+
517
+ ## Examples
518
+
519
+ ### Basic Coverage Check
520
+
521
+ ```sh
522
+ # Show all files sorted by lowest coverage first
523
+ simplecov-mcp
524
+
525
+ # Find the 5 files with worst coverage
526
+ simplecov-mcp list | head -10
527
+ ```
528
+
529
+ ### Detailed File Investigation
530
+
531
+ ```sh
532
+ # Check a specific file
533
+ simplecov-mcp summary lib/simplecov_mcp/tools/coverage_summary_tool.rb
534
+
535
+ # See which lines aren't covered
536
+ simplecov-mcp uncovered lib/simplecov_mcp/tools/coverage_summary_tool.rb
537
+
538
+ # View uncovered code in context
539
+ simplecov-mcp uncovered lib/simplecov_mcp/tools/coverage_summary_tool.rb --source=uncovered --source-context 3
540
+
541
+ # Get detailed hit counts
542
+ simplecov-mcp detailed lib/simplecov_mcp/tools/coverage_summary_tool.rb
543
+ ```
544
+
545
+ ### JSON Output for Scripts
546
+
547
+ ```sh
548
+ # Get JSON for parsing
549
+ simplecov-mcp list --json > coverage.json
550
+
551
+ # Extract files below threshold
552
+ simplecov-mcp list --json | jq '.files[] | select(.percentage < 80)'
553
+
554
+ # Count files below 80% coverage
555
+ simplecov-mcp list --json | jq '[.files[] | select(.percentage < 80)] | length'
556
+ ```
557
+
558
+ ### Filtering and Sorting
559
+
560
+ ```sh
561
+ # Show only lib/ files
562
+ simplecov-mcp list --tracked-globs "lib/**/*.rb"
563
+
564
+ # Show files sorted by highest coverage
565
+ simplecov-mcp list --sort-order descending
566
+
567
+ # Check specific directory
568
+ simplecov-mcp list --tracked-globs "lib/simplecov_mcp/tools/**/*.rb"
569
+ ```
570
+
571
+
572
+
573
+ ### Staleness Checking
574
+
575
+ ```sh
576
+ # Check if coverage is stale (for CI/CD)
577
+ simplecov-mcp --stale error
578
+
579
+ # Check with specific file patterns
580
+ simplecov-mcp list --stale error --tracked-globs "lib/**/*.rb,app/**/*.rb"
581
+
582
+ # See which files are stale (don't error)
583
+ simplecov-mcp list # Stale files marked with !
584
+ ```
585
+
586
+ ### Source Code Display
587
+
588
+ ```sh
589
+ # Show full source with coverage markers
590
+ simplecov-mcp summary lib/simplecov_mcp/cli.rb --source
591
+
592
+ # Show only uncovered lines with context
593
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source=uncovered
594
+
595
+ # More context around uncovered code
596
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source=uncovered --source-context 5
597
+
598
+ # Without colors (for logging)
599
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source --no-color
600
+ ```
601
+
602
+ ### CI/CD Integration
603
+
604
+ ```sh
605
+ # Fail build if coverage is stale
606
+ simplecov-mcp --stale error || exit 1
607
+
608
+ # Generate JSON report for artifact
609
+ simplecov-mcp list --json > artifacts/coverage-report.json
610
+
611
+ # Check specific directory in monorepo
612
+ simplecov-mcp --root services/api --resultset services/api/coverage
613
+ ```
614
+
615
+ ### Debugging
616
+
617
+ ```sh
618
+ # Verbose error output
619
+ simplecov-mcp --error-mode trace summary lib/simplecov_mcp/cli.rb
620
+
621
+ # Custom log file
622
+ simplecov-mcp --log-file /tmp/simplecov-debug.log summary lib/simplecov_mcp/cli.rb
623
+
624
+ # Check what resultset is being used
625
+ simplecov-mcp --error-mode trace 2>&1 | grep resultset
626
+ ```
627
+
628
+ ## Exit Codes
629
+
630
+ - `0` - Success
631
+ - `1` - Error (file not found, coverage data missing, stale coverage with `--stale error`, etc.)
632
+
633
+ ## Next Steps
634
+
635
+ - **[Library API](LIBRARY_API.md)** - Use in Ruby code
636
+ - **[Examples](EXAMPLES.md)** - More usage examples and recipes
637
+ - **[Troubleshooting](TROUBLESHOOTING.md)** - Common issues and solutions
@@ -0,0 +1,82 @@
1
+ # Development Guide
2
+
3
+ > **Note:** Commands like `simplecov-mcp` assume the gem is installed globally. If not, substitute `bundle exec exe/simplecov-mcp`.
4
+
5
+ ## Setup
6
+
7
+ ```sh
8
+ git clone https://github.com/keithrbennett/simplecov-mcp.git
9
+ cd simplecov-mcp
10
+ bundle install
11
+ gem build simplecov-mcp.gemspec && gem install simplecov-mcp-*.gem # optional
12
+ simplecov-mcp version # verify it works
13
+ ```
14
+
15
+ ## Running Tests
16
+
17
+ ```sh
18
+ bundle exec rspec
19
+ ```
20
+
21
+ ## Project-Specific Patterns
22
+
23
+ **All Ruby files start with:**
24
+ ```ruby
25
+ # frozen_string_literal: true
26
+ ```
27
+
28
+ **Error handling uses custom exceptions from `errors.rb`:**
29
+ ```ruby
30
+ rescue Errno::ENOENT => e
31
+ raise FileError.new("Coverage data not found: #{e.message}")
32
+ rescue JSON::ParserError => e
33
+ raise CoverageDataError.new("Invalid coverage format: #{e.message}")
34
+ ```
35
+
36
+ **MCP tools extend `BaseTool` and follow this pattern:**
37
+ ```ruby
38
+ module SimpleCovMcp::Tools
39
+ class MyTool < BaseTool
40
+ def self.name = 'my_tool'
41
+ def self.description = 'What this tool does'
42
+
43
+ def self.call(path:, root: '.', resultset: nil, stale: 'off', error_mode: 'on', **)
44
+ model = CoverageModel.new(root: root, resultset: resultset, staleness: stale)
45
+ data = model.my_method_for(path)
46
+ respond_json(model.relativize(data), name: 'my_tool_output.json')
47
+ rescue => e
48
+ handle_mcp_error(e, name, error_mode: error_mode.to_sym)
49
+ end
50
+ end
51
+ end
52
+ ```
53
+
54
+ **Use test fixtures for consistency:**
55
+ ```ruby
56
+ let(:project_root) { (FIXTURES_DIR / 'project1').to_s }
57
+ let(:coverage_dir) { File.join(project_root, 'coverage') }
58
+ ```
59
+
60
+ **MCP tool tests need setup:**
61
+ ```ruby
62
+ let(:server_context) { instance_double('ServerContext').as_null_object }
63
+ before { setup_mcp_response_stub }
64
+ ```
65
+
66
+ ## Adding Features
67
+
68
+ **CLI commands:** Add to `SUBCOMMANDS` in `cli.rb`, implement handler, add tests
69
+
70
+ **MCP tools:** Create `*_tool.rb` in `lib/simplecov_mcp/tools/`, register in `mcp_server.rb`
71
+
72
+ **Coverage features:** Add to `CoverageModel` in `model.rb` or `CovUtil` in `util.rb`
73
+
74
+ ## Troubleshooting
75
+
76
+ **RVM + Codex macOS:** Currently not possible for Codex to run rspec when running on macOS with rvm-managed rubies - see [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
77
+
78
+ **MCP server testing:**
79
+ ```sh
80
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"version_tool","arguments":{}}}' | simplecov-mcp
81
+ ```
82
+