simplecov-mcp 1.0.0 → 2.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 (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +98 -50
  3. data/docs/{ARCHITECTURE.md → dev/ARCHITECTURE.md} +11 -10
  4. data/docs/dev/BRANCH_ONLY_COVERAGE.md +158 -0
  5. data/docs/{DEVELOPMENT.md → dev/DEVELOPMENT.md} +2 -1
  6. data/docs/dev/README.md +10 -0
  7. data/docs/dev/RELEASING.md +146 -0
  8. data/docs/{arch-decisions → dev/arch-decisions}/001-x-arch-decision.md +3 -1
  9. data/docs/{arch-decisions → dev/arch-decisions}/002-x-arch-decision.md +7 -5
  10. data/docs/{arch-decisions → dev/arch-decisions}/003-x-arch-decision.md +2 -0
  11. data/docs/{arch-decisions → dev/arch-decisions}/004-x-arch-decision.md +6 -2
  12. data/docs/{arch-decisions → dev/arch-decisions}/005-x-arch-decision.md +4 -2
  13. data/docs/{arch-decisions → dev/arch-decisions}/README.md +3 -3
  14. data/docs/{presentations → dev/presentations}/simplecov-mcp-presentation.md +28 -22
  15. data/docs/fixtures/demo_project/README.md +9 -0
  16. data/docs/{ADVANCED_USAGE.md → user/ADVANCED_USAGE.md} +129 -319
  17. data/docs/user/CLI_FALLBACK_FOR_LLMS.md +34 -0
  18. data/docs/user/CLI_USAGE.md +750 -0
  19. data/docs/{ERROR_HANDLING.md → user/ERROR_HANDLING.md} +12 -12
  20. data/docs/user/EXAMPLES.md +588 -0
  21. data/docs/user/INSTALLATION.md +130 -0
  22. data/docs/{LIBRARY_API.md → user/LIBRARY_API.md} +90 -32
  23. data/docs/{MCP_INTEGRATION.md → user/MCP_INTEGRATION.md} +36 -34
  24. data/docs/user/README.md +14 -0
  25. data/docs/{TROUBLESHOOTING.md → user/TROUBLESHOOTING.md} +21 -100
  26. data/docs/user/V2-BREAKING-CHANGES.md +472 -0
  27. data/exe/simplecov-mcp +1 -1
  28. data/lib/simplecov_mcp/{cli_config.rb → app_config.rb} +12 -12
  29. data/lib/simplecov_mcp/app_context.rb +1 -1
  30. data/lib/simplecov_mcp/base_tool.rb +66 -38
  31. data/lib/simplecov_mcp/cli.rb +67 -123
  32. data/lib/simplecov_mcp/commands/base_command.rb +16 -27
  33. data/lib/simplecov_mcp/commands/command_factory.rb +8 -2
  34. data/lib/simplecov_mcp/commands/detailed_command.rb +16 -2
  35. data/lib/simplecov_mcp/commands/list_command.rb +1 -1
  36. data/lib/simplecov_mcp/commands/raw_command.rb +18 -2
  37. data/lib/simplecov_mcp/commands/summary_command.rb +20 -3
  38. data/lib/simplecov_mcp/commands/totals_command.rb +53 -0
  39. data/lib/simplecov_mcp/commands/uncovered_command.rb +24 -5
  40. data/lib/simplecov_mcp/commands/validate_command.rb +60 -0
  41. data/lib/simplecov_mcp/commands/version_command.rb +19 -4
  42. data/lib/simplecov_mcp/config_parser.rb +32 -0
  43. data/lib/simplecov_mcp/constants.rb +3 -3
  44. data/lib/simplecov_mcp/coverage_reporter.rb +31 -0
  45. data/lib/simplecov_mcp/error_handler.rb +81 -40
  46. data/lib/simplecov_mcp/error_handler_factory.rb +2 -2
  47. data/lib/simplecov_mcp/errors.rb +32 -20
  48. data/lib/simplecov_mcp/formatters/source_formatter.rb +23 -19
  49. data/lib/simplecov_mcp/formatters.rb +51 -0
  50. data/lib/simplecov_mcp/mcp_server.rb +9 -7
  51. data/lib/simplecov_mcp/mode_detector.rb +6 -5
  52. data/lib/simplecov_mcp/model.rb +122 -83
  53. data/lib/simplecov_mcp/option_normalizers.rb +39 -18
  54. data/lib/simplecov_mcp/option_parser_builder.rb +82 -65
  55. data/lib/simplecov_mcp/option_parsers/env_options_parser.rb +3 -5
  56. data/lib/simplecov_mcp/option_parsers/error_helper.rb +18 -17
  57. data/lib/simplecov_mcp/path_relativizer.rb +17 -14
  58. data/lib/simplecov_mcp/predicate_evaluator.rb +72 -0
  59. data/lib/simplecov_mcp/presenters/base_coverage_presenter.rb +1 -3
  60. data/lib/simplecov_mcp/presenters/coverage_detailed_presenter.rb +1 -3
  61. data/lib/simplecov_mcp/presenters/coverage_raw_presenter.rb +1 -3
  62. data/lib/simplecov_mcp/presenters/coverage_summary_presenter.rb +1 -3
  63. data/lib/simplecov_mcp/presenters/coverage_uncovered_presenter.rb +1 -3
  64. data/lib/simplecov_mcp/presenters/project_coverage_presenter.rb +1 -3
  65. data/lib/simplecov_mcp/presenters/project_totals_presenter.rb +27 -0
  66. data/lib/simplecov_mcp/resolvers/coverage_line_resolver.rb +14 -18
  67. data/lib/simplecov_mcp/resolvers/resultset_path_resolver.rb +7 -9
  68. data/lib/simplecov_mcp/resultset_loader.rb +20 -25
  69. data/lib/simplecov_mcp/staleness_checker.rb +50 -46
  70. data/lib/simplecov_mcp/table_formatter.rb +64 -0
  71. data/lib/simplecov_mcp/tools/all_files_coverage_tool.rb +20 -50
  72. data/lib/simplecov_mcp/tools/coverage_detailed_tool.rb +13 -7
  73. data/lib/simplecov_mcp/tools/coverage_raw_tool.rb +12 -7
  74. data/lib/simplecov_mcp/tools/coverage_summary_tool.rb +13 -8
  75. data/lib/simplecov_mcp/tools/coverage_table_tool.rb +20 -60
  76. data/lib/simplecov_mcp/tools/coverage_totals_tool.rb +44 -0
  77. data/lib/simplecov_mcp/tools/help_tool.rb +38 -66
  78. data/lib/simplecov_mcp/tools/uncovered_lines_tool.rb +13 -8
  79. data/lib/simplecov_mcp/tools/validate_tool.rb +72 -0
  80. data/lib/simplecov_mcp/tools/version_tool.rb +7 -14
  81. data/lib/simplecov_mcp/util.rb +18 -12
  82. data/lib/simplecov_mcp/version.rb +1 -1
  83. data/lib/simplecov_mcp.rb +23 -29
  84. data/spec/all_files_coverage_tool_spec.rb +4 -3
  85. data/spec/{cli_config_spec.rb → app_config_spec.rb} +31 -26
  86. data/spec/base_tool_spec.rb +17 -14
  87. data/spec/cli/show_default_report_spec.rb +2 -2
  88. data/spec/cli_enumerated_options_spec.rb +31 -9
  89. data/spec/cli_error_spec.rb +46 -23
  90. data/spec/cli_format_spec.rb +123 -0
  91. data/spec/cli_json_options_spec.rb +50 -0
  92. data/spec/cli_source_spec.rb +11 -63
  93. data/spec/cli_spec.rb +82 -97
  94. data/spec/cli_usage_spec.rb +15 -15
  95. data/spec/commands/base_command_spec.rb +12 -92
  96. data/spec/commands/command_factory_spec.rb +7 -3
  97. data/spec/commands/detailed_command_spec.rb +10 -24
  98. data/spec/commands/list_command_spec.rb +28 -0
  99. data/spec/commands/raw_command_spec.rb +43 -20
  100. data/spec/commands/summary_command_spec.rb +10 -23
  101. data/spec/commands/totals_command_spec.rb +34 -0
  102. data/spec/commands/uncovered_command_spec.rb +29 -23
  103. data/spec/commands/validate_command_spec.rb +213 -0
  104. data/spec/commands/version_command_spec.rb +38 -0
  105. data/spec/constants_spec.rb +3 -3
  106. data/spec/coverage_reporter_spec.rb +102 -0
  107. data/spec/coverage_table_tool_spec.rb +21 -10
  108. data/spec/coverage_totals_tool_spec.rb +37 -0
  109. data/spec/error_handler_spec.rb +120 -4
  110. data/spec/error_mode_spec.rb +18 -22
  111. data/spec/errors_edge_cases_spec.rb +101 -28
  112. data/spec/errors_stale_spec.rb +34 -0
  113. data/spec/file_based_mcp_tools_spec.rb +6 -6
  114. data/spec/fixtures/project1/lib/bar.rb +2 -0
  115. data/spec/fixtures/project1/lib/foo.rb +2 -0
  116. data/spec/help_tool_spec.rb +2 -18
  117. data/spec/integration_spec.rb +114 -170
  118. data/spec/logging_fallback_spec.rb +3 -3
  119. data/spec/mcp_server_integration_spec.rb +1 -1
  120. data/spec/mcp_server_spec.rb +70 -53
  121. data/spec/mode_detector_spec.rb +46 -41
  122. data/spec/model_error_handling_spec.rb +141 -82
  123. data/spec/model_staleness_spec.rb +13 -13
  124. data/spec/option_normalizers_spec.rb +111 -112
  125. data/spec/option_parsers/env_options_parser_spec.rb +25 -37
  126. data/spec/option_parsers/error_helper_spec.rb +56 -56
  127. data/spec/path_relativizer_spec.rb +15 -0
  128. data/spec/presenters/coverage_detailed_presenter_spec.rb +1 -1
  129. data/spec/presenters/coverage_summary_presenter_spec.rb +1 -1
  130. data/spec/presenters/coverage_uncovered_presenter_spec.rb +1 -1
  131. data/spec/presenters/project_coverage_presenter_spec.rb +9 -8
  132. data/spec/presenters/project_totals_presenter_spec.rb +144 -0
  133. data/spec/resolvers/coverage_line_resolver_spec.rb +261 -36
  134. data/spec/resolvers/resultset_path_resolver_spec.rb +13 -8
  135. data/spec/shared_examples/file_based_mcp_tools.rb +23 -18
  136. data/spec/shared_examples/formatted_command_examples.rb +64 -0
  137. data/spec/simple_cov_mcp_module_spec.rb +24 -3
  138. data/spec/simplecov_mcp/formatters/source_formatter_spec.rb +267 -0
  139. data/spec/simplecov_mcp/formatters_spec.rb +76 -0
  140. data/spec/simplecov_mcp/presenters/base_coverage_presenter_spec.rb +79 -0
  141. data/spec/simplecov_mcp_model_spec.rb +99 -49
  142. data/spec/simplecov_mcp_opts_spec.rb +42 -39
  143. data/spec/spec_helper.rb +27 -92
  144. data/spec/staleness_checker_spec.rb +10 -9
  145. data/spec/staleness_more_spec.rb +4 -4
  146. data/spec/support/cli_helpers.rb +22 -0
  147. data/spec/support/control_flow_helpers.rb +20 -0
  148. data/spec/support/fake_mcp.rb +40 -0
  149. data/spec/support/io_helpers.rb +29 -0
  150. data/spec/support/mcp_helpers.rb +35 -0
  151. data/spec/support/mcp_runner.rb +10 -8
  152. data/spec/support/mocking_helpers.rb +30 -0
  153. data/spec/table_format_spec.rb +70 -0
  154. data/spec/tools/validate_tool_spec.rb +132 -0
  155. data/spec/tools_error_handling_spec.rb +34 -48
  156. data/spec/util_spec.rb +5 -4
  157. data/spec/version_spec.rb +7 -7
  158. data/spec/version_tool_spec.rb +20 -22
  159. metadata +90 -23
  160. data/docs/BRANCH_ONLY_COVERAGE.md +0 -81
  161. data/docs/CLI_USAGE.md +0 -637
  162. data/docs/EXAMPLES.md +0 -430
  163. data/docs/INSTALLATION.md +0 -352
  164. data/spec/cli_success_predicate_spec.rb +0 -141
@@ -0,0 +1,750 @@
1
+ # CLI Usage Guide
2
+
3
+ [Back to main README](../README.md)
4
+
5
+ Complete reference for using simplecov-mcp from the command line.
6
+
7
+ > Docs use `smcp` as a shortcut pointing at the demo fixture with partial coverage:
8
+ > `alias smcp='simplecov-mcp --root docs/fixtures/demo_project'`
9
+ > Replace `smcp` with `simplecov-mcp` to run commands against your own project.
10
+
11
+ ## Table of Contents
12
+
13
+ - [Quick Reference](#quick-reference)
14
+ - [Subcommands](#subcommands)
15
+ - [Global Options](#global-options)
16
+ - [Output Formats](#output-formats)
17
+ - [Environment Variables](#environment-variables)
18
+ - [Examples](#examples)
19
+
20
+ ## Quick Reference
21
+
22
+ ```sh
23
+ # Show coverage table for all files
24
+ smcp
25
+ smcp list
26
+
27
+ # Check specific file
28
+ smcp summary app/models/order.rb
29
+
30
+ # Find uncovered lines
31
+ smcp uncovered app/models/order.rb
32
+
33
+ # Get detailed per-line coverage
34
+ smcp detailed app/models/order.rb
35
+
36
+ # Get raw SimpleCov data
37
+ smcp raw app/models/order.rb
38
+
39
+ # Get project totals
40
+ smcp totals
41
+ smcp -fJ totals
42
+
43
+ # Show version
44
+ smcp version
45
+
46
+ # Get help
47
+ smcp -h # -h = --help
48
+ ```
49
+
50
+ ## Subcommands
51
+
52
+ ### `list`
53
+
54
+ Show coverage summary for all files (default subcommand).
55
+
56
+ ```sh
57
+ smcp list
58
+ smcp -o d list # -o = --sort-order, d = descending
59
+ smcp -fJ list
60
+ ```
61
+
62
+ Default sort order is descending (highest coverage first) so the lowest-coverage files stay visible at the bottom of the scrollback.
63
+
64
+ **Options:**
65
+
66
+ | Short | Long | Description |
67
+ |---------|--------------------------|-------------------------------------------------------|
68
+ | `-o` | `--sort-order` | Sort by coverage percentage (ascending or descending) |
69
+ | `-g` | `--tracked-globs` | Filter to specific file patterns |
70
+ | `-S` | `--staleness` | Staleness checking mode (off or error) |
71
+ | `-fJ` | `--format pretty-json` | Output as pretty-printed JSON |
72
+ | `-fj` | `--format json` | Output as single-line JSON |
73
+ | `-f y` | `--format yaml` | Output as YAML |
74
+ | `-f ap` | `--format awesome_print` | Output using AwesomePrint |
75
+
76
+ **Output (table format):**
77
+ ```
78
+ ┌────────────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
79
+ │ File │ % │ Covered │ Total │ Stale │
80
+ ├────────────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
81
+ │ lib/payments/refund_service.rb │ 60.00% │ 3 │ 5 │ │
82
+ │ app/controllers/orders_controller.rb │ 70.00% │ 7 │ 10 │ │
83
+ │ lib/ops/jobs/report_job.rb │ 80.00% │ 4 │ 5 │ │
84
+ │ lib/payments/processor.rb │ 80.00% │ 4 │ 5 │ │
85
+ │ app/models/order.rb │ 85.71% │ 6 │ 7 │ │
86
+ │ lib/api/client.rb │ 88.89% │ 8 │ 9 │ │
87
+ │ app/models/user.rb │ 100.00% │ 6 │ 6 │ │
88
+ └────────────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
89
+ Files: total 7, ok 7, stale 0
90
+ ```
91
+
92
+ **Stale indicators:** M (missing file), T (timestamp mismatch), L (line count mismatch)
93
+
94
+ ### `summary <path>`
95
+
96
+ Show covered/total/percentage for a specific file.
97
+
98
+ ```sh
99
+ smcp summary app/models/order.rb
100
+ smcp summary app/models/order.rb -fJ
101
+ smcp summary app/models/order.rb --source full
102
+ ```
103
+
104
+ **Arguments:**
105
+ - `<path>` - File path (relative to project root or absolute)
106
+
107
+ **Options:**
108
+
109
+ | Short | Long | Description |
110
+ |-------|------------------|--------------------------------------------|
111
+ | `-fJ` | `--format pretty-json` | Output as pretty-printed JSON |
112
+ | `-fj` | `--format json` | Output as single-line JSON |
113
+ | `-f y` | `--format yaml` | Output as YAML |
114
+ | `-f ap` | `--format awesome_print` | Output using AwesomePrint |
115
+ | `-s` | `--source MODE` | Include source code (full or uncovered) |
116
+
117
+ **Output (default format):**
118
+ ```
119
+ 85.71% 6/7 app/models/order.rb
120
+ ```
121
+
122
+ **Output (JSON format):**
123
+ ```json
124
+ {
125
+ "file": "app/models/order.rb",
126
+ "summary": {
127
+ "covered": 6,
128
+ "total": 7,
129
+ "percentage": 85.71
130
+ },
131
+ "stale": false
132
+ }
133
+ ```
134
+
135
+ ### `uncovered <path>`
136
+
137
+ Show uncovered line numbers for a specific file.
138
+
139
+ ```sh
140
+ smcp uncovered app/controllers/orders_controller.rb
141
+ smcp uncovered app/controllers/orders_controller.rb --source uncovered
142
+ smcp uncovered app/controllers/orders_controller.rb --source uncovered --context-lines 3
143
+ ```
144
+
145
+ **Arguments:**
146
+ - `<path>` - File path (relative to project root or absolute)
147
+
148
+ **Options:**
149
+
150
+ | Short | Long | Description |
151
+ |-------|-----------------------|-------------------------------------------------------|
152
+ | `-s` | `--source uncovered` | Show uncovered lines with context |
153
+ | `-c` | `--context-lines N` | Lines of context around uncovered lines (default: 2) |
154
+ | | `--color` | Enable syntax coloring |
155
+ | | `--no-color` | Disable syntax coloring |
156
+ | `-fJ` | `--format pretty-json` | Output as pretty-printed JSON |
157
+ | `-fj` | `--format json` | Output as single-line JSON |
158
+ | `-f y` | `--format yaml` | Output as YAML |
159
+ | `-f ap` | `--format awesome_print` | Output using AwesomePrint |
160
+
161
+ **Output (default format):**
162
+ ```
163
+ File: app/controllers/orders_controller.rb
164
+ Uncovered lines: 14, 15, 20
165
+ Summary: 70.0% 7/10
166
+ ```
167
+
168
+ **Output (with source):**
169
+ ```
170
+ File: app/controllers/orders_controller.rb
171
+ Uncovered lines: 14, 15, 20
172
+ Summary: 70.0% 7/10
173
+
174
+ Line | Source
175
+ ------+-----------------------------------------------------------
176
+ 14 · | def show(id)
177
+ 15 · | @repo.find(id)
178
+ 16 ✓ | end
179
+ 17 |
180
+ 18 ✓ | def cancel(id)
181
+ 19 ✓ | order = @repo.find(id)
182
+ 20 · | return :missing unless order
183
+ ```
184
+
185
+ **Legend:**
186
+ - `✓` - Line is covered
187
+ - `·` - Line is not covered
188
+ - ` ` - Line is not executable (comments, blank lines)
189
+
190
+ ### `detailed <path>`
191
+
192
+ Show per-line coverage with hit counts.
193
+
194
+ ```sh
195
+ smcp detailed app/models/order.rb
196
+ smcp detailed app/models/order.rb -fJ
197
+ smcp detailed app/models/order.rb --source full
198
+ ```
199
+
200
+ **Arguments:**
201
+ - `<path>` - File path (relative to project root or absolute)
202
+
203
+ **Options:**
204
+
205
+ | Short | Long | Description |
206
+ |---------|--------------------------|-------------------------------|
207
+ | `-fJ` | `--format pretty-json` | Output as pretty-printed JSON |
208
+ | `-fj` | `--format json` | Output as single-line JSON |
209
+ | `-f y` | `--format yaml` | Output as YAML |
210
+ | `-f ap` | `--format awesome_print` | Output using AwesomePrint |
211
+ | `-s` | `--source MODE` | Include source code |
212
+
213
+ **Output (default format):**
214
+ ```
215
+ File: app/models/order.rb
216
+ Line Hits Covered
217
+ ----- ---- -------
218
+ 6 1 yes
219
+ 7 1 yes
220
+ 8 1 yes
221
+ 11 1 yes
222
+ 12 1 yes
223
+ 15 1 yes
224
+ 16 0 no
225
+ ```
226
+
227
+ **Output (JSON format):**
228
+ ```json
229
+ {
230
+ "file": "app/models/order.rb",
231
+ "lines": [
232
+ { "line": 6, "hits": 1, "covered": true },
233
+ { "line": 7, "hits": 1, "covered": true },
234
+ { "line": 8, "hits": 1, "covered": true },
235
+ { "line": 11, "hits": 1, "covered": true },
236
+ { "line": 12, "hits": 1, "covered": true },
237
+ { "line": 15, "hits": 1, "covered": true },
238
+ { "line": 16, "hits": 0, "covered": false }
239
+ ],
240
+ "summary": {
241
+ "covered": 6,
242
+ "total": 7,
243
+ "percentage": 85.71
244
+ },
245
+ "stale": false
246
+ }
247
+ ```
248
+
249
+ ### `raw <path>`
250
+
251
+ Show the raw SimpleCov lines array.
252
+
253
+ ```sh
254
+ smcp raw app/models/order.rb
255
+ smcp raw app/models/order.rb -fJ
256
+ ```
257
+
258
+ **Arguments:**
259
+ - `<path>` - File path (relative to project root or absolute)
260
+
261
+ **Output (default format):**
262
+ ```
263
+ File: app/models/order.rb
264
+ [nil, nil, nil, nil, nil, 1, 1, 1, nil, nil, 1, 1, nil, nil, 1, 0, nil, nil, nil, nil]
265
+ ```
266
+
267
+ **Output (JSON format):**
268
+ ```json
269
+ {
270
+ "file": "app/models/order.rb",
271
+ "lines": [null, null, null, null, null, 1, 1, 1, null, null, 1, 1, null, null, 1, 0, null, null, null, null],
272
+ "stale": false
273
+ }
274
+ ```
275
+
276
+ **Array explanation:**
277
+ - Integer (e.g., `1`, `5`) - Number of times line was executed
278
+ - `0` - Line is executable but was not executed
279
+ - `null` - Line is not executable (comment, blank line)
280
+
281
+ ### `totals`
282
+
283
+ Show aggregated totals for all tracked files.
284
+
285
+ ```sh
286
+ smcp totals
287
+ smcp -fJ totals
288
+ smcp -g "lib/ops/jobs/*.rb" totals # -g = --tracked-globs
289
+ ```
290
+
291
+ **Output (default format):**
292
+ ```
293
+ Lines: total 47 covered 38 uncovered 9
294
+ Average coverage: 80.85% across 7 files (ok: 7, stale: 0)
295
+ ```
296
+
297
+ **Output (JSON format):**
298
+ ```json
299
+ {
300
+ "lines": { "total": 47, "covered": 38, "uncovered": 9 },
301
+ "percentage": 80.85,
302
+ "files": { "total": 7, "ok": 7, "stale": 0 }
303
+ }
304
+ ```
305
+
306
+ **Notes:**
307
+ - Respects `--tracked-globs` when you only want to aggregate a subset of files.
308
+ - Honors `--staleness error` to raise if coverage data is out of date.
309
+
310
+ ### `version`
311
+
312
+ Show version information.
313
+
314
+ ```sh
315
+ smcp version
316
+ smcp -fJ version
317
+ ```
318
+
319
+ **Output:**
320
+ ```
321
+ SimpleCovMcp version 1.0.0
322
+ ```
323
+
324
+ ## Global Options
325
+
326
+ These options work with all subcommands.
327
+
328
+ ### `-r, --resultset PATH`
329
+
330
+ Path to the `.resultset.json` file or a directory containing it.
331
+
332
+ 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.
333
+
334
+ ### `-R, --root PATH`
335
+
336
+ Project root directory (default: current directory).
337
+
338
+ ```sh
339
+ smcp --root /path/to/project
340
+ ```
341
+
342
+ ### `-fJ`
343
+
344
+ Output as pretty-printed JSON instead of human-readable format.
345
+
346
+ ```sh
347
+ smcp summary lib/api/client.rb -fJ
348
+ ```
349
+
350
+ Useful for:
351
+ - Parsing in scripts
352
+ - Integration with other tools
353
+ - Machine consumption
354
+
355
+ ### `-o, --sort-order ORDER`
356
+
357
+ Sort order for `list` subcommand.
358
+
359
+ **Values:**
360
+ - `descending`, `d` - Highest coverage first (default)
361
+ - `ascending`, `a` - Lowest coverage first
362
+
363
+ ```sh
364
+ smcp -o d list # d = descending (default)
365
+ smcp -o a list # a = ascending
366
+ ```
367
+
368
+ ### `-s, --source MODE`
369
+
370
+ Include source code in output.
371
+
372
+ **Modes:**
373
+
374
+ | Short | Long | Description |
375
+ |-------|-------------|-----------------------------------------------------|
376
+ | `f` | `full` | Show all source lines |
377
+ | `u` | `uncovered` | Show only uncovered lines with context |
378
+
379
+ ```sh
380
+ # Show full source
381
+ smcp -s full summary lib/api/client.rb # -s = --source
382
+ smcp -s f summary lib/api/client.rb # f = full
383
+
384
+ # Show only uncovered lines
385
+ smcp -s u uncovered lib/api/client.rb # u = uncovered
386
+ ```
387
+
388
+ ### `-c, --context-lines N`
389
+
390
+ Number of context lines around uncovered code (for `--source uncovered`). Must be a non-negative integer.
391
+
392
+ ```sh
393
+ smcp -s u -c 3 uncovered lib/api/client.rb # -s u = uncovered, -c = --context-lines
394
+ ```
395
+
396
+ **Default:** 2 lines
397
+
398
+ ### `--color` / `--no-color`
399
+
400
+ Enable or disable ANSI color codes in source output.
401
+
402
+ ```sh
403
+ smcp uncovered lib/api/client.rb --source --color
404
+ smcp uncovered lib/api/client.rb --source --no-color
405
+ ```
406
+
407
+ **Default:** Colors enabled if output is a TTY
408
+
409
+ ### `-S, --staleness MODE`
410
+
411
+ Staleness checking mode.
412
+
413
+ **Modes:**
414
+
415
+ | Short | Long | Description |
416
+ |-------|---------|----------------------------------------------------------|
417
+ | `o` | `off` | Detect and mark stale files, but don't raise error (default) |
418
+ | `e` | `error` | Detect stale files and raise error |
419
+
420
+ ```sh
421
+ # Exit with error if coverage is stale
422
+ smcp --staleness error
423
+ smcp -S e # Short form
424
+ ```
425
+
426
+ **Staleness conditions:**
427
+ - **M** (Missing): Source file no longer exists on disk
428
+ - **T** (Timestamp): Source file modified after coverage was generated
429
+ - **L** (Length): Source file line count differs from coverage data
430
+ - Tracked files missing from coverage (with --tracked-globs)
431
+
432
+ ### `-g, --tracked-globs PATTERNS`
433
+
434
+ Comma-separated glob patterns for files that should be tracked.
435
+
436
+ ```sh
437
+ smcp -g "lib/payments/**/*.rb,lib/ops/jobs/**/*.rb" list # -g = --tracked-globs
438
+ ```
439
+
440
+ Used with `--staleness error` to detect new files not yet in coverage and to filter the `list`/`totals` subcommands.
441
+
442
+ ### `-l, --log-file PATH`
443
+
444
+ Log file location. Use 'stdout' or 'stderr' to log to standard streams.
445
+
446
+ ```sh
447
+ smcp -l /var/log/simplecov.log # -l = --log-file
448
+ smcp -l stdout # Log to standard output
449
+ smcp -l stderr # Log to standard error
450
+ ```
451
+
452
+ **Default:** `./simplecov_mcp.log`
453
+
454
+ ### `--error-mode MODE`
455
+
456
+ Error handling verbosity.
457
+
458
+ **Modes:**
459
+
460
+ | Short | Long | Description |
461
+ |-------|---------|----------------------------------------------------|
462
+ | | `off` | Silent (no error logging) |
463
+ | `l` | `log` | Log errors without stack traces (default) |
464
+ | `d` | `debug` | Log errors with full stack traces |
465
+
466
+ ```sh
467
+ smcp --error-mode debug summary lib/api/client.rb
468
+ ```
469
+
470
+ ### `--force-cli`
471
+
472
+ 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.
473
+
474
+ ```sh
475
+ smcp --force-cli list
476
+ ```
477
+
478
+ ### `validate` Subcommand
479
+
480
+ Validate coverage against custom policies for CI/CD enforcement.
481
+
482
+ > **⚠️ SECURITY WARNING**
483
+ >
484
+ > Validation predicates execute as **arbitrary Ruby code with full system privileges**. They have unrestricted access
485
+ > to file system, network, system commands, and environment variables.
486
+ >
487
+ > **Only use predicate files from trusted sources.**
488
+ > Review predicates before use, especially in CI/CD environments.
489
+
490
+ The predicate must be a callable (lambda, proc, or object with `#call` method) that receives a `CoverageModel` and returns `true` or `false`.
491
+
492
+ **Predicate return values:**
493
+ - `true` - Coverage meets your criteria (CLI exits with code 0)
494
+ - `false` - Coverage fails your criteria (CLI exits with code 1)
495
+ - Exception raised - Predicate error (CLI exits with code 2)
496
+
497
+ **File mode (most common):**
498
+ ```sh
499
+ # Use example predicate
500
+ smcp validate examples/success_predicates/all_files_above_threshold_predicate.rb
501
+
502
+ # In CI/CD
503
+ bundle exec simplecov-mcp validate coverage_policy.rb
504
+ ```
505
+
506
+ **String mode (inline code):**
507
+ ```sh
508
+ # Simple inline validation
509
+ smcp validate -i '->(m) { m.all_files.all? { |f| f["percentage"] >= 80 } }'
510
+
511
+ # With global options
512
+ smcp --resultset coverage validate -i '->(m) { m.all_files.size > 0 }'
513
+ ```
514
+
515
+ **Example predicate file:**
516
+ ```ruby
517
+ # coverage_policy.rb
518
+ ->(model) do
519
+ model.all_files.all? { |f| f['percentage'] >= 80 }
520
+ end
521
+ ```
522
+
523
+ See [examples/success_predicates/](../../examples/success_predicates/) for more examples.
524
+
525
+ ## Output Formats
526
+
527
+ ### Table Format
528
+
529
+ Default for `list` subcommand. Uses Unicode box-drawing characters.
530
+
531
+ ```
532
+ ┌──────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
533
+ │ File │ % │ Covered │ Total │ Stale │
534
+ ├──────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
535
+ │ lib/payments/refund_service.rb │ 60.00% │ 3 │ 5 │ │
536
+ └──────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
537
+ ```
538
+
539
+ ### JSON Format
540
+
541
+ Machine-readable output. Paths are relative to project root.
542
+
543
+ ```json
544
+ {
545
+ "file": "app/models/order.rb",
546
+ "summary": {
547
+ "covered": 6,
548
+ "total": 7,
549
+ "percentage": 85.71
550
+ },
551
+ "stale": false
552
+ }
553
+ ```
554
+
555
+ **Staleness values:**
556
+ - `false` - Coverage data is current
557
+ - `"M"` - File missing (no longer exists on disk)
558
+ - `"T"` - Timestamp mismatch (file modified after coverage)
559
+ - `"L"` - Length mismatch (line count differs)
560
+
561
+ ### Source Display
562
+
563
+ With `--source` flag, shows annotated source code:
564
+
565
+ ```
566
+ Line | Source
567
+ ------+-----------------------------------------------------------
568
+ 1 ✓ | class User
569
+ 2 · | def initialize # Not covered
570
+ 3 ✓ | # ...
571
+ ```
572
+
573
+ ## Environment Variables
574
+
575
+ ### `SIMPLECOV_MCP_OPTS`
576
+
577
+ Default command-line options applied to all invocations.
578
+
579
+ **Format:** Shell-style string containing any valid CLI options
580
+
581
+ ```sh
582
+ export SIMPLECOV_MCP_OPTS="--resultset coverage -fJ"
583
+ smcp summary lib/api/client.rb # Automatically uses options above
584
+ ```
585
+
586
+ **Precedence:** Command-line arguments override environment options
587
+
588
+ ```sh
589
+ # Environment sets -fJ; explicit CLI options still take precedence
590
+ export SIMPLECOV_MCP_OPTS="-fJ"
591
+ smcp summary lib/api/client.rb # Uses JSON (from env)
592
+ smcp summary lib/api/client.rb -fJ # Explicit, same result
593
+ ```
594
+
595
+ **Examples:**
596
+ ```sh
597
+ # Default resultset location
598
+ export SIMPLECOV_MCP_OPTS="--resultset build/coverage"
599
+
600
+ # Enable detailed error logging
601
+ export SIMPLECOV_MCP_OPTS="--error-mode debug"
602
+
603
+ # Paths with spaces
604
+ export SIMPLECOV_MCP_OPTS='--resultset "/path with spaces/coverage"'
605
+
606
+ # Multiple options
607
+ export SIMPLECOV_MCP_OPTS="--resultset coverage --staleness error -fJ"
608
+ ```
609
+
610
+
611
+
612
+ ## Examples
613
+
614
+ ### Basic Coverage Check
615
+
616
+ ```sh
617
+ # Show all files sorted by lowest coverage first
618
+ smcp
619
+
620
+ # Find the 5 files with worst coverage
621
+ smcp list | head -10
622
+ ```
623
+
624
+ ### Detailed File Investigation
625
+
626
+ ```sh
627
+ # Check a specific file
628
+ smcp summary lib/payments/refund_service.rb
629
+
630
+ # See which lines aren't covered
631
+ smcp uncovered lib/payments/refund_service.rb
632
+
633
+ # View uncovered code in context
634
+ smcp uncovered lib/payments/refund_service.rb --source uncovered --context-lines 3
635
+
636
+ # Get detailed hit counts
637
+ smcp detailed lib/payments/refund_service.rb
638
+ ```
639
+
640
+ ### JSON Output for Scripts
641
+
642
+ ```sh
643
+ # Get JSON for parsing
644
+ smcp -fJ list > coverage.json
645
+
646
+ # Extract files below threshold
647
+ smcp -fJ list | jq '.files[] | select(.percentage < 80)'
648
+
649
+ # Ruby alternative:
650
+ smcp -fJ list | ruby -r json -e '
651
+ JSON.parse($stdin.read)["files"].select { |f| f["percentage"] < 80 }.each do |f|
652
+ puts JSON.pretty_generate(f)
653
+ end
654
+ '
655
+
656
+ # Rexe alternative:
657
+ smcp -fJ list | rexe -ij -mb -oJ 'self["files"].select { |f| f["percentage"] < 80 }'
658
+
659
+ # Count files below 80% coverage
660
+ smcp -fJ list | jq '[.files[] | select(.percentage < 80)] | length'
661
+
662
+ # Ruby alternative:
663
+ smcp -fJ list | ruby -r json -e '
664
+ puts JSON.parse($stdin.read)["files"].count { |f| f["percentage"] < 80 }
665
+ '
666
+
667
+ # Rexe alternative:
668
+ smcp -fJ list | rexe -ij -mb -op 'self["files"].count { |f| f["percentage"] < 80 }'
669
+ ```
670
+
671
+ ### Filtering and Sorting
672
+
673
+ ```sh
674
+ # Show only lib/ files
675
+ smcp -g "lib/**/*.rb" list
676
+
677
+ # Show files sorted by highest coverage
678
+ smcp -o d list
679
+
680
+ # Check specific directory
681
+ smcp -g "lib/payments/**/*.rb" list
682
+ ```
683
+
684
+
685
+
686
+ ### Staleness Checking
687
+
688
+ ```sh
689
+ # Check if coverage is stale (for CI/CD)
690
+ smcp --staleness error
691
+
692
+ # Check with specific file patterns
693
+ smcp --staleness error -g "lib/payments/**/*.rb,lib/ops/jobs/**/*.rb" list
694
+
695
+ # See which files are stale (don't error)
696
+ smcp list # Stale files marked with !
697
+ ```
698
+
699
+ ### Source Code Display
700
+
701
+ ```sh
702
+ # Show full source with coverage markers
703
+ smcp summary lib/api/client.rb --source full
704
+
705
+ # Show only uncovered lines with context
706
+ smcp uncovered lib/api/client.rb --source uncovered
707
+
708
+ # More context around uncovered code
709
+ smcp uncovered lib/api/client.rb --source uncovered --context-lines 5
710
+
711
+ # Without colors (for logging)
712
+ smcp uncovered lib/api/client.rb --source full --no-color
713
+ ```
714
+
715
+ ### CI/CD Integration
716
+
717
+ ```sh
718
+ # Fail build if coverage is stale
719
+ smcp --staleness error || exit 1
720
+
721
+ # Generate JSON report for artifact
722
+ smcp -fJ list > artifacts/coverage-report.json
723
+
724
+ # Check specific directory in monorepo
725
+ smcp -R services/api -r services/api/coverage # -R = --root, -r = --resultset
726
+ ```
727
+
728
+ ### Debugging
729
+
730
+ ```sh
731
+ # Verbose error output
732
+ smcp --error-mode debug summary lib/api/client.rb
733
+
734
+ # Custom log file
735
+ smcp --log-file /tmp/simplecov-debug.log summary lib/api/client.rb
736
+
737
+ # Check what resultset is being used
738
+ smcp --error-mode debug 2>&1 | grep resultset
739
+ ```
740
+
741
+ ## Exit Codes
742
+
743
+ - `0` - Success
744
+ - `1` - Error (file not found, coverage data missing, stale coverage with `--staleness error`, etc.)
745
+
746
+ ## Next Steps
747
+
748
+ - **[Library API](LIBRARY_API.md)** - Use in Ruby code
749
+ - **[Examples](EXAMPLES.md)** - More usage examples and recipes
750
+ - **[Troubleshooting](TROUBLESHOOTING.md)** - Common issues and solutions