simplecov-mcp 0.2.1 → 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 (148) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/README.md +173 -345
  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 -15
  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 +14 -7
  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 -23
  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 +8 -13
  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 -4
  134. data/spec/version_tool_spec.rb +143 -0
  135. metadata +121 -59
  136. data/lib/simple_cov/mcp.rb +0 -9
  137. data/lib/simple_cov_mcp/base_tool.rb +0 -54
  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/legacy_shim_spec.rb +0 -13
data/README.md CHANGED
@@ -1,444 +1,272 @@
1
1
  # simplecov-mcp
2
2
 
3
- MCP server + CLI for inspecting SimpleCov coverage data.
3
+ > MCP server + CLI + Ruby library for inspecting SimpleCov coverage data
4
4
 
5
- This gem provides:
5
+ [![Gem Version](https://badge.fury.io/rb/simplecov-mcp.svg)](https://badge.fury.io/rb/simplecov-mcp)
6
6
 
7
- - An MCP (Model Context Protocol) server exposing tools to query coverage for files.
8
- - A flexible CLI with subcommands to list all files, show a file summary, print raw coverage arrays, list uncovered lines, and display detailed per-line hits. Supports JSON output, displaying annotated source code (full file or uncovered lines with context), and custom resultset locations.
7
+ ## What is simplecov-mcp?
9
8
 
10
- ## Features
9
+ **simplecov-mcp** makes SimpleCov coverage data queryable and actionable through three interfaces:
11
10
 
12
- - MCP server tools for coverage queries: raw, summary, uncovered, detailed, all-files list, and version.
13
- - Per-file staleness flag in list outputs to highlight files newer than coverage or with line-count mismatches (shown as a compact '!' column in the CLI).
14
- - CLI subcommands: `list`, `summary`, `raw`, `uncovered`, `detailed`, `version` (default `list`).
15
- - JSON output with `--json` for machine use; human-readable tables/rows by default.
16
- - Annotated source snippets with `--source[=full|uncovered]` and `--source-context N`; optional colors with `--color/--no-color`.
17
- - Flexible resultset location: `--resultset PATH` or `SIMPLECOV_RESULTSET`; accepts file or directory; sensible default search order.
18
- - Works installed as a gem, via Bundler (`bundle exec`), or directly from this repo’s `exe/` (symlink-safe).
11
+ - **MCP server** - Let AI assistants analyze your coverage
12
+ - **CLI** - Fast command-line coverage reports and queries
13
+ - **Ruby library** - Programmatic API for custom tooling
19
14
 
20
- ## SimpleCov Independence
15
+ Works with any SimpleCov-generated `.resultset.json` file—no runtime dependency on your test suite.
21
16
 
22
- This codebase does not require, and is not connected to, the `simplecov` library at runtime. Its only interaction is reading the JSON resultset file that SimpleCov generates (`.resultset.json`). As long as that file exists in your project (in a default or specified location), the CLI and MCP server can operate without `require "simplecov"` in your app or test process.
17
+ ### Key capabilities
23
18
 
24
- ## Installation
19
+ - Flexible path resolution (absolute or relative paths)
20
+ - Staleness detection (identifies outdated coverage files)
21
+ - Multi-suite resultset merging when needed
22
+ - Multiple useful output formats (tables, JSON, annotated source)
25
23
 
26
- Add to your Gemfile or install directly:
24
+ ### Practical use cases
25
+
26
+ - Query coverage data from AI assistants, e.g.:
27
+ - "Using simplecov-mcp, analyze test coverage data and write a report to a markdown file containing a free text analysis of each issue and then two tables, one sorted in descending order of urgency, the other in ascending order of level of effort."
28
+ - "Using simplecov-mcp, generate a table of directories and their average coverage rates, in ascending order of coverage."
29
+ - Find files with the lowest coverage
30
+ - Investigate specific files or directories
31
+ - Generate CI/CD coverage reports
32
+
33
+ ## Quick Start
34
+
35
+ ### Installation
27
36
 
28
37
  ```sh
29
38
  gem install simplecov-mcp
30
39
  ```
31
40
 
32
- Require path is `simple_cov_mcp` (also `simplecov_mcp`). Legacy `simple_cov/mcp` is supported via shim. Executable is `simplecov-mcp`.
41
+ ### Generate Coverage Data
42
+
43
+ ```sh
44
+ # Run your tests with SimpleCov enabled
45
+ bundle exec rspec # or your test command
33
46
 
34
- ## Usage
47
+ # Verify coverage was generated
48
+ ls coverage/.resultset.json
49
+ ```
35
50
 
36
- ### Library Usage (Ruby)
51
+ ### Basic Usage
37
52
 
38
- Use this gem programmatically to inspect coverage without running the CLI or MCP server. The primary entry point is `SimpleCovMcp::CoverageModel`.
53
+ **CLI - View Coverage Table:**
54
+ ```sh
55
+ simplecov-mcp
56
+ ```
39
57
 
40
- Basics:
58
+ **CLI - Check Specific File:**
59
+ ```sh
60
+ simplecov-mcp summary lib/simplecov_mcp/model.rb
61
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb
62
+ ```
41
63
 
64
+ **Ruby Library:**
42
65
  ```ruby
43
- require "simple_cov_mcp"
66
+ require "simplecov_mcp"
44
67
 
45
- # Defaults (omit args; shown here with comments):
46
- # - root: "."
47
- # - resultset: resolved from SIMPLECOV_RESULTSET or common paths under root
48
- # - staleness: "off" (no stale checks)
49
- # - tracked_globs: nil (no project-level file-set checks)
50
68
  model = SimpleCovMcp::CoverageModel.new
51
-
52
- # Custom configuration (non-default values):
53
- model = SimpleCovMcp::CoverageModel.new(
54
- root: "/path/to/project", # non-default project root
55
- resultset: "build/coverage", # file or directory containing .resultset.json
56
- staleness: "error", # enable stale checks (raise on stale)
57
- tracked_globs: ["lib/**/*.rb"] # for 'all_files' staleness: flag new/missing files
58
- )
59
-
60
- # List all files with coverage summary, sorted ascending by % (default)
61
69
  files = model.all_files
62
- # => [ { 'file' => '/abs/path/lib/foo.rb', 'covered' => 12, 'total' => 14, 'percentage' => 85.71, 'stale' => false }, ... ]
63
-
64
- # Per-file summaries
65
- summary = model.summary_for("lib/foo.rb")
66
- # => { 'file' => '/abs/.../lib/foo.rb', 'summary' => {'covered'=>12, 'total'=>14, 'pct'=>85.71} }
67
-
68
- raw = model.raw_for("lib/foo.rb")
69
- # => { 'file' => '/abs/.../lib/foo.rb', 'lines' => [nil, 1, 0, 3, ...] }
70
-
71
- uncovered = model.uncovered_for("lib/foo.rb")
72
- # => { 'file' => '/abs/.../lib/foo.rb', 'uncovered' => [5, 9, 12], 'summary' => { ... } }
70
+ # => [{ "file" => "lib/simplecov_mcp/model.rb", "covered" => 114, "total" => 118, "percentage" => 96.61, "stale" => false }, ...]
73
71
 
74
- detailed = model.detailed_for("lib/foo.rb")
75
- # => { 'file' => '/abs/.../lib/foo.rb', 'lines' => [{'line' => 1, 'hits' => 1, 'covered' => true}, ...], 'summary' => { ... } }
72
+ summary = model.summary_for("lib/simplecov_mcp/model.rb")
73
+ # => { "file" => "lib/simplecov_mcp/model.rb", "summary" => { "covered" => 114, "total" => 118, "pct" => 96.61 }, "stale" => false }
76
74
  ```
77
75
 
78
- ### MCP Quick Start
76
+ **MCP Server:**
77
+ See [MCP Integration Guide](docs/MCP_INTEGRATION.md) for AI assistant setup.
79
78
 
80
- - Prereqs: Ruby 3.2+; run tests once so `coverage/.resultset.json` exists.
81
- - One-off MCP requests can be made by piping JSON-RPC to the server:
79
+ ## Key Features
82
80
 
83
- **Important**: JSON-RPC messages must be on a single line (no line breaks). Multi-line JSON will cause parse errors.
81
+ - **Multiple interfaces** - MCP server, CLI, and Ruby API
82
+ - ✅ **Rich output formats** - Tables, JSON, annotated source code
83
+ - ✅ **Staleness detection** - Identify outdated coverage (missing files, timestamp mismatches, line count changes)
84
+ - ✅ **Multi-suite support** - Automatic merging of multiple test suites (RSpec + Cucumber, etc.)
85
+ - ✅ **Flexible path resolution** - Works with absolute or relative paths
86
+ - ✅ **Comprehensive error handling** - Context-aware messages for each mode
87
+ - ⚠️ **Branch coverage limitation** - Branch-level metrics are collapsed to per-line totals. Use native SimpleCov reports for branch-by-branch analysis.
84
88
 
85
- ```sh
86
- # Per-file summary (staleness off)
87
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/foo.rb","resultset":"coverage","stale":"off"}}}' | simplecov-mcp
88
-
89
- # All files with project-level staleness checks
90
- echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"all_files_coverage_tool","arguments":{"resultset":"coverage","stale":"error","tracked_globs":["lib/**/*.rb"]}}}' | simplecov-mcp
91
- ```
89
+ ## Multi-Suite Coverage Merging
92
90
 
93
- Tip: In an MCP-capable editor/agent, configure `simplecov-mcp` as a stdio server and call the same tool names with the `arguments` shown above.
91
+ ### How It Works
94
92
 
95
- Resultset resolution:
93
+ When a `.resultset.json` file contains multiple test suites (e.g., RSpec + Cucumber), `simplecov-mcp` automatically merges them using SimpleCov's combine logic. All covered files from every suite become available to the CLI, library, and MCP tools.
96
94
 
97
- - If `resultset:` is provided, it may be:
98
- - a file path to `.resultset.json`, or
99
- - a directory containing `.resultset.json` (e.g., `coverage/`).
100
- - If `resultset:` is omitted, resolution follows:
101
- 1) `ENV["SIMPLECOV_RESULTSET"]` (file or directory), then
102
- 2) `.resultset.json`, 3) `coverage/.resultset.json`, 4) `tmp/.resultset.json` under `root`.
95
+ **Performance:** Single-suite projects avoid loading SimpleCov at runtime. Multi-suite resultsets trigger a lazy SimpleCov load only when needed, keeping the tool fast for the simpler coverage configurations.
103
96
 
