cov-loupe 4.1.0 → 6.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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +57 -30
  3. data/CONTRIBUTING.md +83 -51
  4. data/README.md +82 -61
  5. data/RELEASE_NOTES.md +89 -58
  6. data/dev/images/cov-loupe-youtube-thumbnail.png +0 -0
  7. data/dev/prompts/README.md +15 -10
  8. data/dev/prompts/guidelines/ai-code-evaluator-guidelines.md +7 -7
  9. data/dev/prompts/improve/refactor-test-suite.md +19 -4
  10. data/dev/prompts/improve/simplify-code-logic.md +18 -4
  11. data/dev/prompts/improve/update-documentation.md +23 -10
  12. data/dev/prompts/review/comprehensive-codebase-review.md +37 -16
  13. data/dev/prompts/review/identify-action-items.md +51 -20
  14. data/dev/prompts/review/review-documentation.md +91 -0
  15. data/dev/prompts/review/verify-code-changes.md +15 -5
  16. data/dev/prompts/validate/test-documentation-examples.md +12 -1
  17. data/dev/scripts/verify_doc_links.rb +462 -0
  18. data/docs/dev/ARCHITECTURE.md +17 -17
  19. data/docs/dev/DEVELOPMENT.md +9 -5
  20. data/docs/dev/README.md +2 -1
  21. data/docs/dev/RELEASING.md +29 -29
  22. data/docs/dev/arch-decisions/README.md +1 -1
  23. data/docs/dev/arch-decisions/application-architecture.md +15 -15
  24. data/docs/dev/arch-decisions/coverage-data-quality.md +10 -10
  25. data/docs/dev/arch-decisions/output-character-mode.md +10 -10
  26. data/docs/dev/arch-decisions/path-resolution.md +7 -7
  27. data/docs/dev/arch-decisions/policy-validation.md +34 -32
  28. data/docs/dev/arch-decisions/simplecov-integration.md +9 -10
  29. data/docs/fixtures/demo_project/README.md +1 -1
  30. data/docs/index.md +1 -0
  31. data/docs/user/ADVANCED_USAGE.md +38 -50
  32. data/docs/user/CLI_FALLBACK_FOR_LLMS.md +2 -2
  33. data/docs/user/CLI_USAGE.md +202 -143
  34. data/docs/user/ERROR_HANDLING.md +21 -12
  35. data/docs/user/EXAMPLES.md +7 -7
  36. data/docs/user/INSTALLATION.md +3 -1
  37. data/docs/user/LIBRARY_API.md +67 -46
  38. data/docs/user/MCP_INTEGRATION.md +189 -53
  39. data/docs/user/README.md +1 -1
  40. data/docs/user/TROUBLESHOOTING.md +96 -7
  41. data/docs/user/installing-a-prelease-version-of-covloupe.md +2 -0
  42. data/docs/user/migrations/MIGRATING_TO_V2.md +13 -13
  43. data/docs/user/migrations/MIGRATING_TO_V4.md +43 -59
  44. data/docs/user/migrations/MIGRATING_TO_V5.md +136 -0
  45. data/docs/user/migrations/MIGRATING_TO_V6.md +166 -0
  46. data/docs/user/migrations/README.md +2 -0
  47. data/docs/user/prompts/use-cli-not-mcp-prompt.md +8 -8
  48. data/examples/cli_demo.sh +19 -19
  49. data/examples/filter_and_table_demo.rb +1 -1
  50. data/examples/mcp-inputs/coverage_detailed.json +1 -1
  51. data/examples/mcp-inputs/coverage_raw.json +1 -1
  52. data/examples/mcp-inputs/coverage_summary.json +1 -1
  53. data/examples/mcp-inputs/list.json +1 -1
  54. data/examples/mcp-inputs/uncovered_lines.json +1 -1
  55. data/examples/success_predicates/README.md +9 -7
  56. data/examples/success_predicates/all_files_above_threshold_predicate.rb +5 -5
  57. data/examples/success_predicates/directory_specific_thresholds_predicate.rb +6 -6
  58. data/examples/success_predicates/project_coverage_minimum_predicate.rb +3 -3
  59. data/exe/cov-loupe +45 -16
  60. data/lib/cov_loupe/base_tool.rb +64 -34
  61. data/lib/cov_loupe/cli.rb +41 -52
  62. data/lib/cov_loupe/commands/base_command.rb +5 -0
  63. data/lib/cov_loupe/commands/command_factory.rb +10 -9
  64. data/lib/cov_loupe/commands/detailed_command.rb +6 -5
  65. data/lib/cov_loupe/commands/raw_command.rb +5 -5
  66. data/lib/cov_loupe/commands/summary_command.rb +4 -4
  67. data/lib/cov_loupe/commands/totals_command.rb +10 -10
  68. data/lib/cov_loupe/commands/uncovered_command.rb +3 -3
  69. data/lib/cov_loupe/config/app_config.rb +34 -10
  70. data/lib/cov_loupe/config/app_context.rb +8 -1
  71. data/lib/cov_loupe/config/boolean_type.rb +2 -2
  72. data/lib/cov_loupe/config/config_parser.rb +7 -3
  73. data/lib/cov_loupe/config/logger.rb +42 -6
  74. data/lib/cov_loupe/config/option_normalizers.rb +82 -35
  75. data/lib/cov_loupe/config/option_parser_builder.rb +20 -17
  76. data/lib/cov_loupe/coverage/coverage_calculator.rb +25 -1
  77. data/lib/cov_loupe/coverage/coverage_reporter.rb +6 -2
  78. data/lib/cov_loupe/coverage/coverage_table_formatter.rb +17 -7
  79. data/lib/cov_loupe/errors/error_handler.rb +13 -3
  80. data/lib/cov_loupe/errors/error_handler_factory.rb +6 -0
  81. data/lib/cov_loupe/errors/errors.rb +28 -8
  82. data/lib/cov_loupe/formatters/formatters.rb +54 -53
  83. data/lib/cov_loupe/formatters/source_formatter.rb +23 -7
  84. data/lib/cov_loupe/formatters/table_formatter.rb +6 -3
  85. data/lib/cov_loupe/loaders/all_mcp.rb +7 -8
  86. data/lib/cov_loupe/loaders/resultset_loader.rb +36 -11
  87. data/lib/cov_loupe/mcp_server.rb +24 -14
  88. data/lib/cov_loupe/model/model.rb +106 -68
  89. data/lib/cov_loupe/model/model_data_cache.rb +31 -16
  90. data/lib/cov_loupe/option_parsers/error_helper.rb +5 -4
  91. data/lib/cov_loupe/output_chars.rb +20 -20
  92. data/lib/cov_loupe/paths/glob_utils.rb +5 -0
  93. data/lib/cov_loupe/paths/path_relativizer.rb +9 -0
  94. data/lib/cov_loupe/paths/path_utils.rb +20 -7
  95. data/lib/cov_loupe/paths/volume_case_sensitivity.rb +4 -2
  96. data/lib/cov_loupe/presenters/base_coverage_presenter.rb +4 -0
  97. data/lib/cov_loupe/presenters/coverage_payload_presenter.rb +4 -1
  98. data/lib/cov_loupe/presenters/payload_caching.rb +6 -0
  99. data/lib/cov_loupe/presenters/project_coverage_presenter.rb +14 -10
  100. data/lib/cov_loupe/presenters/project_totals_presenter.rb +1 -1
  101. data/lib/cov_loupe/repositories/coverage_repository.rb +9 -11
  102. data/lib/cov_loupe/resolvers/coverage_line_resolver.rb +12 -5
  103. data/lib/cov_loupe/resolvers/resolver_helpers.rb +3 -0
  104. data/lib/cov_loupe/resolvers/resultset_path_resolver.rb +21 -4
  105. data/lib/cov_loupe/resources.rb +6 -4
  106. data/lib/cov_loupe/scripts/latest_ci_status.rb +2 -2
  107. data/lib/cov_loupe/scripts/setup_doc_server.rb +10 -4
  108. data/lib/cov_loupe/scripts/start_doc_server.rb +16 -1
  109. data/lib/cov_loupe/staleness/stale_status.rb +18 -0
  110. data/lib/cov_loupe/staleness/staleness_checker.rb +65 -38
  111. data/lib/cov_loupe/staleness/staleness_message_formatter.rb +9 -3
  112. data/lib/cov_loupe/tools/{coverage_detailed_tool.rb → file_coverage_detailed_tool.rb} +8 -7
  113. data/lib/cov_loupe/tools/{coverage_raw_tool.rb → file_coverage_raw_tool.rb} +8 -7
  114. data/lib/cov_loupe/tools/{coverage_summary_tool.rb → file_coverage_summary_tool.rb} +9 -8
  115. data/lib/cov_loupe/tools/{uncovered_lines_tool.rb → file_uncovered_lines_tool.rb} +9 -8
  116. data/lib/cov_loupe/tools/help_tool.rb +44 -49
  117. data/lib/cov_loupe/tools/{coverage_table_tool.rb → project_coverage_tool.rb} +80 -47
  118. data/lib/cov_loupe/tools/{coverage_totals_tool.rb → project_coverage_totals_tool.rb} +12 -10
  119. data/lib/cov_loupe/tools/{validate_tool.rb → project_validate_tool.rb} +16 -13
  120. data/lib/cov_loupe/tools/version_tool.rb +6 -5
  121. data/lib/cov_loupe/version.rb +1 -1
  122. data/lib/cov_loupe.rb +35 -10
  123. metadata +32 -54
  124. data/docs/dev/presentations/cov-loupe-presentation.md +0 -252
  125. data/lib/cov_loupe/commands/version_command.rb +0 -35
  126. data/lib/cov_loupe/tools/list_tool.rb +0 -65
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab58b40f995f1d04092370085819a657ba056750444cd8c67d46740631f7c2c0
4
- data.tar.gz: 1af5647670eff983389558a3772a79eb46d0bbf6e8ba857a590aeae9f776f8f5
3
+ metadata.gz: 596b917ef1e78eca9ae6ce05c0d351f963065c0d7506bc74c387548ba51a430a
4
+ data.tar.gz: 1a85f7fc229c84e578f9ddd7226b88ca2791e352f3b76438ae2120465bcb70a9
5
5
  SHA512:
