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.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +173 -345
- 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 -15
- 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 +14 -7
- 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 -23
- 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 +8 -13
- 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 -4
- data/spec/version_tool_spec.rb +143 -0
- metadata +121 -59
- data/lib/simple_cov/mcp.rb +0 -9
- data/lib/simple_cov_mcp/base_tool.rb +0 -54
- 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/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
|
-
|
|
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
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
# Run your tests with SimpleCov enabled
|
|
45
|
+
bundle exec rspec # or your test command
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
# Verify coverage was generated
|
|
48
|
+
ls coverage/.resultset.json
|
|
49
|
+
```
|
|
35
50
|
|
|
36
|
-
###
|
|
51
|
+
### Basic Usage
|
|
37
52
|
|
|
38
|
-
|
|
53
|
+
**CLI - View Coverage Table:**
|
|
54
|
+
```sh
|
|
55
|
+
simplecov-mcp
|
|
56
|
+
```
|
|
39
57
|
|
|
40
|
-
|
|
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 "
|
|
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
|
-
|
|
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
|
-
|
|
75
|
-
# => {
|
|
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
|
-
|
|
76
|
+
**MCP Server:**
|
|
77
|
+
See [MCP Integration Guide](docs/MCP_INTEGRATION.md) for AI assistant setup.
|
|
79
78
|
|
|
80
|
-
|
|
81
|
-
- One-off MCP requests can be made by piping JSON-RPC to the server:
|
|
79
|
+
## Key Features
|
|
82
80
|
|
|
83
|
-
|
|
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
|
-
|
|
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
|
-
|
|
91
|
+
### How It Works
|
|
94
92
|
|
|
95
|
-
|
|
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
|
-
-
|
|
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
|
-
|
|
97
|
+
### Current Limitations
|
|
105
98
|
|
|
106
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
114
|
-
model.all_files(sort_order: :descending) # or :ascending (default)
|
|
115
|
-
```
|
|
103
|
+
## Documentation
|
|
116
104
|
|
|
117
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
+
## Requirements
|
|
124
120
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
130
|
+
```sh
|
|
131
|
+
# Command-line option (highest priority)
|
|
132
|
+
simplecov-mcp --resultset /path/to/your/coverage
|
|
136
133
|
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
# Environment variable (project-wide default)
|
|
135
|
+
export SIMPLECOV_MCP_OPTS="--resultset /path/to/your/coverage"
|
|
139
136
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
# MCP server configuration
|
|
138
|
+
# Add to your MCP client config:
|
|
139
|
+
# "args": ["--resultset", "/path/to/your/coverage"]
|
|
143
140
|
```
|
|
144
141
|
|
|
145
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
175
|
-
|
|
157
|
+
# Specific directory
|
|
158
|
+
simplecov-mcp list --tracked-globs "lib/simplecov_mcp/tools/**/*.rb"
|
|
176
159
|
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
216
|
-
|
|
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
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
257
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
210
|
+
## Development
|
|
308
211
|
|
|
309
212
|
```sh
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
# or
|
|
320
|
-
SIMPLECOV_MCP_CLI=1 simplecov-mcp
|
|
321
|
-
```
|
|
218
|
+
# Run tests
|
|
219
|
+
bundle exec rspec
|
|
322
220
|
|
|
323
|
-
|
|
221
|
+
# Test locally
|
|
222
|
+
ruby -Ilib exe/simplecov-mcp
|
|
324
223
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
### MCP Server Mode
|
|
229
|
+
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for more *(coming soon)*.
|
|
338
230
|
|
|
339
|
-
|
|
231
|
+
## SimpleCov Dependency
|
|
340
232
|
|
|
341
|
-
|
|
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
|
-
|
|
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
|
-
|
|
237
|
+
Contributions are welcome! Please:
|
|
352
238
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
249
|
+
## Links
|
|
373
250
|
|
|
374
|
-
|
|
375
|
-
|
|
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
|
-
|
|
256
|
+
## Related Files
|
|
379
257
|
|
|
380
|
-
-
|
|
381
|
-
-
|
|
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
|
-
|
|
262
|
+
---
|
|
384
263
|
|
|
385
|
-
|
|
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
|
-
|
|
266
|
+
📦 **Install:** `gem install simplecov-mcp`
|
|
427
267
|
|
|
428
|
-
|
|
268
|
+
📖 **Read:** [CLI Usage Guide](docs/CLI_USAGE.md) | [MCP Integration](docs/MCP_INTEGRATION.md)
|
|
429
269
|
|
|
430
|
-
|
|
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
|
-
|
|
272
|
+
⭐ **Star the repo** if you find it useful!
|