104
- Path semantics:
97
+ ### Current Limitations
105
98
 
106
- - Methods accept paths relative to `root` or absolute paths. Internally, the model resolves to an absolute path and looks up coverage by:
107
- 1) exact absolute path,
108
- 2) the path without the current working directory prefix,
109
- 3) filename (basename) match as a last resort.
99
+ **Staleness checks:** When suites are merged, we keep a single "latest suite" timestamp. This matches prior behavior but may under-report stale files if only some suites were re-run after a change. A per-file timestamp refinement is planned. Until then, consider multi-suite staleness checks advisory rather than definitive.
110
100
 
111
- Sorting:
101
+ **Multiple resultset files:** Only suites stored inside a *single* `.resultset.json` are merged automatically. If your project produces separate resultset files (e.g., different CI jobs writing `coverage/job1/.resultset.json`, `coverage/job2/.resultset.json`), you must merge them yourself before pointing `simplecov-mcp` at the combined file.
112
102
 
113
- ```ruby
114
- model.all_files(sort_order: :descending) # or :ascending (default)
115
- ```
103
+ ## Documentation
116
104
 
117
- ## Example Prompts
105
+ **Getting Started:**
106
+ - [Installation](docs/INSTALLATION.md) - Setup for different environments
107
+ - [CLI Usage](docs/CLI_USAGE.md) - Command-line reference
108
+ - [Examples](docs/EXAMPLES.md) - Common use cases
118
109
 