6
- metadata.gz: 923ef2da60d9cd406266d7b81483cdb2594b3b6b37cb48648dda2743c0a782de3d58099c28f6971b37cad405bb121a4f089dc92b9558fbc547c89e9a6f41257b
7
- data.tar.gz: f54413f1d76e5fa0f52a263b4ab30d613fea772f788b93c9af1b585fad18aa86d85a2fdadb85f95254c259cf078b662081fa4daa01be1e770ecbf180f2f82357
6
+ metadata.gz: 8a38acddf9daf5d33d30002ff5392269b69e89dc5b5b3d63fa4823835d546a011326465188f55216dd32f6598c60f8b1e878dbd0ba374c1aa696e91f61ca5b04
7
+ data.tar.gz: a742933c4722697bea231eb4e7714804dd1cb721c7640b5afef7d22d1800d0a7c38591f3a122911f8a8d1cc5b307eebce91267f7b2e434f7d008570b15292b93
data/AGENTS.md CHANGED
@@ -9,7 +9,7 @@ This file provides guidance to Codex, Claude Code (claude.ai/code), Gemini CLI,
9
9
  computing it from scratch or analyzing the Simplecov-generated .resultset.json file directly.
10
10
  - Keep workflow transparent: explain what you did, why it matters, and what the user should consider next.
