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.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +173 -356
- data/docs/ADVANCED_USAGE.md +967 -0
- data/docs/ARCHITECTURE.md +79 -0
- data/docs/BRANCH_ONLY_COVERAGE.md +81 -0
- data/docs/CLI_USAGE.md +637 -0
- data/docs/DEVELOPMENT.md +82 -0
- data/docs/ERROR_HANDLING.md +93 -0
- data/docs/EXAMPLES.md +430 -0
- data/docs/INSTALLATION.md +352 -0
- data/docs/LIBRARY_API.md +635 -0
- data/docs/MCP_INTEGRATION.md +488 -0
- data/docs/TROUBLESHOOTING.md +276 -0
- data/docs/arch-decisions/001-x-arch-decision.md +93 -0
- data/docs/arch-decisions/002-x-arch-decision.md +157 -0
- data/docs/arch-decisions/003-x-arch-decision.md +163 -0
- data/docs/arch-decisions/004-x-arch-decision.md +199 -0
- data/docs/arch-decisions/005-x-arch-decision.md +187 -0
- data/docs/arch-decisions/README.md +60 -0
- data/docs/presentations/simplecov-mcp-presentation.md +249 -0
- data/exe/simplecov-mcp +4 -4
- data/lib/simplecov_mcp/app_context.rb +26 -0
- data/lib/simplecov_mcp/base_tool.rb +74 -0
- data/lib/simplecov_mcp/cli.rb +234 -0
- data/lib/simplecov_mcp/cli_config.rb +56 -0
- data/lib/simplecov_mcp/commands/base_command.rb +78 -0
- data/lib/simplecov_mcp/commands/command_factory.rb +39 -0
- data/lib/simplecov_mcp/commands/detailed_command.rb +24 -0
- data/lib/simplecov_mcp/commands/list_command.rb +13 -0
- data/lib/simplecov_mcp/commands/raw_command.rb +22 -0
- data/lib/simplecov_mcp/commands/summary_command.rb +24 -0
- data/lib/simplecov_mcp/commands/uncovered_command.rb +26 -0
- data/lib/simplecov_mcp/commands/version_command.rb +18 -0
- data/lib/simplecov_mcp/constants.rb +22 -0
- data/lib/simplecov_mcp/error_handler.rb +124 -0
- data/lib/simplecov_mcp/error_handler_factory.rb +31 -0
- data/lib/simplecov_mcp/errors.rb +179 -0
- data/lib/simplecov_mcp/formatters/source_formatter.rb +148 -0
- data/lib/simplecov_mcp/mcp_server.rb +40 -0
- data/lib/simplecov_mcp/mode_detector.rb +55 -0
- data/lib/simplecov_mcp/model.rb +300 -0
- data/lib/simplecov_mcp/option_normalizers.rb +92 -0
- data/lib/simplecov_mcp/option_parser_builder.rb +134 -0
- data/lib/simplecov_mcp/option_parsers/env_options_parser.rb +50 -0
- data/lib/simplecov_mcp/option_parsers/error_helper.rb +109 -0
- data/lib/simplecov_mcp/path_relativizer.rb +61 -0
- data/lib/simplecov_mcp/presenters/base_coverage_presenter.rb +44 -0
- data/lib/simplecov_mcp/presenters/coverage_detailed_presenter.rb +16 -0
- data/lib/simplecov_mcp/presenters/coverage_raw_presenter.rb +16 -0
- data/lib/simplecov_mcp/presenters/coverage_summary_presenter.rb +16 -0
- data/lib/simplecov_mcp/presenters/coverage_uncovered_presenter.rb +16 -0
- data/lib/simplecov_mcp/presenters/project_coverage_presenter.rb +52 -0
- data/lib/simplecov_mcp/resolvers/coverage_line_resolver.rb +126 -0
- data/lib/simplecov_mcp/resolvers/resolver_factory.rb +28 -0
- data/lib/simplecov_mcp/resolvers/resultset_path_resolver.rb +78 -0
- data/lib/simplecov_mcp/resultset_loader.rb +136 -0
- data/lib/simplecov_mcp/staleness_checker.rb +243 -0
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/all_files_coverage_tool.rb +31 -13
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/coverage_detailed_tool.rb +7 -7
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/coverage_raw_tool.rb +7 -7
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/coverage_summary_tool.rb +7 -7
- data/lib/simplecov_mcp/tools/coverage_table_tool.rb +90 -0
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/help_tool.rb +13 -4
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/uncovered_lines_tool.rb +7 -7
- data/lib/{simple_cov_mcp → simplecov_mcp}/tools/version_tool.rb +11 -3
- data/lib/simplecov_mcp/util.rb +82 -0
- data/lib/{simple_cov_mcp → simplecov_mcp}/version.rb +1 -1
- data/lib/simplecov_mcp.rb +144 -2
- data/spec/MCP_INTEGRATION_TESTS_README.md +111 -0
- data/spec/TIMESTAMPS.md +48 -0
- data/spec/all_files_coverage_tool_spec.rb +29 -25
- data/spec/base_tool_spec.rb +11 -10
- data/spec/cli/show_default_report_spec.rb +33 -0
- data/spec/cli_config_spec.rb +137 -0
- data/spec/cli_enumerated_options_spec.rb +68 -0
- data/spec/cli_error_spec.rb +105 -47
- data/spec/cli_source_spec.rb +82 -23
- data/spec/cli_spec.rb +140 -5
- data/spec/cli_success_predicate_spec.rb +141 -0
- data/spec/cli_table_spec.rb +1 -1
- data/spec/cli_usage_spec.rb +10 -26
- data/spec/commands/base_command_spec.rb +187 -0
- data/spec/commands/command_factory_spec.rb +72 -0
- data/spec/commands/detailed_command_spec.rb +48 -0
- data/spec/commands/raw_command_spec.rb +46 -0
- data/spec/commands/summary_command_spec.rb +47 -0
- data/spec/commands/uncovered_command_spec.rb +49 -0
- data/spec/constants_spec.rb +61 -0
- data/spec/coverage_table_tool_spec.rb +17 -33
- data/spec/error_handler_spec.rb +22 -13
- data/spec/error_mode_spec.rb +143 -0
- data/spec/errors_edge_cases_spec.rb +239 -0
- data/spec/errors_stale_spec.rb +2 -2
- data/spec/file_based_mcp_tools_spec.rb +99 -0
- data/spec/fixtures/project1/lib/bar.rb +0 -1
- data/spec/fixtures/project1/lib/foo.rb +0 -1
- data/spec/help_tool_spec.rb +11 -17
- data/spec/integration_spec.rb +845 -0
- data/spec/logging_fallback_spec.rb +128 -0
- data/spec/mcp_logging_spec.rb +44 -0
- data/spec/mcp_server_integration_spec.rb +23 -0
- data/spec/mcp_server_spec.rb +15 -4
- data/spec/mode_detector_spec.rb +148 -0
- data/spec/model_error_handling_spec.rb +210 -0
- data/spec/model_staleness_spec.rb +40 -10
- data/spec/option_normalizers_spec.rb +204 -0
- data/spec/option_parsers/env_options_parser_spec.rb +233 -0
- data/spec/option_parsers/error_helper_spec.rb +222 -0
- data/spec/path_relativizer_spec.rb +83 -0
- data/spec/presenters/coverage_detailed_presenter_spec.rb +19 -0
- data/spec/presenters/coverage_raw_presenter_spec.rb +15 -0
- data/spec/presenters/coverage_summary_presenter_spec.rb +15 -0
- data/spec/presenters/coverage_uncovered_presenter_spec.rb +16 -0
- data/spec/presenters/project_coverage_presenter_spec.rb +86 -0
- data/spec/resolvers/coverage_line_resolver_spec.rb +57 -0
- data/spec/resolvers/resolver_factory_spec.rb +61 -0
- data/spec/resolvers/resultset_path_resolver_spec.rb +55 -0
- data/spec/resultset_loader_spec.rb +167 -0
- data/spec/shared_examples/README.md +115 -0
- data/spec/shared_examples/coverage_presenter_examples.rb +66 -0
- data/spec/shared_examples/file_based_mcp_tools.rb +174 -0
- data/spec/shared_examples/mcp_tool_text_json_response.rb +16 -0
- data/spec/simple_cov_mcp_module_spec.rb +16 -0
- data/spec/simplecov_mcp_model_spec.rb +340 -9
- data/spec/simplecov_mcp_opts_spec.rb +182 -0
- data/spec/spec_helper.rb +147 -4
- data/spec/staleness_checker_spec.rb +373 -0
- data/spec/staleness_more_spec.rb +16 -13
- data/spec/support/mcp_runner.rb +64 -0
- data/spec/tools_error_handling_spec.rb +144 -0
- data/spec/util_spec.rb +109 -34
- data/spec/version_spec.rb +117 -9
- data/spec/version_tool_spec.rb +131 -10
- metadata +120 -63
- data/lib/simple_cov/mcp.rb +0 -9
- data/lib/simple_cov_mcp/base_tool.rb +0 -70
- data/lib/simple_cov_mcp/cli.rb +0 -390
- data/lib/simple_cov_mcp/error_handler.rb +0 -131
- data/lib/simple_cov_mcp/error_handler_factory.rb +0 -38
- data/lib/simple_cov_mcp/errors.rb +0 -176
- data/lib/simple_cov_mcp/mcp_server.rb +0 -30
- data/lib/simple_cov_mcp/model.rb +0 -104
- data/lib/simple_cov_mcp/staleness_checker.rb +0 -125
- data/lib/simple_cov_mcp/tools/coverage_table_tool.rb +0 -61
- data/lib/simple_cov_mcp/util.rb +0 -122
- data/lib/simple_cov_mcp.rb +0 -102
- data/spec/coverage_detailed_tool_spec.rb +0 -36
- data/spec/coverage_raw_tool_spec.rb +0 -32
- data/spec/coverage_summary_tool_spec.rb +0 -39
- data/spec/legacy_shim_spec.rb +0 -13
- data/spec/uncovered_lines_tool_spec.rb +0 -33
data/README.md
CHANGED
@@ -1,455 +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
|
-
|
5
|
+
[](https://badge.fury.io/rb/simplecov-mcp)
|
6
6
|
|
7
|
-
|
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
|
-
|
9
|
+
**simplecov-mcp** makes SimpleCov coverage data queryable and actionable through three interfaces:
|
11
10
|
|
12
|
-
- MCP server
|
13
|
-
|
14
|
-
-
|
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
|
-
|
15
|
+
Works with any SimpleCov-generated `.resultset.json` file—no runtime dependency on your test suite.
|
21
16
|
|
22
|
-
|
17
|
+
### Key capabilities
|
23
18
|
|
24
|
-
|
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
|
-
|
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
|
-
|
41
|
+
### Generate Coverage Data
|
33
42
|
|
34
|
-
|
43
|
+
```sh
|
44
|
+
# Run your tests with SimpleCov enabled
|
45
|
+
bundle exec rspec # or your test command
|
35
46
|
|
36
|
-
|
47
|
+
# Verify coverage was generated
|
48
|
+
ls coverage/.resultset.json
|
49
|
+
```
|
37
50
|
|
38
|
-
|
51
|
+
### Basic Usage
|
39
52
|
|
40
|
-
|
53
|
+
**CLI - View Coverage Table:**
|
54
|
+
```sh
|
55
|
+
simplecov-mcp
|
56
|
+
```
|
41
57
|
|
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
|
+
```
|
63
|
+
|
64
|
+
**Ruby Library:**
|
42
65
|
```ruby
|
43
|
-
require "
|
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
|
-
# => [
|
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
|
+
# => [{ "file" => "lib/simplecov_mcp/model.rb", "covered" => 114, "total" => 118, "percentage" => 96.61, "stale" => false }, ...]
|
70
71
|
|
71
|
-
|
72
|
-
# => {
|
73
|
-
|
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
|
-
|
79
|
-
|
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:
|
76
|
+
**MCP Server:**
|
77
|
+
See [MCP Integration Guide](docs/MCP_INTEGRATION.md) for AI assistant setup.
|
82
78
|
|
83
|
-
|
79
|
+
## Key Features
|
84
80
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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.
|
92
88
|
|
93
|
-
|
89
|
+
## Multi-Suite Coverage Merging
|
94
90
|
|
95
|
-
|
91
|
+
### How It Works
|
96
92
|
|
97
|
-
|
98
|
-
- Human-readable strings (e.g., the table and version) return as `type: "text"`.
|
99
|
-
- Errors return as `type: "text"` with a friendly message.
|
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.
|
100
94
|
|
101
|
-
|
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.
|
102
96
|
|
103
|
-
|
104
|
-
- a file path to `.resultset.json`, or
|
105
|
-
- a directory containing `.resultset.json` (e.g., `coverage/`).
|
106
|
-
- If `resultset:` is omitted, resolution follows:
|
107
|
-
1) `ENV["SIMPLECOV_RESULTSET"]` (file or directory), then
|
108
|
-
2) `.resultset.json`, 3) `coverage/.resultset.json`, 4) `tmp/.resultset.json` under `root`.
|
97
|
+
### Current Limitations
|
109
98
|
|
110
|
-
|
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.
|
111
100
|
|
112
|
-
|
113
|
-
1) exact absolute path,
|
114
|
-
2) the path without the current working directory prefix,
|
115
|
-
3) filename (basename) match as a last resort.
|
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.
|
116
102
|
|
117
|
-
|
103
|
+
## Documentation
|
118
104
|
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
122
109
|
|
123
|
-
|
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
|
124
114
|
|
125
|
-
|
115
|
+
**Reference:**
|
116
|
+
- [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues
|
117
|
+
- [Development](docs/DEVELOPMENT.md) - Contributing guide
|
126
118
|
|
127
|
-
|
119
|
+
## Requirements
|
128
120
|
|
129
|
-
|
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`)
|
130
125
|
|
131
|
-
|
132
|
-
* the simplest coverage omissions to address
|
133
|
-
* analyze the risk of the current state of coverage
|
134
|
-
* propose a plan of action (if any) to improve coverage state
|
126
|
+
## Configuring the Resultset
|
135
127
|
|
136
|
-
|
128
|
+
`simplecov-mcp` automatically searches for `.resultset.json` in standard locations (`coverage/.resultset.json`, `.resultset.json`, `tmp/.resultset.json`). For non-standard locations:
|
137
129
|
|
130
|
+
```sh
|
131
|
+
# Command-line option (highest priority)
|
132
|
+
simplecov-mcp --resultset /path/to/your/coverage
|
138
133
|
|
139
|
-
|
140
|
-
|
141
|
-
This tool provides different error handling behavior depending on how it's used:
|
142
|
-
|
143
|
-
### CLI Mode
|
144
|
-
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"
|
145
136
|
|
146
|
-
|
147
|
-
|
148
|
-
|
137
|
+
# MCP server configuration
|
138
|
+
# Add to your MCP client config:
|
139
|
+
# "args": ["--resultset", "/path/to/your/coverage"]
|
149
140
|
```
|
150
141
|
|
151
|
-
|
142
|
+
See [CLI Usage Guide](docs/CLI_USAGE.md#-r---resultset-path) for complete details.
|
152
143
|
|
153
|
-
### Library Mode
|
154
|
-
When used as a Ruby library, errors are raised as custom exception classes that can be caught and handled:
|
155
|
-
|
156
|
-
```ruby
|
157
|
-
begin
|
158
|
-
SimpleCovMcp.run_as_library(['summary', 'missing.rb'])
|
159
|
-
rescue SimpleCovMcp::FileError => e
|
160
|
-
puts "Handled gracefully: #{e.user_friendly_message}"
|
161
|
-
end
|
162
|
-
```
|
163
144
|
|
164
|
-
Available exception classes:
|
165
|
-
- `SimpleCovMcp::Error` - Base error class
|
166
|
-
- `SimpleCovMcp::FileError` - File not found or access issues
|
167
|
-
- `SimpleCovMcp::CoverageDataError` - Invalid or missing coverage data
|
168
|
-
- `SimpleCovMcp::ConfigurationError` - Configuration problems
|
169
|
-
- `SimpleCovMcp::UsageError` - Command usage errors
|
170
145
|
|
171
|
-
|
172
|
-
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
|
173
147
|
|
174
|
-
|
175
|
-
- **Clean error messages** - User-friendly messages are returned to the client (no stack traces unless `SIMPLECOV_MCP_DEBUG=1`)
|
176
|
-
- **Structured responses** - Errors are returned as proper MCP tool responses, not exceptions
|
148
|
+
### Find Coverage Gaps
|
177
149
|
|
178
|
-
|
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
|
179
156
|
|
180
|
-
|
181
|
-
|
157
|
+
# Specific directory
|
158
|
+
simplecov-mcp list --tracked-globs "lib/simplecov_mcp/tools/**/*.rb"
|
182
159
|
|
183
|
-
|
184
|
-
|
185
|
-
SimpleCovMcp.run_as_library(['summary', 'file.rb'])
|
186
|
-
|
187
|
-
# Custom error handler with logging enabled
|
188
|
-
handler = SimpleCovMcp::ErrorHandler.new(
|
189
|
-
log_errors: true, # Enable logging for library usage
|
190
|
-
show_stack_traces: false # Clean error messages
|
191
|
-
)
|
192
|
-
SimpleCovMcp.run_as_library(argv, error_handler: handler)
|
193
|
-
|
194
|
-
# Or configure globally for MCP tools
|
195
|
-
SimpleCovMcp.configure_error_handling do |handler|
|
196
|
-
handler.log_errors = true
|
197
|
-
handler.show_stack_traces = true # For debugging
|
198
|
-
end
|
160
|
+
# Export for analysis
|
161
|
+
simplecov-mcp list --json > coverage-report.json
|
199
162
|
```
|
200
163
|
|
201
|
-
###
|
202
|
-
|
203
|
-
- Missing resultset: `SimpleCov::Mcp::CovUtil.find_resultset` raises with guidance to run tests or set `SIMPLECOV_RESULTSET`.
|
204
|
-
- Missing file coverage: lookups raise `"No coverage entry found for <path>"`.
|
205
|
-
|
206
|
-
Example: fail CI if a file has uncovered lines
|
164
|
+
### CI/CD Integration
|
207
165
|
|
208
|
-
```
|
209
|
-
|
210
|
-
|
211
|
-
model = SimpleCovMcp::CoverageModel.new(root: Dir.pwd)
|
212
|
-
res = model.uncovered_for("lib/foo.rb")
|
213
|
-
if res['uncovered'].any?
|
214
|
-
warn "Uncovered lines in lib/foo.rb: #{res['uncovered'].join(", ")}"
|
215
|
-
exit 1
|
216
|
-
end
|
217
|
-
```
|
218
|
-
|
219
|
-
Example: enforce a project-wide minimum percentage
|
166
|
+
```sh
|
167
|
+
# Fail build if coverage is stale
|
168
|
+
simplecov-mcp --stale error || exit 1
|
220
169
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
threshold = 90.0
|
225
|
-
min = model.all_files.map { |r| r['percentage'] }.min || 100.0
|
226
|
-
if min < threshold
|
227
|
-
warn "Min coverage %.2f%% is below threshold %.2f%%" % [min, threshold]
|
228
|
-
exit 1
|
229
|
-
end
|
170
|
+
# Generate coverage report artifact
|
171
|
+
simplecov-mcp list --json > artifacts/coverage.json
|
230
172
|
```
|
231
173
|
|
232
|
-
|
233
|
-
|
234
|
-
- Consider the following public and stable under SemVer:
|
235
|
-
- `SimpleCovMcp::CoverageModel.new(root:, resultset:, staleness: 'off', tracked_globs: nil)`
|
236
|
-
- `#raw_for(path)`, `#summary_for(path)`, `#uncovered_for(path)`, `#detailed_for(path)`, `#all_files(sort_order:)`
|
237
|
-
- Return shapes shown above (keys and value types). For `all_files`, each row also includes `'stale' => true|false`.
|
238
|
-
- CLI (`SimpleCovMcp.run(argv)`) and MCP tools remain stable but are separate surfaces.
|
239
|
-
- Internal helpers under `SimpleCovMcp::CovUtil` may change; prefer `CoverageModel` unless you need low-level access.
|
240
|
-
|
241
|
-
### Resultset Location
|
242
|
-
|
243
|
-
- Defaults (search order):
|
244
|
-
1. `.resultset.json`
|
245
|
-
2. `coverage/.resultset.json`
|
246
|
-
3. `tmp/.resultset.json`
|
247
|
-
- Override via CLI: `--resultset PATH` (PATH may be the file itself or a directory containing `.resultset.json`).
|
248
|
-
- 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.
|
249
|
-
|
250
|
-
### CLI Mode
|
251
|
-
|
252
|
-
### Stale Coverage Errors
|
174
|
+
### Investigate Specific Files
|
253
175
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
- Enable per instance: `SimpleCovMcp::CoverageModel.new(staleness: 'error')`
|
259
|
-
|
260
|
-
The error message is detailed and includes:
|
176
|
+
```sh
|
177
|
+
# Quick summary
|
178
|
+
simplecov-mcp summary lib/simplecov_mcp/model.rb
|
261
179
|
|
262
|
-
|
263
|
-
-
|
264
|
-
- The absolute path to the `.resultset.json` used
|
180
|
+
# See uncovered lines
|
181
|
+
simplecov-mcp uncovered lib/simplecov_mcp/cli.rb
|
265
182
|
|
266
|
-
|
183
|
+
# View in context
|
184
|
+
simplecov-mcp uncovered lib/simplecov_mcp/cli.rb --source=uncovered --source-context 3
|
267
185
|
|
268
|
-
|
269
|
-
|
270
|
-
File - time: 2025-09-16T14:03:22Z (local 2025-09-16T07:03:22-07:00), lines: 226
|
271
|
-
Coverage - time: 2025-09-15T21:11:09Z (local 2025-09-15T14:11:09-07:00), lines: 220
|
272
|
-
Delta - file is +123s newer than coverage
|
273
|
-
Resultset - /path/to/your/project/coverage/.resultset.json
|
186
|
+
# Detailed hit counts
|
187
|
+
simplecov-mcp detailed lib/simplecov_mcp/util.rb
|
274
188
|
```
|
275
189
|
|
276
|
-
|
190
|
+
## Commands and Tools
|
277
191
|
|
278
|
-
|
279
|
-
simplecov-mcp # same as 'list'
|
280
|
-
```
|
192
|
+
**CLI Subcommands:** `list`, `summary`, `uncovered`, `detailed`, `raw`, `version`
|
281
193
|
|
282
|
-
|
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`
|
283
195
|
|
284
|
-
|
285
|
-
-
|
286
|
-
-
|
287
|
-
- `uncovered <path>` — show uncovered lines and summary
|
288
|
-
- `detailed <path>` — show per-line rows with hits and covered
|
289
|
-
- `version` — show version information
|
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
|
290
199
|
|
291
|
-
|
200
|
+
## Troubleshooting
|
292
201
|
|
293
|
-
-
|
294
|
-
-
|
295
|
-
-
|
296
|
-
-
|
297
|
-
-
|
298
|
-
- `--source[=MODE]` — include source text for `summary`, `uncovered`, `detailed` (MODE: `full` or `uncovered`; default `full`)
|
299
|
-
- `--source-context N` — for `--source=uncovered`, lines of context (default 2)
|
300
|
-
- `--color` / `--no-color` — enable/disable ANSI colors in source output
|
301
|
-
- `--stale off|error` — staleness checking mode (default `off`)
|
302
|
-
- `--tracked-globs x,y,z` — globs for files that should be covered (applies to `list` staleness only)
|
303
|
-
- `--help` — show usage
|
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.
|
304
207
|
|
305
|
-
|
208
|
+
For more detailed help, see the full [Troubleshooting Guide](docs/TROUBLESHOOTING.md).
|
306
209
|
|
307
|
-
|
308
|
-
simplecov-mcp --cli --resultset build/coverage/.resultset.json
|
309
|
-
# or
|
310
|
-
SIMPLECOV_RESULTSET=build/coverage/.resultset.json simplecov-mcp --cli
|
311
|
-
```
|
312
|
-
|
313
|
-
You can also pass a directory that contains `.resultset.json` (common when the file lives in a `coverage/` folder):
|
210
|
+
## Development
|
314
211
|
|
315
212
|
```sh
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
Forces CLI mode:
|
213
|
+
# Clone and setup
|
214
|
+
git clone https://github.com/keithrbennett/simplecov-mcp.git
|
215
|
+
cd simplecov-mcp
|
216
|
+
bundle install
|
322
217
|
|
323
|
-
|
324
|
-
|
325
|
-
# or
|
326
|
-
SIMPLECOV_MCP_CLI=1 simplecov-mcp
|
327
|
-
```
|
218
|
+
# Run tests
|
219
|
+
bundle exec rspec
|
328
220
|
|
329
|
-
|
221
|
+
# Test locally
|
222
|
+
ruby -Ilib exe/simplecov-mcp
|
330
223
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
├───────────────────────────┼──────────┼──────────┼────────┼───┤
|
335
|
-
│ spec/user_spec.rb │ 85.71 │ 12 │ 14 │ │
|
336
|
-
│ lib/models/user.rb │ 92.31 │ 12 │ 13 │ ! │
|
337
|
-
│ lib/services/auth.rb │ 100.00 │ 8 │ 8 │ │
|
338
|
-
└───────────────────────────┴──────────┴──────────┴────────┴───┘
|
224
|
+
# Build and install
|
225
|
+
gem build simplecov-mcp.gemspec
|
226
|
+
gem install simplecov-mcp-*.gem
|
339
227
|
```
|
340
228
|
|
341
|
-
|
342
|
-
|
343
|
-
### MCP Server Mode
|
344
|
-
|
345
|
-
When stdin has data (e.g., from an MCP client), the program runs as an MCP server over stdio.
|
346
|
-
|
347
|
-
Available tools:
|
348
|
-
|
349
|
-
- `coverage_raw_tool(path, root=".", resultset=nil, stale='off')`
|
350
|
-
- `coverage_summary_tool(path, root=".", resultset=nil, stale='off')`
|
351
|
-
- `uncovered_lines_tool(path, root=".", resultset=nil, stale='off')`
|
352
|
-
- `coverage_detailed_tool(path, root=".", resultset=nil, stale='off')`
|
353
|
-
- `all_files_coverage_tool(root=".", resultset=nil, stale='off', tracked_globs=nil)`
|
354
|
-
- Returns `{ files: [{"file","covered","total","percentage","stale"}, ...] }` where `stale` is a boolean.
|
355
|
-
- `version_tool()` — returns version information
|
229
|
+
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for more *(coming soon)*.
|
356
230
|
|
357
|
-
|
231
|
+
## SimpleCov Dependency
|
358
232
|
|
359
|
-
-
|
360
|
-
- `coverage_table_tool` and `version_tool` return `{ "type": "text", "text": "..." }`.
|
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.
|
361
234
|
|
362
|
-
|
235
|
+
## Contributing
|
363
236
|
|
364
|
-
|
365
|
-
- a file path to `.resultset.json`, or
|
366
|
-
- a directory path containing `.resultset.json` (e.g., `coverage/`).
|
367
|
-
- If `resultset` is omitted, the server checks `SIMPLECOV_RESULTSET`, then searches `.resultset.json`, `coverage/.resultset.json`, `tmp/.resultset.json` in that order.
|
368
|
-
- `stale` controls staleness checking per call (`off` or `error`).
|
369
|
-
- 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.
|
237
|
+
Contributions are welcome! Please:
|
370
238
|
|
371
|
-
|
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
|
372
244
|
|
373
|
-
|
374
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/foo.rb"}}}' | simplecov-mcp
|
375
|
-
```
|
376
|
-
|
377
|
-
With an explicit resultset path:
|
378
|
-
|
379
|
-
```sh
|
380
|
-
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
|
381
|
-
```
|
382
|
-
|
383
|
-
With a resultset directory:
|
384
|
-
|
385
|
-
```sh
|
386
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/foo.rb","resultset":"coverage"}}}' | simplecov-mcp
|
387
|
-
```
|
245
|
+
## License
|
388
246
|
|
389
|
-
|
247
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
390
248
|
|
391
|
-
|
392
|
-
- MCP: pass `resultset` in tool arguments, or set `SIMPLECOV_RESULTSET`.
|
249
|
+
## Links
|
393
250
|
|
394
|
-
|
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)
|
395
255
|
|
396
|
-
|
397
|
-
- Likely cause: launching `simplecov-mcp` with an older Ruby that cannot load the `mcp` gem. This gem requires Ruby >= 3.2.
|
398
|
-
- Check the Ruby your MCP client uses: run `ruby -v` in the same environment your client inherits; ensure it reports 3.2+.
|
399
|
-
- 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:
|
400
|
-
- rbenv shim: `~/.rbenv/shims/simplecov-mcp`
|
401
|
-
- asdf shim: `~/.asdf/shims/simplecov-mcp`
|
402
|
-
- RVM wrapper: `/Users/you/.rvm/wrappers/ruby-3.3.0/simplecov-mcp` (adjust version)
|
403
|
-
- Codex CLI example (`~/.codex/config.toml`):
|
404
|
-
```toml
|
405
|
-
# Use the Ruby 3.2+ shim for the MCP server
|
406
|
-
[tools.simplecov_mcp]
|
407
|
-
command = "/Users/you/.rbenv/shims/simplecov-mcp"
|
408
|
-
cwd = "/path/to/your/project"
|
409
|
-
```
|
410
|
-
- 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.
|
411
|
-
- On failures, check `~/simplecov_mcp.log` for details.
|
412
|
-
|
413
|
-
### Notes
|
414
|
-
|
415
|
-
- Library entrypoint: `require "simple_cov_mcp"` (also `simplecov_mcp`). Legacy `simple_cov/mcp` is supported.
|
416
|
-
- Programmatic run: `SimpleCovMcp.run(ARGV)`
|
417
|
-
- Staleness checks: pass `staleness: 'error'` to `CoverageModel` (or use CLI `--stale error`) to
|
418
|
-
raise if source mtimes are newer than coverage or line counts mismatch. Use
|
419
|
-
`--tracked-globs` (CLI) or `tracked_globs` (API/MCP) to flag new files.
|
420
|
-
- Logs basic diagnostics to `~/simplecov_mcp.log`.
|
421
|
-
|
422
|
-
## Executables and PATH
|
423
|
-
|
424
|
-
To run `simplecov-mcp` globally, your PATH must include where Ruby installs executables.
|
425
|
-
|
426
|
-
- Version managers
|
427
|
-
- RVM, rbenv, asdf, chruby typically add the right bin/shim directories to PATH.
|
428
|
-
- Ensure your shell is initialized (e.g., rbenv init, asdf reshim ruby after installs).
|
429
|
-
- Without a manager
|
430
|
-
- Add the gem bin dir to PATH: see it with `gem env` (look for "EXECUTABLE DIRECTORY") or `ruby -e 'puts Gem.bindir'`.
|
431
|
-
- Example: `export PATH="$HOME/.gem/ruby/3.2.0/bin:$PATH"` (adjust version).
|
432
|
-
- Alternatives
|
433
|
-
- Use Bundler: `bundle exec simplecov-mcp` with cwd set to your project.
|
434
|
-
- Symlink the repo executable into a bin on your PATH; the script resolves its lib/ via realpath.
|
435
|
-
- Or configure Codex to run the executable by filename (`simplecov-mcp`) and inherit the current workspace as cwd.
|
256
|
+
## Related Files
|
436
257
|
|
437
|
-
|
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
|
438
261
|
|
439
|
-
|
262
|
+
---
|
440
263
|
|
441
|
-
|
442
|
-
bundle install
|
443
|
-
ruby -Ilib exe/simplecov-mcp --cli
|
444
|
-
```
|
264
|
+
## Next Steps
|
445
265
|
|
446
|
-
|
266
|
+
📦 **Install:** `gem install simplecov-mcp`
|
447
267
|
|
448
|
-
|
449
|
-
bundle exec rspec
|
450
|
-
# open coverage/index.html for HTML report, or run exe/simplecov-mcp for table summary
|
451
|
-
```
|
268
|
+
📖 **Read:** [CLI Usage Guide](docs/CLI_USAGE.md) | [MCP Integration](docs/MCP_INTEGRATION.md)
|
452
269
|
|
453
|
-
|
270
|
+
🐛 **Report issues:** [GitHub Issues](https://github.com/keithrbennett/simplecov-mcp/issues)
|
454
271
|
|
455
|
-
|
272
|
+
⭐ **Star the repo** if you find it useful!
|