119
- Using simplecov-mcp, show me a table of all files and their coverages.
110
+ **Advanced Usage:**
111
+ - [MCP Integration](docs/MCP_INTEGRATION.md) - AI assistant configuration
112
+ - [Library API](docs/LIBRARY_API.md) - Ruby API documentation
113
+ - [Error Handling](docs/ERROR_HANDLING.md) - Error modes and exceptions
120
114
 
121
- ----
115
+ **Reference:**
116
+ - [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues
117
+ - [Development](docs/DEVELOPMENT.md) - Contributing guide
122
118
 
123
- Using simplecov-mcp, find the uncovered code lines and report to me:
119
+ ## Requirements
124
120
 
125
- * the most important coverage omissions to address
126
- * the simplest coverage omissions to address
127
- * analyze the risk of the current state of coverage
128
- * propose a plan of action (if any) to improve coverage state
121
+ - **Ruby >= 3.2** (required by `mcp` gem dependency)
122
+ - SimpleCov-generated `.resultset.json` file
123
+ - `simplecov` gem >= 0.21
124
+ - RVM users: export your preferred ruby/gemset *before* running commands (e.g. `rvm use 3.4.5@simplecov-mcp`)
129
125
 
130
- ----
126
+ ## Configuring the Resultset
131
127
 
128
+ `simplecov-mcp` automatically searches for `.resultset.json` in standard locations (`coverage/.resultset.json`, `.resultset.json`, `tmp/.resultset.json`). For non-standard locations:
132
129
 
133
- ## Error Handling
134
-
135
- This tool provides different error handling behavior depending on how it's used:
130
+ ```sh
131
+ # Command-line option (highest priority)
132
+ simplecov-mcp --resultset /path/to/your/coverage
136
133
 
137
- ### CLI Mode
138
- When used as a command-line tool, errors are displayed as user-friendly messages without stack traces:
134
+ # Environment variable (project-wide default)
135
+ export SIMPLECOV_MCP_OPTS="--resultset /path/to/your/coverage"
139
136
 
140
- ```bash
141
- $ simplecov-mcp summary nonexistent.rb
142
- File error: No coverage data found for the specified file
137
+ # MCP server configuration
138
+ # Add to your MCP client config:
139
+ # "args": ["--resultset", "/path/to/your/coverage"]
143
140
  ```
144
141
 
145
- For debugging, set the `SIMPLECOV_MCP_DEBUG=1` environment variable to see full stack traces.
146
-
147
- ### Library Mode
148
- When used as a Ruby library, errors are raised as custom exception classes that can be caught and handled:
142
+ See [CLI Usage Guide](docs/CLI_USAGE.md#-r---resultset-path) for complete details.
149
143
 
150
- ```ruby
151
- begin
152
- SimpleCovMcp.run_as_library(['summary', 'missing.rb'])
153
- rescue SimpleCovMcp::FileError => e
154
- puts "Handled gracefully: #{e.user_friendly_message}"
155
- end
156
- ```
157
144
 
158
- Available exception classes:
159
- - `SimpleCovMcp::Error` - Base error class
160
- - `SimpleCovMcp::FileError` - File not found or access issues
161
- - `SimpleCovMcp::CoverageDataError` - Invalid or missing coverage data
162
- - `SimpleCovMcp::ConfigurationError` - Configuration problems
163
- - `SimpleCovMcp::UsageError` - Command usage errors
164
145
 
165
- ### MCP Server Mode
166
- When running as an MCP server, errors are handled internally and returned as structured responses to the MCP client. The MCP server uses:
146
+ ## Common Workflows
167
147
 
168
- - **Logging enabled** - Errors are logged to `~/simplecov_mcp.log` for server debugging
169
- - **Clean error messages** - User-friendly messages are returned to the client (no stack traces unless `SIMPLECOV_MCP_DEBUG=1`)
170
- - **Structured responses** - Errors are returned as proper MCP tool responses, not exceptions
148
+ ### Find Coverage Gaps
171
149
 
172
- The MCP server automatically configures error handling appropriately for server usage.
150
+ ```sh
151
+ # Files with worst coverage
152
+ simplecov-mcp list --sort-order d # display table in descending order, worst will be at end of output
153
+ simplecov-mcp list -o d # same as above, short form option
154
+ simplecov-mcp list | less # display table in pager, worst files first
155
+ simplecov-mcp list | head -10 # truncate the table
173
156
 
174
- ### Custom Error Handlers
175
- Library usage defaults to no logging to avoid side effects, but you can customize this:
157
+ # Specific directory
158
+ simplecov-mcp list --tracked-globs "lib/simplecov_mcp/tools/**/*.rb"
176
159
 
177
- ```ruby
178
- # Default library behavior - no logging
179
- SimpleCovMcp.run_as_library(['summary', 'file.rb'])
180
-
181
- # Custom error handler with logging enabled
182
- handler = SimpleCovMcp::ErrorHandler.new(
183
- log_errors: true, # Enable logging for library usage
184
- show_stack_traces: false # Clean error messages
185
- )
186
- SimpleCovMcp.run_as_library(argv, error_handler: handler)
187
-
188
- # Or configure globally for MCP tools
189
- SimpleCovMcp.configure_error_handling do |handler|
190
- handler.log_errors = true
191
- handler.show_stack_traces = true # For debugging
192
- end
160
+ # Export for analysis
161
+ simplecov-mcp list --json > coverage-report.json
193
162
  ```
194
163
 
195
- ### Legacy Error Handling Tips
196
-
197
- - Missing resultset: `SimpleCov::Mcp::CovUtil.find_resultset` raises with guidance to run tests or set `SIMPLECOV_RESULTSET`.
198
- - Missing file coverage: lookups raise `"No coverage entry found for <path>"`.
164
+ ### CI/CD Integration
199
165
 
200
- Example: fail CI if a file has uncovered lines
201
-
202
- ```ruby
203
- require "simple_cov_mcp"
204
-
205
- model = SimpleCovMcp::CoverageModel.new(root: Dir.pwd)
206
- res = model.uncovered_for("lib/foo.rb")
207
- if res['uncovered'].any?
208
- warn "Uncovered lines in lib/foo.rb: #{res['uncovered'].join(", ")}"
209
- exit 1
210
- end
211
- ```
212
-
213
- Example: enforce a project-wide minimum percentage
166
+ ```sh
167
+ # Fail build if coverage is stale
168
+ simplecov-mcp --stale error || exit 1
214
169
 
215
- ```ruby
216
- require "simple_cov_mcp"
217
-
218
- threshold = 90.0
219
- min = model.all_files.map { |r| r['percentage'] }.min || 100.0
220
- if min < threshold
221
- warn "Min coverage %.2f%% is below threshold %.2f%%" % [min, threshold]
222
- exit 1
223
- end
170
+ # Generate coverage report artifact
171
+ simplecov-mcp list --json > artifacts/coverage.json
224
172
  ```
225
173
 
226
- Public API stability:
227
-
228
- - Consider the following public and stable under SemVer:
229
- - `SimpleCovMcp::CoverageModel.new(root:, resultset:, staleness: 'off', tracked_globs: nil)`
230
- - `#raw_for(path)`, `#summary_for(path)`, `#uncovered_for(path)`, `#detailed_for(path)`, `#all_files(sort_order:)`
231
- - Return shapes shown above (keys and value types). For `all_files`, each row also includes `'stale' => true|false`.
232
- - CLI (`SimpleCovMcp.run(argv)`) and MCP tools remain stable but are separate surfaces.
233
- - Internal helpers under `SimpleCovMcp::CovUtil` may change; prefer `CoverageModel` unless you need low-level access.
234
-
235
- ### Resultset Location
236
-
237
- - Defaults (search order):
238
- 1. `.resultset.json`
239
- 2. `coverage/.resultset.json`
240
- 3. `tmp/.resultset.json`
241
- - Override via CLI: `--resultset PATH` (PATH may be the file itself or a directory containing `.resultset.json`).
242
- - Override via environment: `SIMPLECOV_RESULTSET=PATH` (file or directory). This takes precedence over defaults. The CLI flag, when present, takes precedence over the environment variable.
243
-
244
- ### CLI Mode
245
-
246
- ### Stale Coverage Errors
174
+ ### Investigate Specific Files
247
175
 
248
- When strict staleness checking is enabled, the model (and CLI) raise a
249
- `CoverageDataStaleError` if a source file appears newer than the coverage data
250
- or the line counts differ.
251
-
252
- - Enable per instance: `SimpleCovMcp::CoverageModel.new(staleness: 'error')`
253
-
254
- The error message is detailed and includes:
176
+ ```sh
177
+ # Quick summary
178
+ simplecov-mcp summary lib/simplecov_mcp/model.rb
255
179
 
256
- - File and Coverage times (UTC and local) and line counts
257
- - A delta indicating how much newer the file is than coverage
258
- - The absolute path to the `.resultset.json` used
180
+ # See uncovered lines
181
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb
259
182
 
260
- Example excerpt:
183
+ # View in context
184
+ simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source=uncovered --source-context 3
261
185
 
186
+ # Detailed hit counts
187
+ simplecov-mcp detailed lib/simplecov_mcp/util.rb
262
188
  ```
263
- Coverage data stale: Coverage data appears stale for lib/foo.rb
264
- File - time: 2025-09-16T14:03:22Z (local 2025-09-16T07:03:22-07:00), lines: 226
265
- Coverage - time: 2025-09-15T21:11:09Z (local 2025-09-15T14:11:09-07:00), lines: 220
266
- Delta - file is +123s newer than coverage
267
- Resultset - /path/to/your/project/coverage/.resultset.json
268
- ```
269
-
270
- Run in a project directory with a SimpleCov resultset:
271
189
 
272
- ```sh
273
- simplecov-mcp # same as 'list'
274
- ```
190
+ ## Commands and Tools
275
191
 
276
- Subcommands:
192
+ **CLI Subcommands:** `list`, `summary`, `uncovered`, `detailed`, `raw`, `version`
277
193
 
278
- - `list` show the table of all files (sorted ascending by default)
279
- - `summary <path>` — show covered/total/% for a file
280
- - `raw <path>` — show the original SimpleCov lines array
281
- - `uncovered <path>` — show uncovered lines and summary
282
- - `detailed <path>` — show per-line rows with hits and covered
283
- - `version` — show version information
194
+ **MCP Tools:** `coverage_summary_tool`, `coverage_detailed_tool`, `coverage_raw_tool`, `uncovered_lines_tool`, `all_files_coverage_tool`, `coverage_table_tool`, `help_tool`, `version_tool`
284
195
 
285
- Global flags (OptionParser):
196
+ 📖 **See also:**
197
+ - [CLI Usage Guide](docs/CLI_USAGE.md) - Complete command-line reference
198
+ - [MCP Integration Guide](docs/MCP_INTEGRATION.md#available-mcp-tools) - MCP tools documentation
286
199
 
287
- - `--cli` (alias `--report`) — force CLI output
288
- - `--resultset PATH` — path or directory for `.resultset.json`
289
- - `--root PATH` — project root (default `.`)
290
- - `--json` — print JSON output for machine use
291
- - `--sort-order ascending|descending` — for `list`
292
- - `--source[=MODE]` — include source text for `summary`, `uncovered`, `detailed` (MODE: `full` or `uncovered`; default `full`)
293
- - `--source-context N` — for `--source=uncovered`, lines of context (default 2)
294
- - `--color` / `--no-color` — enable/disable ANSI colors in source output
295
- - `--stale off|error` — staleness checking mode (default `off`)
296
- - `--tracked-globs x,y,z` — globs for files that should be covered (applies to `list` staleness only)
297
- - `--help` — show usage
200
+ ## Troubleshooting
298
201
 
299
- Select a nonstandard resultset path:
202
+ - **"command not found"** - See [Installation Guide](docs/INSTALLATION.md#path-configuration)
203
+ - **"cannot load such file -- mcp"** - Upgrade to Ruby >= 3.2
204
+ - **"Could not find .resultset.json"** - Run tests to generate coverage. See the [Configuring the Resultset](#configuring-the-resultset) section for more details.
205
+ - **MCP server won't connect** - Check PATH and Ruby version in [MCP Troubleshooting](docs/MCP_INTEGRATION.md#troubleshooting)
206
+ - **Codex on macOS with RVM** - Codex's macOS sandbox disallows `/bin/ps`, which RVM needs. Use a different version manager (rbenv, chruby) or run outside the Codex environment.
300
207
 
301
- ```sh
302
- simplecov-mcp --cli --resultset build/coverage/.resultset.json
303
- # or
304
- SIMPLECOV_RESULTSET=build/coverage/.resultset.json simplecov-mcp --cli
305
- ```
208
+ For more detailed help, see the full [Troubleshooting Guide](docs/TROUBLESHOOTING.md).
306
209
 
307
- You can also pass a directory that contains `.resultset.json` (common when the file lives in a `coverage/` folder):
210
+ ## Development
308
211
 
309
212
  ```sh
310
- simplecov-mcp --cli --resultset coverage
311
- # or via env
312
- SIMPLECOV_RESULTSET=coverage simplecov-mcp --cli
313
- ```
314
-
315
- Forces CLI mode:
213
+ # Clone and setup
214
+ git clone https://github.com/keithrbennett/simplecov-mcp.git
215
+ cd simplecov-mcp
216
+ bundle install
316
217
 
317
- ```sh
318
- simplecov-mcp --cli
319
- # or
320
- SIMPLECOV_MCP_CLI=1 simplecov-mcp
321
- ```
218
+ # Run tests
219
+ bundle exec rspec
322
220
 
323
- Example output:
221
+ # Test locally
222
+ ruby -Ilib exe/simplecov-mcp
324
223
 
325
- ```text
326
- ┌───────────────────────────┬──────────┬──────────┬────────┬───┐
327
- File │ % │ Covered │ Total │ ! │
328
- ├───────────────────────────┼──────────┼──────────┼────────┼───┤
329
- │ spec/user_spec.rb │ 85.71 │ 12 │ 14 │ │
330
- │ lib/models/user.rb │ 92.31 │ 12 │ 13 │ ! │
331
- │ lib/services/auth.rb │ 100.00 │ 8 │ 8 │ │
332
- └───────────────────────────┴──────────┴──────────┴────────┴───┘
224
+ # Build and install
225
+ gem build simplecov-mcp.gemspec
226
+ gem install simplecov-mcp-*.gem
333
227
  ```
334
228
 
335
- Files are sorted by percentage (ascending), then by path.
336
-
337
- ### MCP Server Mode
229
+ See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for more *(coming soon)*.
338
230
 
339
- When stdin has data (e.g., from an MCP client), the program runs as an MCP server over stdio.
231
+ ## SimpleCov Dependency
340
232
 
341
- Available tools:
233
+ `simplecov-mcp` declares a runtime dependency on `simplecov` (>= 0.21) to support multi-suite merging using SimpleCov's combine helpers. The dependency is lazy-loaded only when needed, ensuring fast startup for single-suite projects.
342
234
 
343
- - `coverage_raw_tool(path, root=".", resultset=nil, stale='off')`
344
- - `coverage_summary_tool(path, root=".", resultset=nil, stale='off')`
345
- - `uncovered_lines_tool(path, root=".", resultset=nil, stale='off')`
346
- - `coverage_detailed_tool(path, root=".", resultset=nil, stale='off')`
347
- - `all_files_coverage_tool(root=".", resultset=nil, stale='off', tracked_globs=nil)`
348
- - Returns `{ files: [{"file","covered","total","percentage","stale"}, ...] }` where `stale` is a boolean.
349
- - `version_tool()` — returns version information
235
+ ## Contributing
350
236
 
351
- Notes:
237
+ Contributions are welcome! Please:
352
238
 
353
- - `resultset` lets clients pass a nonstandard path to `.resultset.json` directly (absolute or relative to `root`). It may be:
354
- - a file path to `.resultset.json`, or
355
- - a directory path containing `.resultset.json` (e.g., `coverage/`).
356
- - If `resultset` is omitted, the server checks `SIMPLECOV_RESULTSET`, then searches `.resultset.json`, `coverage/.resultset.json`, `tmp/.resultset.json` in that order.
357
- - `stale` controls staleness checking per call (`off` or `error`).
358
- - For `all_files_coverage`, `tracked_globs` detects new project files missing from coverage, and the tool also flags covered files that are newer than the coverage timestamp or present in coverage but deleted in the project.
239
+ 1. Fork the repository
240
+ 2. Create a feature branch
241
+ 3. Add tests for new functionality
242
+ 4. Ensure all tests pass (`bundle exec rspec`)
243
+ 5. Submit a pull request
359
244
 
360
- Example (manual - note single-line JSON-RPC format):
361
-
362
- ```sh
363
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/foo.rb"}}}' | simplecov-mcp
364
- ```
365
-
366
- With an explicit resultset path:
245
+ ## License
367
246
 
368
- ```sh
369
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/foo.rb","resultset":"build/coverage/.resultset.json"}}}' | simplecov-mcp
370
- ```
247
+ MIT License - see [LICENSE](LICENSE) file for details.
371
248
 
372
- With a resultset directory:
249
+ ## Links
373
250
 
374
- ```sh
375
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/foo.rb","resultset":"coverage"}}}' | simplecov-mcp
376
- ```
251
+ - **GitHub:** https://github.com/keithrbennett/simplecov-mcp
252
+ - **RubyGems:** https://rubygems.org/gems/simplecov-mcp
253
+ - **Issues:** https://github.com/keithrbennett/simplecov-mcp/issues
254
+ - **Changelog:** [RELEASE_NOTES.md](RELEASE_NOTES.md)
377
255
 
378
- CLI vs MCP summary:
256
+ ## Related Files
379
257
 
380
- - CLI: use subcommands. Pass `--resultset PATH` or set `SIMPLECOV_RESULTSET`.
381
- - MCP: pass `resultset` in tool arguments, or set `SIMPLECOV_RESULTSET`.
258
+ - [CLAUDE.md](CLAUDE.md) - Claude Code integration notes
259
+ - [AGENTS.md](AGENTS.md) - AI agent configuration
260
+ - [GEMINI.md](GEMINI.md) - Gemini-specific guidance
382
261
 
383
- ## Troubleshooting
262
+ ---
384
263
 
385
- - MCP client fails to start or times out
386
- - Likely cause: launching `simplecov-mcp` with an older Ruby that cannot load the `mcp` gem. This gem requires Ruby >= 3.2.
387
- - Check the Ruby your MCP client uses: run `ruby -v` in the same environment your client inherits; ensure it reports 3.2+.
388
- - Fix PATH or select a newer Ruby via rbenv/rvm/asdf, then retry. You can configure your MCP client to point to the shim/binary for that Ruby version. For example:
389
- - rbenv shim: `~/.rbenv/shims/simplecov-mcp`
390
- - asdf shim: `~/.asdf/shims/simplecov-mcp`
391
- - RVM wrapper: `/Users/you/.rvm/wrappers/ruby-3.3.0/simplecov-mcp` (adjust version)
392
- - Codex CLI example (`~/.codex/config.toml`):
393
- ```toml
394
- # Use the Ruby 3.2+ shim for the MCP server
395
- [tools.simplecov_mcp]
396
- command = "/Users/you/.rbenv/shims/simplecov-mcp"
397
- cwd = "/path/to/your/project"
398
- ```
399
- - Validate manually: `simplecov-mcp --cli` (or from this repo: `ruby -Ilib exe/simplecov-mcp --cli`). If you see the coverage table, the binary starts correctly.
400
- - On failures, check `~/simplecov_mcp.log` for details.
401
-
402
- ### Notes
403
-
404
- - Library entrypoint: `require "simple_cov_mcp"` (also `simplecov_mcp`). Legacy `simple_cov/mcp` is supported.
405
- - Programmatic run: `SimpleCovMcp.run(ARGV)`
406
- - Staleness checks: pass `staleness: 'error'` to `CoverageModel` (or use CLI `--stale error`) to
407
- raise if source mtimes are newer than coverage or line counts mismatch. Use
408
- `--tracked-globs` (CLI) or `tracked_globs` (API/MCP) to flag new files.
409
- - Logs basic diagnostics to `~/simplecov_mcp.log`.
410
-
411
- ## Executables and PATH
412
-
413
- To run `simplecov-mcp` globally, your PATH must include where Ruby installs executables.
414
-
415
- - Version managers
416
- - RVM, rbenv, asdf, chruby typically add the right bin/shim directories to PATH.
417
- - Ensure your shell is initialized (e.g., rbenv init, asdf reshim ruby after installs).
418
- - Without a manager
419
- - Add the gem bin dir to PATH: see it with `gem env` (look for "EXECUTABLE DIRECTORY") or `ruby -e 'puts Gem.bindir'`.
420
- - Example: `export PATH="$HOME/.gem/ruby/3.2.0/bin:$PATH"` (adjust version).
421
- - Alternatives
422
- - Use Bundler: `bundle exec simplecov-mcp` with cwd set to your project.
423
- - Symlink the repo executable into a bin on your PATH; the script resolves its lib/ via realpath.
424
- - Or configure Codex to run the executable by filename (`simplecov-mcp`) and inherit the current workspace as cwd.
264
+ ## Next Steps
425
265
 
426
- ## Development
266
+ 📦 **Install:** `gem install simplecov-mcp`
427
267
 
428
- Standard Ruby gem structure. After cloning:
268
+ 📖 **Read:** [CLI Usage Guide](docs/CLI_USAGE.md) | [MCP Integration](docs/MCP_INTEGRATION.md)
429
269
 
430
- ```sh
431
- bundle install
432
- ruby -Ilib exe/simplecov-mcp --cli
433
- ```
434
-
435
- Run tests with coverage (SimpleCov writes to `coverage/`):
436
-
437
- ```sh
438
- bundle exec rspec
439
- # open coverage/index.html for HTML report, or run exe/simplecov-mcp for table summary
440
- ```
441
-
442
- ## License
270
+ 🐛 **Report issues:** [GitHub Issues](https://github.com/keithrbennett/simplecov-mcp/issues)
443
271
 
444
- MIT
272
+ ⭐ **Star the repo** if you find it useful!