11
11
  - Leave the repository tidy; only touch files that advance the request. If you find
12
- other opportunities for improvement along te way, mention them in the form of a prompt the user can use later.
12
+ other opportunities for improvement along the way, mention them in the form of a prompt the user can use later.
13
13
 
14
14
  ## Running External Commands
15
15
 
@@ -27,9 +27,27 @@ Prefer project‑local tools and scripts (for example, bin/ scripts, package.jso
27
27
  - Planning tool: skip for trivial chores; otherwise create a multi-step plan and keep it updated as you work (max one `in_progress` step).
28
28
  - When moving or renaming tracked files, use `git mv` (or `git mv -k`) instead of plain `mv` so history stays intact.
29
29
 
30
+ ## Ruby Guidelines
31
+ - Use the project's Ruby version.
32
+ - Prefer `bundle exec` for project tools.
33
+ - Prefer binstubs when present:
34
+ - `bin/rake`
35
+ - `bin/rspec`
36
+ - `bin/rubocop`
37
+ - Before editing, inspect:
38
+ - `Gemfile`
39
+ - `Gemfile.lock`
40
+ - `*.gemspec`
41
+ - `.rubocop.yml`
42
+ - `.rspec`
43
+ - Run the smallest relevant test first.
44
+ - Preserve existing Ruby idioms.
45
+ - Do not add gems unless necessary.
46
+ - If `ruby-lsp` is available, prefer symbol-aware analysis over broad file dumping when the tool supports that workflow.
47
+
30
48
  ## Repository Snapshot
31
49
  - Ruby gem exposing a SimpleCov coverage CLI (`exe/cov-loupe`) and MCP server; library lives under `lib/cov_loupe/`.
32
- - Key files: main entry point at `lib/cov_loupe.rb`, core modules in `lib/cov_loupe/` including `cli.rb`, `model.rb`, `mcp_server.rb`, and tool implementations in `lib/cov_loupe/tools/*.rb`.
50
+ - Key files: main entry point at `lib/cov_loupe.rb`, core modules in `lib/cov_loupe/` including `cli.rb`, `model/model.rb`, `mcp_server.rb`, and tool implementations in `lib/cov_loupe/tools/*.rb`.
33
51
  - Tests: RSpec under `spec/` with fixtures in `spec/fixtures/`; running tests produces `coverage/.resultset.json` consumed by the tools.
34
52
  - Useful commands:
35
53
  - `bundle install` – install dependencies
@@ -38,7 +56,7 @@ Prefer project‑local tools and scripts (for example, bin/ scripts, package.jso
38
56
  - `cov-loupe list` – table view of coverage data
39
57
 
40
58
  ## Project Overview
41
- `cov-loupe` is a Ruby gem that ships both a CLI and an MCP (Model Context Protocol) server for inspecting SimpleCov coverage data. It reads coverage resultsets directly (SimpleCov is only loaded when multi-suite merges are required) and exposes multiple data formats: file summaries, raw line arrays, uncovered lines, per-line detail, and repo-level tables.
59
+ `cov-loupe` is a Ruby gem that ships both a CLI and an MCP (Model Context Protocol) server for inspecting SimpleCov coverage data. It reads coverage resultsets directly (SimpleCov itself is a runtime dependency and is loaded when multi-suite merges are required) and exposes multiple data formats: file summaries, raw line arrays, uncovered lines, per-line detail, and repo-level tables.
42
60
 
43
61
  ### Key Technologies
44
62
  - **Ruby** – implementation language and packaging format (gem).
@@ -50,15 +68,15 @@ Prefer project‑local tools and scripts (for example, bin/ scripts, package.jso
50
68
  `CovLoupe.run` operates in either CLI mode (default) or MCP server mode (when `-m mcp` or `--mode mcp` is specified). This dual-mode entry point enables both interactive commands and background tool-serving from the same executable.
51
69
 
52
70
  ### Core Components
53
- - `lib/cov_loupe/model.rb` (`CoverageModel`) – core API for querying and shaping coverage data.
71
+ - `lib/cov_loupe/model/model.rb` (`CoverageModel`) – core API for querying and shaping coverage data.
54
72
  - `lib/cov_loupe/cli.rb` (`CoverageCLI`) – CLI interface with subcommands like `list`, `summary`, `raw`, and more.
55
73
  - `lib/cov_loupe/mcp_server.rb` (`MCPServer`) – JSON-RPC server that exposes tools to MCP clients.
56
- - `lib/cov_loupe/tools/*.rb` – tool implementations (`coverage_summary_tool`, `list_tool`, etc.).
57
- - Error handling utilities keep behavior context-aware (friendly CLI output, raised exceptions for libraries, structured MCP responses logged to `./cov_loupe.log`).
74
+ - `lib/cov_loupe/tools/*.rb` – tool implementations (`file_coverage_summary`, `project_coverage`, etc.).
75
+ - Error handling utilities keep behavior context-aware: friendly CLI output, raised exceptions for libraries, and `tools/call` results with `isError: true` for MCP argument-validation and tool-execution failures. Protocol- or dispatch-level failures such as unknown tools remain JSON-RPC errors.
58
76
 
59
77
  ### Coverage Data Flow
60
78
  1. Read SimpleCov `.resultset.json` files without needing SimpleCov at runtime (unless merging suites).
61
- 2. Resolve file paths using absolute match, relative path matching, and basename fallback strategies.
79
+ 2. Resolve file paths using exact normalized matches and project-root-relative matching.
62
80
  3. Provide coverage data in multiple formats: raw arrays, summaries, uncovered lines, per-line details, totals, and formatted tables.
63
81
 
64
82
  ## Building, Running, and Testing
@@ -94,11 +112,14 @@ Use `bundle exec rspec spec/path_spec.rb` to target specific specs when needed.
94
112
  # or
95
113
  cov-loupe --help
96
114
  ```
97
- - Exercise the MCP server manually by piping JSON-RPC:
115
+ - Smoke-test the MCP server manually by piping JSON-RPC:
98
116
  ```sh
99
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/cov_loupe/model.rb"}}}' | bundle exec exe/cov-loupe -m mcp
100
- echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"help_tool","arguments":{}}}' | bundle exec exe/cov-loupe -m mcp
117
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"file_coverage_summary","arguments":{"path":"lib/cov_loupe/model/model.rb"}}}' | bundle exec exe/cov-loupe -m mcp
118
+ echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"help","arguments":{}}}' | bundle exec exe/cov-loupe -m mcp
101
119
  ```
120
+ These commands confirm that the server launches and responds over stdio; they are not exhaustive
121
+ contract tests. Optional validation and error sanity checks are documented in
122
+ [MCP Integration — Error Responses](docs/user/MCP_INTEGRATION.md#error-responses).
102
123
 
103
124
  ### Building
104
125
  ```sh
