cov-loupe 3.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 (171) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +329 -0
  4. data/docs/dev/ARCHITECTURE.md +80 -0
  5. data/docs/dev/BRANCH_ONLY_COVERAGE.md +158 -0
  6. data/docs/dev/DEVELOPMENT.md +83 -0
  7. data/docs/dev/README.md +10 -0
  8. data/docs/dev/RELEASING.md +146 -0
  9. data/docs/dev/arch-decisions/001-x-arch-decision.md +95 -0
  10. data/docs/dev/arch-decisions/002-x-arch-decision.md +159 -0
  11. data/docs/dev/arch-decisions/003-x-arch-decision.md +165 -0
  12. data/docs/dev/arch-decisions/004-x-arch-decision.md +203 -0
  13. data/docs/dev/arch-decisions/005-x-arch-decision.md +189 -0
  14. data/docs/dev/arch-decisions/README.md +60 -0
  15. data/docs/dev/presentations/cov-loupe-presentation.md +255 -0
  16. data/docs/fixtures/demo_project/README.md +9 -0
  17. data/docs/user/ADVANCED_USAGE.md +777 -0
  18. data/docs/user/CLI_FALLBACK_FOR_LLMS.md +34 -0
  19. data/docs/user/CLI_USAGE.md +750 -0
  20. data/docs/user/ERROR_HANDLING.md +93 -0
  21. data/docs/user/EXAMPLES.md +588 -0
  22. data/docs/user/INSTALLATION.md +130 -0
  23. data/docs/user/LIBRARY_API.md +693 -0
  24. data/docs/user/MCP_INTEGRATION.md +490 -0
  25. data/docs/user/README.md +14 -0
  26. data/docs/user/TROUBLESHOOTING.md +197 -0
  27. data/docs/user/V2-BREAKING-CHANGES.md +472 -0
  28. data/exe/cov-loupe +23 -0
  29. data/lib/cov_loupe/app_config.rb +56 -0
  30. data/lib/cov_loupe/app_context.rb +26 -0
  31. data/lib/cov_loupe/base_tool.rb +102 -0
  32. data/lib/cov_loupe/cli.rb +178 -0
  33. data/lib/cov_loupe/commands/base_command.rb +67 -0
  34. data/lib/cov_loupe/commands/command_factory.rb +45 -0
  35. data/lib/cov_loupe/commands/detailed_command.rb +38 -0
  36. data/lib/cov_loupe/commands/list_command.rb +13 -0
  37. data/lib/cov_loupe/commands/raw_command.rb +38 -0
  38. data/lib/cov_loupe/commands/summary_command.rb +41 -0
  39. data/lib/cov_loupe/commands/totals_command.rb +53 -0
  40. data/lib/cov_loupe/commands/uncovered_command.rb +45 -0
  41. data/lib/cov_loupe/commands/validate_command.rb +60 -0
  42. data/lib/cov_loupe/commands/version_command.rb +33 -0
  43. data/lib/cov_loupe/config_parser.rb +32 -0
  44. data/lib/cov_loupe/constants.rb +22 -0
  45. data/lib/cov_loupe/coverage_reporter.rb +31 -0
  46. data/lib/cov_loupe/error_handler.rb +165 -0
  47. data/lib/cov_loupe/error_handler_factory.rb +31 -0
  48. data/lib/cov_loupe/errors.rb +191 -0
  49. data/lib/cov_loupe/formatters/source_formatter.rb +152 -0
  50. data/lib/cov_loupe/formatters.rb +51 -0
  51. data/lib/cov_loupe/mcp_server.rb +42 -0
  52. data/lib/cov_loupe/mode_detector.rb +56 -0
  53. data/lib/cov_loupe/model.rb +339 -0
  54. data/lib/cov_loupe/option_normalizers.rb +113 -0
  55. data/lib/cov_loupe/option_parser_builder.rb +147 -0
  56. data/lib/cov_loupe/option_parsers/env_options_parser.rb +48 -0
  57. data/lib/cov_loupe/option_parsers/error_helper.rb +110 -0
  58. data/lib/cov_loupe/path_relativizer.rb +64 -0
  59. data/lib/cov_loupe/predicate_evaluator.rb +72 -0
  60. data/lib/cov_loupe/presenters/base_coverage_presenter.rb +42 -0
  61. data/lib/cov_loupe/presenters/coverage_detailed_presenter.rb +14 -0
  62. data/lib/cov_loupe/presenters/coverage_raw_presenter.rb +14 -0
  63. data/lib/cov_loupe/presenters/coverage_summary_presenter.rb +14 -0
  64. data/lib/cov_loupe/presenters/coverage_uncovered_presenter.rb +14 -0
  65. data/lib/cov_loupe/presenters/project_coverage_presenter.rb +50 -0
  66. data/lib/cov_loupe/presenters/project_totals_presenter.rb +27 -0
  67. data/lib/cov_loupe/resolvers/coverage_line_resolver.rb +122 -0
  68. data/lib/cov_loupe/resolvers/resolver_factory.rb +28 -0
  69. data/lib/cov_loupe/resolvers/resultset_path_resolver.rb +76 -0
  70. data/lib/cov_loupe/resultset_loader.rb +131 -0
  71. data/lib/cov_loupe/staleness_checker.rb +247 -0
  72. data/lib/cov_loupe/table_formatter.rb +64 -0
  73. data/lib/cov_loupe/tools/all_files_coverage_tool.rb +51 -0
  74. data/lib/cov_loupe/tools/coverage_detailed_tool.rb +35 -0
  75. data/lib/cov_loupe/tools/coverage_raw_tool.rb +34 -0
  76. data/lib/cov_loupe/tools/coverage_summary_tool.rb +34 -0
  77. data/lib/cov_loupe/tools/coverage_table_tool.rb +50 -0
  78. data/lib/cov_loupe/tools/coverage_totals_tool.rb +44 -0
  79. data/lib/cov_loupe/tools/help_tool.rb +115 -0
  80. data/lib/cov_loupe/tools/uncovered_lines_tool.rb +34 -0
  81. data/lib/cov_loupe/tools/validate_tool.rb +72 -0
  82. data/lib/cov_loupe/tools/version_tool.rb +32 -0
  83. data/lib/cov_loupe/util.rb +88 -0
  84. data/lib/cov_loupe/version.rb +5 -0
  85. data/lib/cov_loupe.rb +140 -0
  86. data/spec/MCP_INTEGRATION_TESTS_README.md +111 -0
  87. data/spec/TIMESTAMPS.md +48 -0
  88. data/spec/all_files_coverage_tool_spec.rb +53 -0
  89. data/spec/app_config_spec.rb +142 -0
  90. data/spec/base_tool_spec.rb +62 -0
  91. data/spec/cli/show_default_report_spec.rb +33 -0
  92. data/spec/cli_enumerated_options_spec.rb +90 -0
  93. data/spec/cli_error_spec.rb +184 -0
  94. data/spec/cli_format_spec.rb +123 -0
  95. data/spec/cli_json_options_spec.rb +50 -0
  96. data/spec/cli_source_spec.rb +44 -0
  97. data/spec/cli_spec.rb +192 -0
  98. data/spec/cli_table_spec.rb +28 -0
  99. data/spec/cli_usage_spec.rb +42 -0
  100. data/spec/commands/base_command_spec.rb +107 -0
  101. data/spec/commands/command_factory_spec.rb +76 -0
  102. data/spec/commands/detailed_command_spec.rb +34 -0
  103. data/spec/commands/list_command_spec.rb +28 -0
  104. data/spec/commands/raw_command_spec.rb +69 -0
  105. data/spec/commands/summary_command_spec.rb +34 -0
  106. data/spec/commands/totals_command_spec.rb +34 -0
  107. data/spec/commands/uncovered_command_spec.rb +55 -0
  108. data/spec/commands/validate_command_spec.rb +213 -0
  109. data/spec/commands/version_command_spec.rb +38 -0
  110. data/spec/constants_spec.rb +61 -0
  111. data/spec/cov_loupe/formatters/source_formatter_spec.rb +267 -0
  112. data/spec/cov_loupe/formatters_spec.rb +76 -0
  113. data/spec/cov_loupe/presenters/base_coverage_presenter_spec.rb +79 -0
  114. data/spec/cov_loupe_model_spec.rb +454 -0
  115. data/spec/cov_loupe_module_spec.rb +37 -0
  116. data/spec/cov_loupe_opts_spec.rb +185 -0
  117. data/spec/coverage_reporter_spec.rb +102 -0
  118. data/spec/coverage_table_tool_spec.rb +59 -0
  119. data/spec/coverage_totals_tool_spec.rb +37 -0
  120. data/spec/error_handler_spec.rb +197 -0
  121. data/spec/error_mode_spec.rb +139 -0
  122. data/spec/errors_edge_cases_spec.rb +312 -0
  123. data/spec/errors_stale_spec.rb +83 -0
  124. data/spec/file_based_mcp_tools_spec.rb +99 -0
  125. data/spec/fixtures/project1/lib/bar.rb +5 -0
  126. data/spec/fixtures/project1/lib/foo.rb +6 -0
  127. data/spec/help_tool_spec.rb +26 -0
  128. data/spec/integration_spec.rb +789 -0
  129. data/spec/logging_fallback_spec.rb +128 -0
  130. data/spec/mcp_logging_spec.rb +44 -0
  131. data/spec/mcp_server_integration_spec.rb +23 -0
  132. data/spec/mcp_server_spec.rb +106 -0
  133. data/spec/mode_detector_spec.rb +153 -0
  134. data/spec/model_error_handling_spec.rb +269 -0
  135. data/spec/model_staleness_spec.rb +79 -0
  136. data/spec/option_normalizers_spec.rb +203 -0
  137. data/spec/option_parsers/env_options_parser_spec.rb +221 -0
  138. data/spec/option_parsers/error_helper_spec.rb +222 -0
  139. data/spec/path_relativizer_spec.rb +98 -0
  140. data/spec/presenters/coverage_detailed_presenter_spec.rb +19 -0
  141. data/spec/presenters/coverage_raw_presenter_spec.rb +15 -0
  142. data/spec/presenters/coverage_summary_presenter_spec.rb +15 -0
  143. data/spec/presenters/coverage_uncovered_presenter_spec.rb +16 -0
  144. data/spec/presenters/project_coverage_presenter_spec.rb +87 -0
  145. data/spec/presenters/project_totals_presenter_spec.rb +144 -0
  146. data/spec/resolvers/coverage_line_resolver_spec.rb +282 -0
  147. data/spec/resolvers/resolver_factory_spec.rb +61 -0
  148. data/spec/resolvers/resultset_path_resolver_spec.rb +60 -0
  149. data/spec/resultset_loader_spec.rb +167 -0
  150. data/spec/shared_examples/README.md +115 -0
  151. data/spec/shared_examples/coverage_presenter_examples.rb +66 -0
  152. data/spec/shared_examples/file_based_mcp_tools.rb +179 -0
  153. data/spec/shared_examples/formatted_command_examples.rb +64 -0
  154. data/spec/shared_examples/mcp_tool_text_json_response.rb +16 -0
  155. data/spec/spec_helper.rb +127 -0
  156. data/spec/staleness_checker_spec.rb +374 -0
  157. data/spec/staleness_more_spec.rb +42 -0
  158. data/spec/support/cli_helpers.rb +22 -0
  159. data/spec/support/control_flow_helpers.rb +20 -0
  160. data/spec/support/fake_mcp.rb +40 -0
  161. data/spec/support/io_helpers.rb +29 -0
  162. data/spec/support/mcp_helpers.rb +35 -0
  163. data/spec/support/mcp_runner.rb +66 -0
  164. data/spec/support/mocking_helpers.rb +30 -0
  165. data/spec/table_format_spec.rb +70 -0
  166. data/spec/tools/validate_tool_spec.rb +132 -0
  167. data/spec/tools_error_handling_spec.rb +130 -0
  168. data/spec/util_spec.rb +154 -0
  169. data/spec/version_spec.rb +123 -0
  170. data/spec/version_tool_spec.rb +141 -0
  171. metadata +290 -0
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'CovLoupe::VERSION' do
6
+ describe 'constant existence' do
7
+ it 'defines a VERSION constant' do
8
+ expect(CovLoupe.const_defined?(:VERSION)).to be true
9
+ end
10
+
11
+ it 'exposes VERSION as a non-empty string' do
12
+ expect(CovLoupe::VERSION).to be_a(String)
13
+ expect(CovLoupe::VERSION).not_to be_empty
14
+ end
15
+
16
+ it 'is frozen (immutable)' do
17
+ expect(CovLoupe::VERSION).to be_frozen
18
+ end
19
+ end
20
+
21
+ describe 'semantic versioning compliance' do
22
+ let(:version) { CovLoupe::VERSION }
23
+ # Simplified semantic versioning regex
24
+ # Preserves key semver rules: no leading zeros on numeric parts, optional prerelease/build metadata
25
+ let(:semver_regex) do
26
+ %r{\A
27
+ (?<major>0|[1-9]\d*)\.
28
+ (?<minor>0|[1-9]\d*)\.
29
+ (?<patch>0|[1-9]\d*)
30
+ (?:[.-](?<prerelease>[0-9A-Za-z.-]+))?
31
+ (?:\+(?<buildmetadata>[0-9A-Za-z.-]+))?
32
+ \z}x
33
+ end
34
+
35
+ it 'follows semantic versioning format (accepting hyphen or dot pre-release separator)' do
36
+ expect(version).to match(semver_regex)
37
+ end
38
+
39
+ it 'has valid major.minor.patch core version' do
40
+ match = version.match(semver_regex)
41
+ expect(match).not_to be_nil, "VERSION '#{version}' does not match semantic versioning format"
42
+
43
+ major = match[:major].to_i
44
+ minor = match[:minor].to_i
45
+ patch = match[:patch].to_i
46
+
47
+ expect(major).to be >= 0
48
+ expect(minor).to be >= 0
49
+ expect(patch).to be >= 0
50
+ end
51
+
52
+ context 'when version has prerelease identifier' do
53
+ let(:prerelease_version) { '9.9.9-rc.1' }
54
+
55
+ before do
56
+ stub_const('CovLoupe::VERSION', prerelease_version)
57
+ end
58
+
59
+ it 'has valid prerelease format' do
60
+ match = version.match(semver_regex)
61
+ prerelease = match[:prerelease]
62
+ expect(prerelease).not_to be_empty
63
+ expect(prerelease).not_to start_with('.')
64
+ expect(prerelease).not_to end_with('.')
65
+ end
66
+ end
67
+
68
+ context 'when version has build metadata' do
69
+ let(:build_metadata_version) { '9.9.9+build.42' }
70
+
71
+ before do
72
+ stub_const('CovLoupe::VERSION', build_metadata_version)
73
+ end
74
+
75
+ it 'has valid build metadata format' do
76
+ match = version.match(semver_regex)
77
+ buildmetadata = match[:buildmetadata]
78
+ expect(buildmetadata).not_to be_empty
79
+ expect(buildmetadata).to match(/\A[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*\z/)
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'version consistency' do
85
+ it 'is accessible via require path' do
86
+ expect { CovLoupe::VERSION }.not_to raise_error
87
+ end
88
+
89
+ it 'matches the version referenced in gemspec' do
90
+ gemspec_path = File.expand_path('../cov-loupe.gemspec', __dir__)
91
+ gemspec_content = File.read(gemspec_path)
92
+
93
+ version_line = gemspec_content.lines.find { |line| line.include?('spec.version') }
94
+ expect(version_line).not_to be_nil, 'Could not find version line in gemspec'
95
+ expect(version_line).to include('CovLoupe::VERSION')
96
+ end
97
+ end
98
+
99
+ describe 'current version sanity check' do
100
+ it 'is not the initial 0.0.0 version' do
101
+ # Ensure this is a real release, not an uninitialized version
102
+ expect(CovLoupe::VERSION).not_to eq('0.0.0')
103
+ end
104
+ end
105
+
106
+ describe 'standalone version file load' do
107
+ it 'defines the module and VERSION constant when only version.rb is loaded' do
108
+ original_version = CovLoupe::VERSION
109
+
110
+ stub_const('CovLoupe', Module.new do
111
+ class << self
112
+ attr_accessor :default_log_file, :active_log_file
113
+ end
114
+ end)
115
+
116
+ version_path = File.expand_path('../lib/cov_loupe/version.rb', __dir__)
117
+ load version_path
118
+
119
+ expect(Object.const_defined?(:CovLoupe)).to be true
120
+ expect(CovLoupe::VERSION).to eq(original_version)
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'cov_loupe/tools/version_tool'
5
+
6
+ RSpec.describe CovLoupe::Tools::VersionTool do
7
+ let(:server_context) { instance_double('ServerContext').as_null_object }
8
+
9
+ before do
10
+ setup_mcp_response_stub
11
+ end
12
+
13
+ describe '.call' do
14
+ it 'returns a text payload with the version string when called without arguments' do
15
+ response = described_class.call(server_context: server_context)
16
+ item = response.payload.first
17
+ expect(item[:type] || item['type']).to eq('text')
18
+ text = item['text']
19
+ expect(text).to eq("CovLoupe version: #{CovLoupe::VERSION}")
20
+ end
21
+
22
+ it 'includes the exact version constant value' do
23
+ response = described_class.call(server_context: server_context)
24
+ item = response.payload.first
25
+ text = item['text']
26
+ expect(text).to include(CovLoupe::VERSION)
27
+ end
28
+
29
+ it 'matches the expected format exactly' do
30
+ expected_format = "CovLoupe version: #{CovLoupe::VERSION}"
31
+ response = described_class.call(server_context: server_context)
32
+ item = response.payload.first
33
+ text = item['text']
34
+ expect(text).to eq(expected_format)
35
+ end
36
+
37
+ it 'returns an MCP::Tool::Response object' do
38
+ response = described_class.call(server_context: server_context)
39
+ expect(response).to be_a(MCP::Tool::Response)
40
+ end
41
+
42
+ it 'has a single payload item' do
43
+ response = described_class.call(server_context: server_context)
44
+ expect(response.payload).to be_an(Array)
45
+ expect(response.payload.size).to eq(1)
46
+ end
47
+
48
+ context 'when error_mode is specified' do
49
+ it 'accepts error_mode parameter without affecting output' do
50
+ response = described_class.call(error_mode: 'off', server_context: server_context)
51
+ item = response.payload.first
52
+ text = item['text']
53
+ expect(text).to eq("CovLoupe version: #{CovLoupe::VERSION}")
54
+ end
55
+
56
+ it 'accepts error_mode "log" (default)' do
57
+ response = described_class.call(error_mode: 'log', server_context: server_context)
58
+ item = response.payload.first
59
+ expect(item[:type] || item['type']).to eq('text')
60
+ end
61
+
62
+ it 'accepts error_mode "debug"' do
63
+ response = described_class.call(error_mode: 'debug', server_context: server_context)
64
+ item = response.payload.first
65
+ expect(item[:type] || item['type']).to eq('text')
66
+ end
67
+ end
68
+
69
+ context 'when additional arguments are passed' do
70
+ it 'ignores additional arguments gracefully' do
71
+ response = described_class.call(
72
+ server_context: server_context,
73
+ extra_arg: 'value',
74
+ another: { nested: 'data' }
75
+ )
76
+ item = response.payload.first
77
+ text = item['text']
78
+ expect(text).to eq("CovLoupe version: #{CovLoupe::VERSION}")
79
+ end
80
+ end
81
+
82
+ context 'when an error occurs' do
83
+ it 'handles VERSION constant access errors and returns structured error response' do
84
+ # Force an error by hiding VERSION so const_missing is triggered
85
+ hide_const('CovLoupe::VERSION')
86
+ allow(CovLoupe).to receive(:const_missing).with(:VERSION)
87
+ .and_raise(StandardError, 'Version access error')
88
+
89
+ response = described_class.call(error_mode: 'log', server_context: server_context)
90
+
91
+ # Should return error response in MCP format
92
+ expect(response).to be_a(MCP::Tool::Response)
93
+ item = response.payload.first
94
+ expect(item[:type] || item['type']).to eq('text')
95
+
96
+ error_text = item['text']
97
+ expect(error_text).to include('Error')
98
+ end
99
+
100
+ it 'handles errors in the response creation process' do
101
+ # Force an error by mocking string interpolation to fail
102
+ version_obj = double('VERSION')
103
+ allow(version_obj).to receive(:to_s).and_raise(StandardError, 'String conversion error')
104
+
105
+ # Replace VERSION with our mock object
106
+ stub_const('CovLoupe::VERSION', version_obj)
107
+
108
+ response = described_class.call(error_mode: 'log', server_context: server_context)
109
+
110
+ # Should return error response in MCP format via the rescue block
111
+ expect(response).to be_a(MCP::Tool::Response)
112
+ item = response.payload.first
113
+ expect(item[:type] || item['type']).to eq('text')
114
+
115
+ error_text = item['text']
116
+ expect(error_text).to include('Error')
117
+ end
118
+
119
+ it 'respects error_mode setting when handling errors' do
120
+ # Force an error using a mock VERSION that raises an exception
121
+ version_obj = double('VERSION')
122
+ allow(version_obj).to receive(:to_s).and_raise(StandardError, 'Version error')
123
+ stub_const('CovLoupe::VERSION', version_obj)
124
+
125
+ # Test error_mode 'off' (should be silent but still return structured response)
126
+ response = described_class.call(error_mode: 'off', server_context: server_context)
127
+ expect(response).to be_a(MCP::Tool::Response)
128
+ item = response.payload.first
129
+ expect(item[:type] || item['type']).to eq('text')
130
+
131
+ # Test error_mode 'debug' (should include more detail)
132
+ response = described_class.call(error_mode: 'debug', server_context: server_context)
133
+ expect(response).to be_a(MCP::Tool::Response)
134
+ item = response.payload.first
135
+ expect(item[:type] || item['type']).to eq('text')
136
+ error_text = item['text']
137
+ expect(error_text).to include('Error')
138
+ end
139
+ end
140
+ end
141
+ end
metadata ADDED
@@ -0,0 +1,290 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cov-loupe
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Keith R. Bennett
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: awesome_print
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.9'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.9'
26
+ - !ruby/object:Gem::Dependency
27
+ name: mcp
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.3'
40
+ - !ruby/object:Gem::Dependency
41
+ name: simplecov
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0.21'
47
+ - - "<"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0.21'
57
+ - - "<"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.0'
60
+ description: Provides an MCP (Model Context Protocol) server and a CLI to inspect
61
+ SimpleCov coverage, including per-file summaries and uncovered lines.
62
+ email:
63
+ - keithrbennett@gmail.com
64
+ executables:
65
+ - cov-loupe
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - LICENSE
70
+ - README.md
71
+ - docs/dev/ARCHITECTURE.md
72
+ - docs/dev/BRANCH_ONLY_COVERAGE.md
73
+ - docs/dev/DEVELOPMENT.md
74
+ - docs/dev/README.md
75
+ - docs/dev/RELEASING.md
76
+ - docs/dev/arch-decisions/001-x-arch-decision.md
77
+ - docs/dev/arch-decisions/002-x-arch-decision.md
78
+ - docs/dev/arch-decisions/003-x-arch-decision.md
79
+ - docs/dev/arch-decisions/004-x-arch-decision.md
80
+ - docs/dev/arch-decisions/005-x-arch-decision.md
81
+ - docs/dev/arch-decisions/README.md
82
+ - docs/dev/presentations/cov-loupe-presentation.md
83
+ - docs/fixtures/demo_project/README.md
84
+ - docs/user/ADVANCED_USAGE.md
85
+ - docs/user/CLI_FALLBACK_FOR_LLMS.md
86
+ - docs/user/CLI_USAGE.md
87
+ - docs/user/ERROR_HANDLING.md
88
+ - docs/user/EXAMPLES.md
89
+ - docs/user/INSTALLATION.md
90
+ - docs/user/LIBRARY_API.md
91
+ - docs/user/MCP_INTEGRATION.md
92
+ - docs/user/README.md
93
+ - docs/user/TROUBLESHOOTING.md
94
+ - docs/user/V2-BREAKING-CHANGES.md
95
+ - exe/cov-loupe
96
+ - lib/cov_loupe.rb
97
+ - lib/cov_loupe/app_config.rb
98
+ - lib/cov_loupe/app_context.rb
99
+ - lib/cov_loupe/base_tool.rb
100
+ - lib/cov_loupe/cli.rb
101
+ - lib/cov_loupe/commands/base_command.rb
102
+ - lib/cov_loupe/commands/command_factory.rb
103
+ - lib/cov_loupe/commands/detailed_command.rb
104
+ - lib/cov_loupe/commands/list_command.rb
105
+ - lib/cov_loupe/commands/raw_command.rb
106
+ - lib/cov_loupe/commands/summary_command.rb
107
+ - lib/cov_loupe/commands/totals_command.rb
108
+ - lib/cov_loupe/commands/uncovered_command.rb
109
+ - lib/cov_loupe/commands/validate_command.rb
110
+ - lib/cov_loupe/commands/version_command.rb
111
+ - lib/cov_loupe/config_parser.rb
112
+ - lib/cov_loupe/constants.rb
113
+ - lib/cov_loupe/coverage_reporter.rb
114
+ - lib/cov_loupe/error_handler.rb
115
+ - lib/cov_loupe/error_handler_factory.rb
116
+ - lib/cov_loupe/errors.rb
117
+ - lib/cov_loupe/formatters.rb
118
+ - lib/cov_loupe/formatters/source_formatter.rb
119
+ - lib/cov_loupe/mcp_server.rb
120
+ - lib/cov_loupe/mode_detector.rb
121
+ - lib/cov_loupe/model.rb
122
+ - lib/cov_loupe/option_normalizers.rb
123
+ - lib/cov_loupe/option_parser_builder.rb
124
+ - lib/cov_loupe/option_parsers/env_options_parser.rb
125
+ - lib/cov_loupe/option_parsers/error_helper.rb
126
+ - lib/cov_loupe/path_relativizer.rb
127
+ - lib/cov_loupe/predicate_evaluator.rb
128
+ - lib/cov_loupe/presenters/base_coverage_presenter.rb
129
+ - lib/cov_loupe/presenters/coverage_detailed_presenter.rb
130
+ - lib/cov_loupe/presenters/coverage_raw_presenter.rb
131
+ - lib/cov_loupe/presenters/coverage_summary_presenter.rb
132
+ - lib/cov_loupe/presenters/coverage_uncovered_presenter.rb
133
+ - lib/cov_loupe/presenters/project_coverage_presenter.rb
134
+ - lib/cov_loupe/presenters/project_totals_presenter.rb
135
+ - lib/cov_loupe/resolvers/coverage_line_resolver.rb
136
+ - lib/cov_loupe/resolvers/resolver_factory.rb
137
+ - lib/cov_loupe/resolvers/resultset_path_resolver.rb
138
+ - lib/cov_loupe/resultset_loader.rb
139
+ - lib/cov_loupe/staleness_checker.rb
140
+ - lib/cov_loupe/table_formatter.rb
141
+ - lib/cov_loupe/tools/all_files_coverage_tool.rb
142
+ - lib/cov_loupe/tools/coverage_detailed_tool.rb
143
+ - lib/cov_loupe/tools/coverage_raw_tool.rb
144
+ - lib/cov_loupe/tools/coverage_summary_tool.rb
145
+ - lib/cov_loupe/tools/coverage_table_tool.rb
146
+ - lib/cov_loupe/tools/coverage_totals_tool.rb
147
+ - lib/cov_loupe/tools/help_tool.rb
148
+ - lib/cov_loupe/tools/uncovered_lines_tool.rb
149
+ - lib/cov_loupe/tools/validate_tool.rb
150
+ - lib/cov_loupe/tools/version_tool.rb
151
+ - lib/cov_loupe/util.rb
152
+ - lib/cov_loupe/version.rb
153
+ - spec/MCP_INTEGRATION_TESTS_README.md
154
+ - spec/TIMESTAMPS.md
155
+ - spec/all_files_coverage_tool_spec.rb
156
+ - spec/app_config_spec.rb
157
+ - spec/base_tool_spec.rb
158
+ - spec/cli/show_default_report_spec.rb
159
+ - spec/cli_enumerated_options_spec.rb
160
+ - spec/cli_error_spec.rb
161
+ - spec/cli_format_spec.rb
162
+ - spec/cli_json_options_spec.rb
163
+ - spec/cli_source_spec.rb
164
+ - spec/cli_spec.rb
165
+ - spec/cli_table_spec.rb
166
+ - spec/cli_usage_spec.rb
167
+ - spec/commands/base_command_spec.rb
168
+ - spec/commands/command_factory_spec.rb
169
+ - spec/commands/detailed_command_spec.rb
170
+ - spec/commands/list_command_spec.rb
171
+ - spec/commands/raw_command_spec.rb
172
+ - spec/commands/summary_command_spec.rb
173
+ - spec/commands/totals_command_spec.rb
174
+ - spec/commands/uncovered_command_spec.rb
175
+ - spec/commands/validate_command_spec.rb
176
+ - spec/commands/version_command_spec.rb
177
+ - spec/constants_spec.rb
178
+ - spec/cov_loupe/formatters/source_formatter_spec.rb
179
+ - spec/cov_loupe/formatters_spec.rb
180
+ - spec/cov_loupe/presenters/base_coverage_presenter_spec.rb
181
+ - spec/cov_loupe_model_spec.rb
182
+ - spec/cov_loupe_module_spec.rb
183
+ - spec/cov_loupe_opts_spec.rb
184
+ - spec/coverage_reporter_spec.rb
185
+ - spec/coverage_table_tool_spec.rb
186
+ - spec/coverage_totals_tool_spec.rb
187
+ - spec/error_handler_spec.rb
188
+ - spec/error_mode_spec.rb
189
+ - spec/errors_edge_cases_spec.rb
190
+ - spec/errors_stale_spec.rb
191
+ - spec/file_based_mcp_tools_spec.rb
192
+ - spec/fixtures/project1/lib/bar.rb
193
+ - spec/fixtures/project1/lib/foo.rb
194
+ - spec/help_tool_spec.rb
195
+ - spec/integration_spec.rb
196
+ - spec/logging_fallback_spec.rb
197
+ - spec/mcp_logging_spec.rb
198
+ - spec/mcp_server_integration_spec.rb
199
+ - spec/mcp_server_spec.rb
200
+ - spec/mode_detector_spec.rb
201
+ - spec/model_error_handling_spec.rb
202
+ - spec/model_staleness_spec.rb
203
+ - spec/option_normalizers_spec.rb
204
+ - spec/option_parsers/env_options_parser_spec.rb
205
+ - spec/option_parsers/error_helper_spec.rb
206
+ - spec/path_relativizer_spec.rb
207
+ - spec/presenters/coverage_detailed_presenter_spec.rb
208
+ - spec/presenters/coverage_raw_presenter_spec.rb
209
+ - spec/presenters/coverage_summary_presenter_spec.rb
210
+ - spec/presenters/coverage_uncovered_presenter_spec.rb
211
+ - spec/presenters/project_coverage_presenter_spec.rb
212
+ - spec/presenters/project_totals_presenter_spec.rb
213
+ - spec/resolvers/coverage_line_resolver_spec.rb
214
+ - spec/resolvers/resolver_factory_spec.rb
215
+ - spec/resolvers/resultset_path_resolver_spec.rb
216
+ - spec/resultset_loader_spec.rb
217
+ - spec/shared_examples/README.md
218
+ - spec/shared_examples/coverage_presenter_examples.rb
219
+ - spec/shared_examples/file_based_mcp_tools.rb
220
+ - spec/shared_examples/formatted_command_examples.rb
221
+ - spec/shared_examples/mcp_tool_text_json_response.rb
222
+ - spec/spec_helper.rb
223
+ - spec/staleness_checker_spec.rb
224
+ - spec/staleness_more_spec.rb
225
+ - spec/support/cli_helpers.rb
226
+ - spec/support/control_flow_helpers.rb
227
+ - spec/support/fake_mcp.rb
228
+ - spec/support/io_helpers.rb
229
+ - spec/support/mcp_helpers.rb
230
+ - spec/support/mcp_runner.rb
231
+ - spec/support/mocking_helpers.rb
232
+ - spec/table_format_spec.rb
233
+ - spec/tools/validate_tool_spec.rb
234
+ - spec/tools_error_handling_spec.rb
235
+ - spec/util_spec.rb
236
+ - spec/version_spec.rb
237
+ - spec/version_tool_spec.rb
238
+ homepage: https://github.com/keithrbennett/cov-loupe
239
+ licenses:
240
+ - MIT
241
+ metadata:
242
+ rubygems_mfa_required: 'true'
243
+ post_install_message: |
244
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
245
+ ┃ V3.0.0 - GEM RENAMED: simplecov-mcp → cov-loupe ┃
246
+ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
247
+ ┃ ┃
248
+ ┃ This gem has been renamed! If upgrading from simplecov-mcp: ┃
249
+ ┃ ┃
250
+ ┃ • Executable: simplecov-mcp → cov-loupe ┃
251
+ ┃ • Environment: SIMPLECOV_MCP_OPTS → COV_LOUPE_OPTS ┃
252
+ ┃ • Log file: simplecov_mcp.log → cov_loupe.log ┃
253
+ ┃ • Alias: smcp → clp (in documentation) ┃
254
+ ┃ ┃
255
+ ┃ Module name (CovLoupe) and require path (cov_loupe) unchanged. ┃
256
+ ┃ ┃
257
+ ┃ Uninstall old gem: gem uninstall simplecov-mcp ┃
258
+ ┃ ┃
259
+ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
260
+ ┃ V2.0.0 BREAKING CHANGES (if upgrading from v1.x) ┃
261
+ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
262
+ ┃ ┃
263
+ ┃ • Options must now come BEFORE subcommands ┃
264
+ ┃ • --stale renamed to --staleness (-S still works) ┃
265
+ ┃ • --json replaced with --format json ┃
266
+ ┃ • Error modes renamed: 'on' → 'log', 'trace' → 'debug' ┃
267
+ ┃ • --success-predicate moved to 'validate' subcommand ┃
268
+ ┃ • Default sort order changed from ascending to descending ┃
269
+ ┃ ┃
270
+ ┃ See docs/user/V2-BREAKING-CHANGES.md for complete migration guide. ┃
271
+ ┃ ┃
272
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
273
+ rdoc_options: []
274
+ require_paths:
275
+ - lib
276
+ required_ruby_version: !ruby/object:Gem::Requirement
277
+ requirements:
278
+ - - ">="
279
+ - !ruby/object:Gem::Version
280
+ version: '3.2'
281
+ required_rubygems_version: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ requirements: []
287
+ rubygems_version: 3.7.2
288
+ specification_version: 4
289
+ summary: MCP server + CLI for SimpleCov coverage data
290
+ test_files: []