@@ -118,45 +139,48 @@ The `cov-loupe` executable can be run directly (`bundle exec exe/cov-loupe ...`
118
139
  - `detailed <path>`, `d` – show per-line hit counts and coverage status.
119
140
  - `totals`, `t` – show aggregated totals for the project.
120
141
  - `validate <file|-i code>`, `v` – run a Ruby predicate to enforce coverage policies.
121
- - `version` show version information.
142
+ - Use `-v` / `--version` to print the version string and exit.
122
143
 
123
144
  ## MCP Server Usage
124
145
  Run `cov-loupe` in MCP mode with `-m mcp`/`--mode mcp`. You can issue JSON-RPC requests over stdio, for example:
125
146
  ```
126
- {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"help_tool","arguments":{}}}
127
- {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"coverage_summary_tool","arguments":{"path":"lib/cov_loupe/model.rb"}}}
147
+ {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"help","arguments":{}}}
148
+ {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"file_coverage_summary","arguments":{"path":"lib/cov_loupe/model/model.rb"}}}
128
149
  ```
129
- All responses are emitted as `type: "text"`; JSON objects are returned as JSON strings in the content payload so MCP clients can parse them easily.
150
+ All responses are emitted as `type: "text"`; JSON objects are returned as JSON strings in the content payload so MCP clients can parse them easily. **Check `result.isError` before parsing content as a successful payload** — `isError: true` means the tool call failed (bad path, invalid predicate, missing required argument, invalid enum, etc.). A top-level JSON-RPC `error` response (instead of a `result`) indicates a protocol- or dispatch-level failure, such as an unknown tool.
130
151
 
131
152
  ## Prompt Examples for MCP Clients
132
- - “What’s the coverage percentage for `lib/cov_loupe/model.rb`?” → call `coverage_summary_tool`.
133
- - “Which lines in `spec/fixtures/project1/lib/bar.rb` are uncovered?” → call `uncovered_lines_tool`.
134
- - "Show the repo coverage table sorted worst-first." → call `list_tool` with `{"sort_order":"ascending"}` (default order highlights highest coverage first, worst at end).
135
- - “List files with the worst coverage.” → call `list_tool` (optionally `{"sort_order":"ascending"}`).
136
- - “I’m not sure which tool applies.” → call `help_tool`.
153
+ - “What’s the coverage percentage for `lib/cov_loupe/model/model.rb`?” → call `file_coverage_summary`.
154
+ - “Which lines in `spec/fixtures/project1/lib/bar.rb` are uncovered?” → call `file_uncovered_lines`.
155
+ - "Show the repo coverage table sorted worst-first." → call `project_coverage` with `{"sort_order":"ascending"}` (default order highlights highest coverage first, worst at end).
156
+ - “List files with the worst coverage.” → call `project_coverage` (optionally `{"sort_order":"ascending"}`).
157
+ - “I’m not sure which tool applies.” → call `help`.
137
158
  Always prefer these tools over free-form reasoning to keep responses grounded in actual coverage data.
138
159
 
139
160
  ## MCP Tool Playbook
140
- - Always select an MCP tool over ad-hoc reasoning for coverage data. Unsure which one fits? Call `help_tool`.
141
- - Available tools: `coverage_summary_tool`, `coverage_detailed_tool`, `uncovered_lines_tool`, `coverage_raw_tool`, `list_tool`, `coverage_totals_tool`, `coverage_table_tool`, `validate_tool`, `help_tool`, and `version_tool`.
142
- - Responses return deterministic JSON/text; surface the tool output directly unless the user asks for interpretation. Note that `list_tool` now includes `skipped_files`, `missing_tracked_files`, `newer_files`, and `deleted_files` arrays in its output to report any files that could not be processed due to errors or staleness.
161
+ - Always select an MCP tool over ad-hoc reasoning for coverage data. Unsure which one fits? Call `help`.
162
+ - Available tools: `file_coverage_summary`, `file_coverage_detailed`, `file_uncovered_lines`, `file_coverage_raw`, `project_coverage`, `project_coverage_totals`, `project_validate`, `help`, and `version`.
163
+ - Check `result.isError` before parsing tool response content. `isError: false` means the tool succeeded; `isError: true` means the call failed (bad path, invalid predicate, stale coverage, missing required argument, invalid enum, etc.) and the `content` carries a friendly error message. A top-level JSON-RPC `error` object (not a `result`) indicates a protocol- or dispatch-level failure, such as an unknown tool.
164
+ - On success, responses return deterministic JSON/text; surface the tool output directly unless the user asks for interpretation. Note that `project_coverage` now includes `skipped_files`, `missing_tracked_files`, `newer_files`, `deleted_files`, `length_mismatch_files`, and `unreadable_files` arrays in its output to report any files that could not be processed due to errors or staleness.
143
165
 
144
166
  ## Development Conventions
145
167
  - Target Ruby >= 3.2; use two-space indentation and `# frozen_string_literal: true` in Ruby files.
146
- - Match existing style and patterns (see `CoverageModel` and `CovUtil` helpers). Comments should clarify non-obvious logic only.
168
+ - Match existing style and patterns (see `CoverageModel` and `CoverageCalculator` helpers). Comments should clarify non-obvious logic only.
147
169
  - Never undo or overwrite user changes outside your scope; integrate with them instead. However, if the new changes would be better implemented by modifying other sections, e.g., extracting now-duplicated behavior into a special method, then do that.
148
170
  - When adding behavior, couple it with tests; keep or raise coverage. Specs belong in `spec/**/*_spec.rb` mirroring the lib path.
149
171
  - Validate meaningful changes with `bundle exec rspec` when feasible; note skipped verification in your summary if you cannot run it.
150
- - The codebase follows standard Ruby conventions and emphasizes user-friendly CLI output, structured MCP responses, and rich error handling.
172
+ - The codebase follows standard Ruby conventions and emphasizes user-friendly CLI output, `isError: true` results for MCP argument-validation and tool-execution failures, JSON-RPC errors for protocol- or dispatch-level failures, and rich error handling.
151
173
 
152
174
  ### Error Handling Strategy
153
175
  - **CLI mode** – render user-friendly messages, respect exit codes, and support optional debug output.
154
176
  - **Library mode** – raise custom exceptions for programmatic handling.
155
- - **MCP server mode** – return structured error responses and log context to `./cov_loupe.log`.
177
+ - **MCP server mode** – return `tools/call` results with `isError: true` for failed calls, including argument-validation and tool-execution failures; reserve JSON-RPC errors for protocol- or dispatch-level failures such as unknown tools, and log execution-error context to `./cov_loupe.log`.
156
178
 
157
179
  ### Path Resolution Strategy
158
- 1. Attempt exact absolute path matches within the coverage data.
159
- 2. Retry using paths without the working-directory prefix.
180
+ 1. Attempt exact normalized path matches within the coverage data.
181
+ 2. Retry using paths without the project-root prefix.
182
+
183
+ On case-insensitive volumes, comparisons are case-normalized; on case-sensitive volumes, case must match exactly.
160
184
 
161
185
  ### Resultset Discovery
162
186
  - The tool locates `.resultset.json` by checking default paths or by honoring explicit CLI/MCP arguments. See [Configuring the Resultset](README.md#configuring-the-resultset) for details.
@@ -179,7 +203,7 @@ Always prefer these tools over free-form reasoning to keep responses grounded in
179
203
 
180
204
  ## Response Expectations
181
205
  - Be concise and collaborative. Lead with the change/insight; follow with necessary detail.
182
- - Reference files with inline clickable paths (e.g., `lib/cov_loupe/model.rb:42`). Avoid ranges and external URIs.
206
+ - Reference files with inline clickable paths (e.g., `lib/cov_loupe/model/model.rb:42`). Avoid ranges and external URIs.
183
207
  - When providing content intended for the user to copy and paste (like commit messages or configuration snippets), do not include line numbers or any other decorators that would interfere with direct usage.
184
208
  - Summaries use plain bullets (`-`). Offer next steps only when they flow naturally (tests, commits, builds, validation).
185
209
  - Do not dump entire files; mention paths. Keep tone factual, note open questions, and highlight testing gaps.
@@ -216,15 +240,18 @@ Read-only file system @ rb_sysopen
216
240
  bundle exec rubocop --cache false
217
241
  ```
218
242
 
219
- This disables caching and adds approximately 5 seconds to execution time (3s → 8s) but ensures successful analysis in sandboxed environments. See [dev/prompts/ai-code-evaluator-guidelines.md](dev/prompts/ai-code-evaluator-guidelines.md) for details on why caching is enabled by default.
243
+ This disables caching and adds approximately 5 seconds to execution time (3s → 8s) but ensures successful analysis in sandboxed environments. See [dev/prompts/guidelines/ai-code-evaluator-guidelines.md](dev/prompts/guidelines/ai-code-evaluator-guidelines.md) for details on why caching is enabled by default.
220
244
 
221
245
  ## Documentation
222
246
  - `README.md` – primary documentation for installation, CLI usage, MCP integration, troubleshooting, and resultset configuration.
223
247
  - `docs/user/` – user-facing guides, examples, and troubleshooting.
224
248
  - `docs/dev/` – deeper architecture notes, contributing details, and decisions.
225
249
 
250
+ ### Migration Docs
251
+ Migration documentation must accurately reflect the state of the project at the version it describes. Do not retroactively update migration docs with changes (such as renamed methods or moved files) that did not exist in that version. Each version's migration guide should describe only the changes and APIs that were correct at the time of that release.
252
+
226
253
  ## Important Conventions
227
254
  - Require files via `cov_loupe` paths.
228
255
  - Ensure API paths work with both absolute and relative inputs.
229
256
  - The executable name is `cov-loupe` (hyphenated).
230
- - Keep CLI error messages user-friendly and MCP responses structured.
257
+ - Keep CLI error messages user-friendly, MCP argument-validation and tool-execution failures flagged with `isError: true`, and protocol- or dispatch-level failures represented as JSON-RPC errors.
data/CONTRIBUTING.md CHANGED
@@ -2,101 +2,133 @@
2
2
 
3
3
  [Back to main README](docs/index.md)
4
4
 
5
- Thank you for your interest in contributing!
6
- This project welcomes bug reports, improvements, and suggestions that make it more useful and reliable for the Ruby community.
5
+ Thank you for your interest in contributing.
6
+
7
+ Bug reports, feature proposals, documentation suggestions, and other feedback are welcome.
7
8
 
8
9
  ---
9
10
 
10
- ## How to Contribute
11
+ ## Before Submitting a Pull Request
12
+
13
+ Please do not submit a pull request unless you have first opened an issue and received explicit approval from the maintainer to proceed.
14
+
15
+ Discussing a proposal in an issue does not by itself constitute approval. Please wait until the maintainer specifically confirms that a pull request would be welcome.
16
+
17
+ This project is maintained by a single developer. Even a well-intentioned and technically sound pull request can require substantial review, testing, discussion, and ongoing maintenance. A proposed change may also conflict with the project's scope, design, priorities, or planned work.
18
+
19
+ The contribution process is:
20
+
21
+ 1. Open an issue describing the problem or proposed improvement.
22
+ 2. Discuss the desired behavior and, when useful, the likely implementation.
23
+ 3. Wait for explicit approval to prepare a pull request.
24
+ 4. Submit a pull request only after receiving that approval.
25
+
26
+ Pull requests submitted without prior approval may be closed without detailed review.
27
+
28
+ ### AI-Assisted Contributions
29
+
30
+ AI-assisted work is welcomed. The same prior-approval requirement applies whether the work is produced manually or with AI assistance.
31
+
32
+ Contributors are responsible for supervising and validating their work. A pull request should not shift the primary burden of reviewing, debugging, or establishing correctness to the maintainer.
33
+
34
+ ---
35
+
36
+ ## Reporting Issues
37
+
38
+ Before opening an issue:
39
+
40
+ - Check whether an existing issue already addresses the subject.
41
+ - Include clear reproduction steps when reporting a problem.
42
+ - Describe the expected and actual behavior.
43
+ - Include your Ruby version (`ruby -v`), operating system, and any other relevant environment information.
44
+ - Keep discussion technical and respectful. See the [Code of Conduct](docs/code_of_conduct.md).
45
+
46
+ ---
47
+
48
+ ## Preparing an Approved Change
49
+
50
+ After receiving explicit approval to submit a pull request:
11
51
 
12
- ### 1. Reporting Issues
13
- - Check existing issues before opening a new one.
14
- - Include clear reproduction steps, expected vs. actual results, and your Ruby version (`ruby -v`) and OS.
15
- - Keep discussion technical and respectful — see the [Code of Conduct](docs/code_of_conduct.md).
52
+ 1. Fork the repository on GitHub.
53
+ 2. Create a branch for your work:
16
54
 
17
- ### 2. Submitting Changes
18
- 1. **Fork** the repository on GitHub.
19
- 1. **Create a branch** for your work:
20
55
  ```bash
21
56
  git checkout -b feature/my-change
22
57
  ```
23
- 1. **Install dependencies**:
58
+
59
+ 3. Install dependencies:
60
+
24
61
  ```bash
25
62
  bundle install
26
63
  ```
27
- 1. Make your changes, conforming to the project's coding style.
28
- 1. **Run tests** to verify your changes:
64
+
65
+ 4. Make your changes, following the project's existing coding style.
66
+ 5. Run the tests:
67
+
29
68
  ```bash
30
69
  bundle exec rspec
31
70
  ```
32
- 1. **Lint the code**:
71
+
72
+ 6. Run RuboCop:
73
+
33
74
  ```bash
34
75
  bundle exec rubocop
35
76
  ```
36
- 1. Commit changes with clear, concise messages following conventional commit style (e.g. `fix: handle missing file gracefully`).
37
- 1. **Push** your branch and open a **Pull Request** against `main`.
38
77
 
39
- PRs should:
40
- - Include or update tests for new/changed behavior.
41
- - Pass all existing tests and RuboCop checks.
42
- - Update documentation or README examples if behavior changes.
78
+ 7. Commit the changes with a clear, informative message.
79
+ 8. Push the branch and open a pull request against `main`.
80
+
81
+ Pull requests should:
82
+
83
+ - Link to the issue in which the change was approved.
84
+ - Include or update tests for new or changed behavior.
85
+ - Pass all existing tests and RuboCop checks.
86
+ - Update documentation and examples when behavior changes.
87
+ - Explain how the change was tested and validated.
43
88
 
44
89
  ---
45
90
 
46
91
  ## Development Setup
47
92
 
48
- This project requires Ruby >= 3.2 (due to the `mcp` gem dependency). Typical workflow:
93
+ This project requires Ruby 3.2 or later because of the `mcp` gem dependency.
94
+
95
+ A typical setup is:
49
96
 
50
97
  ```bash
51
98
  git clone https://github.com/keithrbennett/cov-loupe.git
52
99
  cd cov-loupe
53
100
  bundle install
54
- rspec
101
+ bundle exec rspec
55
102
  ```
56
103
 
57
- Optional tools:
58
- - `rake` as an alternate way to run `rspec` and `rubocop`
59
- - `exe/cov-loupe` the CLI and MCP entry point, use for end-to-end runs
104
+ Useful commands and entry points include:
105
+
106
+ - `bundle exec rspec` run the test suite
107
+ - `bundle exec rubocop` — run static analysis and style checks
108
+ - `bundle exec rake` — run the default Rake tasks
109
+ - `exe/cov-loupe` — run the CLI or MCP entry point for end-to-end testing
60
110
 
61
111
  ---
62
112
 
63
113
  ## Documentation
64
114
 
65
- This project uses [MkDocs](https://www.mkdocs.org/) with the [Material theme](https://squidfunk.github.io/mkdocs-material/) to build and serve documentation.
115
+ This project uses [MkDocs](https://www.mkdocs.org/) with the [Material theme](https://squidfunk.github.io/mkdocs-material/) to build and serve its documentation.
116
+
117
+ To run the documentation locally:
66
118
 
67
- **Quick start:**
68
119
  ```bash
69
120
  pip3 install -r requirements.txt
70
- mkdocs serve # View at http://127.0.0.1:8000
121
+ mkdocs serve
71
122
  ```
72
123
 
73
- For detailed platform-specific installation instructions (macOS, Linux, Windows) and troubleshooting, see the [Documentation Development](docs/dev/DEVELOPMENT.md#documentation-development) section of the Development Guide
74
-
75
- ---
124
+ The documentation will be available at <http://127.0.0.1:8000>.
76
125
 
77
- ## Release Process (maintainer only)
126
+ For detailed platform-specific installation instructions and troubleshooting, see [Documentation Development](docs/dev/DEVELOPMENT.md#documentation-development).
78
127
 
79
- 1. Update version in `lib/cov_loupe/version.rb`
80
- 2. Update `RELEASE_NOTES.md`
81
- 3. Commit, tag, and push:
82
- ```bash
83
- git add -A
84
- git commit -m "Bump version to 1.0.0, update release notes"
85
- git tag -a v1.0.0 -m "v1.0.0 - brief summary of release"
86
- git push origin main --tags
87
- ```
88
- 4. Build and publish:
89
- ```bash
90
- gem build cov-loupe.gemspec
91
- gem push cov-loupe-#{version-string}.gem
92
- ```
93
128
  ---
94
129
 
95
130
  ## Code of Conduct
96
131
 
97
- Please review and follow the [Code of Conduct](docs/code_of_conduct.md).
98
- Instances of unacceptable behavior may be reported through GitHub’s [Report Abuse form](https://github.com/contact/report-abuse).
99
-
100
- ---
132
+ Please review and follow the [Code of Conduct](docs/code_of_conduct.md).
101
133
 
102
- Thank you for helping improve **cov-loupe**!
134
+ Instances of unacceptable behavior may be reported through GitHub's [Report Abuse form](https://github.com/contact/report-abuse).