rigortype 0.2.1 → 0.2.3
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/README.md +41 -14
- data/docs/handbook/01-getting-started.md +311 -0
- data/docs/handbook/02-everyday-types.md +337 -0
- data/docs/handbook/03-narrowing.md +359 -0
- data/docs/handbook/04-tuples-and-shapes.md +321 -0
- data/docs/handbook/05-methods-and-blocks.md +339 -0
- data/docs/handbook/06-classes.md +305 -0
- data/docs/handbook/07-rbs-and-extended.md +427 -0
- data/docs/handbook/08-understanding-errors.md +373 -0
- data/docs/handbook/09-plugins.md +241 -0
- data/docs/handbook/10-sorbet.md +347 -0
- data/docs/handbook/11-sig-gen.md +312 -0
- data/docs/handbook/12-lightweight-hkt.md +333 -0
- data/docs/handbook/README.md +275 -0
- data/docs/handbook/appendix-elixir.md +370 -0
- data/docs/handbook/appendix-go.md +399 -0
- data/docs/handbook/appendix-java-csharp.md +470 -0
- data/docs/handbook/appendix-liskov.md +580 -0
- data/docs/handbook/appendix-mypy.md +370 -0
- data/docs/handbook/appendix-phpstan.md +338 -0
- data/docs/handbook/appendix-protocols-and-structural-typing.md +292 -0
- data/docs/handbook/appendix-rust.md +446 -0
- data/docs/handbook/appendix-steep.md +336 -0
- data/docs/handbook/appendix-type-theory.md +1662 -0
- data/docs/handbook/appendix-typeprof.md +416 -0
- data/docs/handbook/appendix-typescript.md +332 -0
- data/docs/install.md +189 -0
- data/docs/llms.txt +72 -0
- data/docs/manual/01-installation.md +342 -0
- data/docs/manual/02-cli-reference.md +569 -0
- data/docs/manual/03-configuration.md +152 -0
- data/docs/manual/04-diagnostics.md +206 -0
- data/docs/manual/05-inspecting-types.md +109 -0
- data/docs/manual/06-baseline.md +104 -0
- data/docs/manual/07-plugins.md +92 -0
- data/docs/manual/08-skills.md +143 -0
- data/docs/manual/09-editor-integration.md +245 -0
- data/docs/manual/10-mcp-server.md +539 -0
- data/docs/manual/11-ci.md +274 -0
- data/docs/manual/12-caching.md +116 -0
- data/docs/manual/13-troubleshooting.md +120 -0
- data/docs/manual/14-rails-quickstart.md +332 -0
- data/docs/manual/15-type-protection-coverage.md +204 -0
- data/docs/manual/16-rbs-extended-annotations.md +190 -0
- data/docs/manual/17-driving-improvement.md +160 -0
- data/docs/manual/README.md +87 -0
- data/docs/manual/ci-templates/README.md +58 -0
- data/docs/manual/plugins/README.md +86 -0
- data/docs/manual/plugins/rigor-actioncable.md +78 -0
- data/docs/manual/plugins/rigor-actionmailer.md +74 -0
- data/docs/manual/plugins/rigor-actionpack.md +80 -0
- data/docs/manual/plugins/rigor-activejob.md +58 -0
- data/docs/manual/plugins/rigor-activerecord.md +102 -0
- data/docs/manual/plugins/rigor-activestorage.md +74 -0
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +86 -0
- data/docs/manual/plugins/rigor-devise.md +70 -0
- data/docs/manual/plugins/rigor-dry-schema.md +56 -0
- data/docs/manual/plugins/rigor-dry-struct.md +60 -0
- data/docs/manual/plugins/rigor-dry-types.md +59 -0
- data/docs/manual/plugins/rigor-dry-validation.md +62 -0
- data/docs/manual/plugins/rigor-factorybot.md +76 -0
- data/docs/manual/plugins/rigor-graphql.md +89 -0
- data/docs/manual/plugins/rigor-hanami.md +83 -0
- data/docs/manual/plugins/rigor-mangrove.md +73 -0
- data/docs/manual/plugins/rigor-minitest.md +86 -0
- data/docs/manual/plugins/rigor-pundit.md +72 -0
- data/docs/manual/plugins/rigor-rails-i18n.md +92 -0
- data/docs/manual/plugins/rigor-rails-routes.md +94 -0
- data/docs/manual/plugins/rigor-rails.md +44 -0
- data/docs/manual/plugins/rigor-rbs-inline.md +83 -0
- data/docs/manual/plugins/rigor-rspec-rails.md +72 -0
- data/docs/manual/plugins/rigor-rspec.md +86 -0
- data/docs/manual/plugins/rigor-shoulda-matchers.md +78 -0
- data/docs/manual/plugins/rigor-sidekiq.md +78 -0
- data/docs/manual/plugins/rigor-sinatra.md +61 -0
- data/docs/manual/plugins/rigor-sorbet.md +63 -0
- data/docs/manual/plugins/rigor-statesman.md +75 -0
- data/docs/manual/plugins/rigor-typescript-utility-types.md +71 -0
- data/exe/rigor +1 -1
- data/lib/rigor/analysis/incremental_session.rb +4 -2
- data/lib/rigor/analysis/run_stats.rb +13 -1
- data/lib/rigor/analysis/runner.rb +54 -12
- data/lib/rigor/cli/check_command.rb +1 -1
- data/lib/rigor/cli/docs_command.rb +248 -0
- data/lib/rigor/cli/skill_command.rb +103 -41
- data/lib/rigor/cli/skill_describe.rb +346 -0
- data/lib/rigor/cli/triage_command.rb +8 -2
- data/lib/rigor/cli/triage_renderer.rb +4 -0
- data/lib/rigor/cli.rb +25 -3
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +124 -32
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +37 -6
- data/lib/rigor/inference/scope_indexer.rb +87 -89
- data/lib/rigor/plugin/isolation.rb +5 -5
- data/lib/rigor/plugin/loader.rb +4 -2
- data/lib/rigor/triage/catalogue.rb +16 -1
- data/lib/rigor/triage.rb +30 -7
- data/lib/rigor/version.rb +1 -1
- data/skills/rigor-ask/SKILL.md +172 -0
- data/skills/rigor-doctor/SKILL.md +87 -0
- data/skills/rigor-editor-setup/SKILL.md +114 -0
- data/skills/rigor-mcp-setup/SKILL.md +117 -0
- data/skills/rigor-monkeypatch-resolve/SKILL.md +79 -0
- data/skills/rigor-next-steps/SKILL.md +113 -0
- data/skills/rigor-plugin-tune/SKILL.md +79 -0
- data/skills/rigor-protection-uplift/SKILL.md +133 -0
- data/skills/rigor-rbs-setup/SKILL.md +128 -0
- data/skills/rigor-upgrade/SKILL.md +79 -0
- metadata +90 -1
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
# Rigor MCP Server — AI Agent Integration
|
|
2
|
+
|
|
3
|
+
`rigor mcp` is the Model Context Protocol (MCP) server bundled with the
|
|
4
|
+
`rigortype` gem. It exposes Rigor's analysis tools as JSON-RPC 2.0 tool
|
|
5
|
+
calls over a newline-delimited stdio stream, so AI coding assistants —
|
|
6
|
+
Claude Code, Cursor, Cline, VS Code Copilot Chat, and any other
|
|
7
|
+
MCP-aware agent — can call Rigor directly during a session.
|
|
8
|
+
|
|
9
|
+
## MCP vs LSP — choosing the right integration
|
|
10
|
+
|
|
11
|
+
Both `rigor lsp` and `rigor mcp` expose the same underlying engine.
|
|
12
|
+
The difference is the consumer.
|
|
13
|
+
|
|
14
|
+
| | `rigor lsp` | `rigor mcp` |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| Protocol | Language Server Protocol | Model Context Protocol |
|
|
17
|
+
| Consumer | Your editor | An AI coding agent |
|
|
18
|
+
| Interaction | Continuous (push diagnostics on every save) | On-demand (agent calls a tool when it decides to) |
|
|
19
|
+
| Transport | stdio (TCP queued) | stdio (HTTP queued) |
|
|
20
|
+
| When to use | Editor integration | AI-assisted development |
|
|
21
|
+
|
|
22
|
+
Use `rigor lsp` to get inline diagnostics and hover in Neovim, VS Code,
|
|
23
|
+
Helix, or Emacs. Use `rigor mcp` to let an AI agent check types before
|
|
24
|
+
suggesting a refactor, look up the type at a cursor position, or triage
|
|
25
|
+
a project's diagnostic set as context for a code-review session.
|
|
26
|
+
|
|
27
|
+
There is no conflict in running both simultaneously.
|
|
28
|
+
|
|
29
|
+
## Tools at a glance
|
|
30
|
+
|
|
31
|
+
| Tool | Underlying command | Returns |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `rigor_check` | `rigor check --format json` | JSON diagnostic report |
|
|
34
|
+
| `rigor_type_of` | `rigor type-of --format json` | JSON type at `FILE:LINE:COL` |
|
|
35
|
+
| `rigor_triage` | `rigor triage --format json` | JSON distribution + class/method selectors + hotspots + hints |
|
|
36
|
+
| `rigor_annotate` | `rigor annotate --no-color` | Annotated Ruby source |
|
|
37
|
+
| `rigor_sig_gen` | `rigor sig-gen --print --format json` | JSON RBS skeleton candidates |
|
|
38
|
+
| `rigor_explain` | `rigor explain --format json` | JSON rule catalog entries |
|
|
39
|
+
| `rigor_coverage` | `rigor coverage --format json` | JSON precision-tier breakdown |
|
|
40
|
+
|
|
41
|
+
All tools are read-only. Write-side operations (`rigor init`,
|
|
42
|
+
`rigor baseline generate`, `rigor sig-gen --write`) are intentionally
|
|
43
|
+
excluded — modifying project files is the developer's call, not an
|
|
44
|
+
agent's tool call.
|
|
45
|
+
|
|
46
|
+
## Prerequisites
|
|
47
|
+
|
|
48
|
+
The single prerequisite is **`rigor` on your `PATH`** — the same
|
|
49
|
+
executable `rigor check` and `rigor lsp` already use. Any install
|
|
50
|
+
channel in [Installing Rigor](01-installation.md) provides it; `mise`
|
|
51
|
+
is the recommended channel because its shims make `rigor` available to
|
|
52
|
+
processes (and AI agents) that do not inherit your shell environment.
|
|
53
|
+
|
|
54
|
+
Do **not** add `rigortype` to your project's `Gemfile`. Rigor is a
|
|
55
|
+
tool, not a library. See
|
|
56
|
+
[Installing Rigor § Recommended — a runtime version manager](01-installation.md#recommended--a-runtime-version-manager).
|
|
57
|
+
|
|
58
|
+
## CLI
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
rigor mcp [--transport=stdio] [--config=PATH]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- `--transport=stdio` — default; only value accepted in v1. HTTP
|
|
65
|
+
transport is queued for v2.
|
|
66
|
+
- `--config=PATH` — session-level default config path. Individual tool
|
|
67
|
+
calls may supply their own `config` argument, which takes precedence.
|
|
68
|
+
Without either, `Configuration.discover` walks `.rigor.yml` /
|
|
69
|
+
`.rigor.dist.yml` from the working directory.
|
|
70
|
+
|
|
71
|
+
Exit codes: 0 (clean shutdown — stdin EOF), 64 (unknown
|
|
72
|
+
`--transport`).
|
|
73
|
+
|
|
74
|
+
## Client wiring
|
|
75
|
+
|
|
76
|
+
### Claude Desktop
|
|
77
|
+
|
|
78
|
+
Add an entry to `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
79
|
+
(macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"mcpServers": {
|
|
84
|
+
"rigor": {
|
|
85
|
+
"command": "rigor",
|
|
86
|
+
"args": ["mcp"]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Restart Claude Desktop. The `rigor_check`, `rigor_type_of`, and other
|
|
93
|
+
tools will appear in the model's tool palette. To pin the analysis to a
|
|
94
|
+
specific project config:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"mcpServers": {
|
|
99
|
+
"rigor": {
|
|
100
|
+
"command": "rigor",
|
|
101
|
+
"args": ["mcp", "--config=/path/to/project/.rigor.yml"]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Claude Code CLI
|
|
108
|
+
|
|
109
|
+
Claude Code reads MCP server definitions from its project-level
|
|
110
|
+
settings. Add to `.claude/settings.json` in your project root:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"mcpServers": {
|
|
115
|
+
"rigor": {
|
|
116
|
+
"command": "rigor",
|
|
117
|
+
"args": ["mcp"]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Or register it globally in `~/.claude/settings.json` so it is
|
|
124
|
+
available in every project. Once registered, Claude Code can call
|
|
125
|
+
`rigor_check` on files it is about to edit, use `rigor_type_of` to
|
|
126
|
+
ground a suggestion, and run `rigor_triage` to understand a project's
|
|
127
|
+
diagnostic shape before proposing a cleanup plan.
|
|
128
|
+
|
|
129
|
+
### Cursor
|
|
130
|
+
|
|
131
|
+
Add to `.cursor/mcp.json` (project root) or `~/.cursor/mcp.json`
|
|
132
|
+
(user-level):
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"mcpServers": {
|
|
137
|
+
"rigor": {
|
|
138
|
+
"command": "rigor",
|
|
139
|
+
"args": ["mcp"]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Cursor's Composer will then offer Rigor tools alongside its built-in
|
|
146
|
+
capabilities. `rigor_check` is especially useful before a Composer
|
|
147
|
+
refactor — run it first so the agent knows the current diagnostic
|
|
148
|
+
baseline, then compare after.
|
|
149
|
+
|
|
150
|
+
### Cline (VS Code extension)
|
|
151
|
+
|
|
152
|
+
Open the Cline panel → MCP Servers → Add Server → Custom, and fill in:
|
|
153
|
+
|
|
154
|
+
| Field | Value |
|
|
155
|
+
|---|---|
|
|
156
|
+
| Name | `rigor` |
|
|
157
|
+
| Command | `rigor` |
|
|
158
|
+
| Args | `["mcp"]` |
|
|
159
|
+
|
|
160
|
+
Or add directly to Cline's `cline_mcp_settings.json`:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"rigor": {
|
|
166
|
+
"command": "rigor",
|
|
167
|
+
"args": ["mcp"]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Generic / custom MCP client
|
|
174
|
+
|
|
175
|
+
`rigor mcp` speaks the [MCP stdio transport](https://spec.modelcontextprotocol.io/specification/basic/transports/#stdio):
|
|
176
|
+
one JSON-RPC 2.0 message per line, `\n`-terminated, no
|
|
177
|
+
`Content-Length` framing. Any client that follows this convention
|
|
178
|
+
works. The initialization sequence:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
→ {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}
|
|
182
|
+
← {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"rigor","version":"0.2.1"}}}
|
|
183
|
+
→ {"jsonrpc":"2.0","method":"notifications/initialized"}
|
|
184
|
+
→ {"jsonrpc":"2.0","id":1,"method":"tools/list"}
|
|
185
|
+
← {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
All messages except `notifications/*` require a response.
|
|
189
|
+
`notifications/*` carry no `id` and are silently consumed.
|
|
190
|
+
|
|
191
|
+
## Tool reference
|
|
192
|
+
|
|
193
|
+
### rigor_check
|
|
194
|
+
|
|
195
|
+
Analyze one or more Ruby files or directories for type errors,
|
|
196
|
+
undefined methods, arity mismatches, and nil-receiver risks.
|
|
197
|
+
|
|
198
|
+
**Input:**
|
|
199
|
+
|
|
200
|
+
| Argument | Type | Required | Default |
|
|
201
|
+
|---|---|---|---|
|
|
202
|
+
| `paths` | `string[]` | yes | — |
|
|
203
|
+
| `config` | `string` | no | session default |
|
|
204
|
+
|
|
205
|
+
**Returns:** JSON — the same structure as `rigor check --format json`.
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"diagnostics": [
|
|
210
|
+
{
|
|
211
|
+
"path": "app/models/user.rb",
|
|
212
|
+
"line": 42,
|
|
213
|
+
"column": 5,
|
|
214
|
+
"rule": "call.undefined-method",
|
|
215
|
+
"severity": "error",
|
|
216
|
+
"message": "undefined method `naem` for String"
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
`isError` is `false` when the run completes normally, even if
|
|
223
|
+
diagnostics were found. `isError: true` signals a configuration or
|
|
224
|
+
runtime failure (bad path, unreadable config, etc.).
|
|
225
|
+
|
|
226
|
+
**Typical agent use:** call `rigor_check` on the files an agent is
|
|
227
|
+
about to edit, record the baseline, apply the edit, call again, diff
|
|
228
|
+
the two diagnostic arrays to see whether the change introduced or
|
|
229
|
+
resolved issues.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### rigor_type_of
|
|
234
|
+
|
|
235
|
+
Get the inferred type of the expression at a specific source location.
|
|
236
|
+
|
|
237
|
+
**Input:**
|
|
238
|
+
|
|
239
|
+
| Argument | Type | Required |
|
|
240
|
+
|---|---|---|
|
|
241
|
+
| `file` | `string` | yes |
|
|
242
|
+
| `line` | `integer` (1-based) | yes |
|
|
243
|
+
| `col` | `integer` (1-based) | yes |
|
|
244
|
+
| `config` | `string` | no |
|
|
245
|
+
|
|
246
|
+
**Returns:** JSON — the same as `rigor type-of --format json`.
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"file": "lib/order.rb",
|
|
251
|
+
"line": 17,
|
|
252
|
+
"column": 10,
|
|
253
|
+
"node": "LocalVariableReadNode",
|
|
254
|
+
"type": "Integer | nil",
|
|
255
|
+
"erased": "Integer?"
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Typical agent use:** ground a hover explanation ("what type is `x`
|
|
260
|
+
at this cursor position?") or validate a type assumption before
|
|
261
|
+
generating a signature.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### rigor_triage
|
|
266
|
+
|
|
267
|
+
Summarize a project's diagnostic stream: rule distribution,
|
|
268
|
+
class/method selectors, per-file hotspots, and heuristic hints for
|
|
269
|
+
the most common error clusters.
|
|
270
|
+
|
|
271
|
+
**Input:**
|
|
272
|
+
|
|
273
|
+
| Argument | Type | Required | Default |
|
|
274
|
+
|---|---|---|---|
|
|
275
|
+
| `paths` | `string[]` | no | configured paths |
|
|
276
|
+
| `top` | `integer` | no | `10` |
|
|
277
|
+
| `config` | `string` | no | session default |
|
|
278
|
+
|
|
279
|
+
**Returns:** JSON — the same as `rigor triage --format json`.
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"summary": { "total": 488, "error": 480, "warning": 8, "info": 0 },
|
|
284
|
+
"distribution": [
|
|
285
|
+
{ "rule": "call.possible-nil-receiver", "count": 212 }
|
|
286
|
+
],
|
|
287
|
+
"selectors": [
|
|
288
|
+
{ "receiver": "String", "method": "squish", "count": 31, "files": 12,
|
|
289
|
+
"rules": { "call.undefined-method": 31 } }
|
|
290
|
+
],
|
|
291
|
+
"hotspots": [
|
|
292
|
+
{ "file": "app/models/account.rb", "count": 38,
|
|
293
|
+
"by_rule": { "call.possible-nil-receiver": 30 } }
|
|
294
|
+
],
|
|
295
|
+
"hints": [
|
|
296
|
+
{ "id": "activesupport-core-ext", "confidence": "likely",
|
|
297
|
+
"diagnostic_count": 365, "summary": "...", "action": "..." }
|
|
298
|
+
],
|
|
299
|
+
"include_info": false
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
By default the `distribution` / `selectors` / `hotspots` arrays count
|
|
304
|
+
only the actionable diagnostics (`error` + `warning`); `info` (mostly
|
|
305
|
+
plugin recognition trace) is excluded, so those counts do not sum to
|
|
306
|
+
`summary.total` and `include_info` is `false`. `summary.info` still
|
|
307
|
+
reports the full info count, and the hints still see every diagnostic.
|
|
308
|
+
|
|
309
|
+
The `selectors` array is the by-(class, method) axis: each row is a
|
|
310
|
+
dispatch target with its `count`, distinct-`files` spread, and
|
|
311
|
+
per-`rule` breakdown, keyed on a normalised receiver class — so an
|
|
312
|
+
agent answers "which method concentrates the diagnostics?" from
|
|
313
|
+
structured fields, never by parsing a `message`.
|
|
314
|
+
|
|
315
|
+
**Typical agent use:** run `rigor_triage` at the start of a code
|
|
316
|
+
review or cleanup session to understand the diagnostic landscape
|
|
317
|
+
before deciding which rules and files to focus on — sort `selectors`
|
|
318
|
+
by `count` for the highest-leverage class/method, or filter by
|
|
319
|
+
`files` to separate systemic clusters from one-off bugs.
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
### rigor_annotate
|
|
324
|
+
|
|
325
|
+
Return the given Ruby source file with each line's last-expression
|
|
326
|
+
type appended as a `#=>` comment. `def` header lines show
|
|
327
|
+
the method's inferred return type.
|
|
328
|
+
|
|
329
|
+
**Input:**
|
|
330
|
+
|
|
331
|
+
| Argument | Type | Required |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| `file` | `string` | yes |
|
|
334
|
+
| `config` | `string` | no |
|
|
335
|
+
|
|
336
|
+
**Returns:** Plain text (annotated Ruby source). Not JSON.
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
module Rigor
|
|
340
|
+
VERSION = "0.2.1" #=> "0.2.1"
|
|
341
|
+
end
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Typical agent use:** understand how Rigor infers types through a
|
|
345
|
+
specific file without having to call `rigor_type_of` line by line.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### rigor_sig_gen
|
|
350
|
+
|
|
351
|
+
Generate RBS skeleton signatures inferred from Ruby source files.
|
|
352
|
+
|
|
353
|
+
**Input:**
|
|
354
|
+
|
|
355
|
+
| Argument | Type | Required | Default |
|
|
356
|
+
|---|---|---|---|
|
|
357
|
+
| `paths` | `string[]` | no | configured paths |
|
|
358
|
+
| `params` | `"untyped"` \| `"observed"` | no | `"untyped"` |
|
|
359
|
+
| `config` | `string` | no | session default |
|
|
360
|
+
|
|
361
|
+
`params: "observed"` harvests call-site argument types from `spec/`
|
|
362
|
+
(or a directory named via `--observe=PATH` in the underlying CLI).
|
|
363
|
+
|
|
364
|
+
**Returns:** JSON — the same as `rigor sig-gen --print --format json`.
|
|
365
|
+
|
|
366
|
+
```json
|
|
367
|
+
{
|
|
368
|
+
"candidates": [
|
|
369
|
+
{
|
|
370
|
+
"class_name": "Order",
|
|
371
|
+
"method_name": "total",
|
|
372
|
+
"kind": "instance",
|
|
373
|
+
"classification": "new-method",
|
|
374
|
+
"rbs": "def total: () -> Integer"
|
|
375
|
+
}
|
|
376
|
+
]
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Classifications: `new-file`, `new-method`, `tighter-return`,
|
|
381
|
+
`equivalent`, `skipped`.
|
|
382
|
+
|
|
383
|
+
**Typical agent use:** call `rigor_sig_gen` to see which methods have
|
|
384
|
+
precise enough returns to be worth writing into `sig/`, then generate
|
|
385
|
+
and insert the RBS. The agent should NOT write signatures
|
|
386
|
+
automatically — present the candidates for human review, then apply
|
|
387
|
+
confirmed entries via `rigor sig-gen --write`.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
### rigor_explain
|
|
392
|
+
|
|
393
|
+
Look up the description of one or all Rigor diagnostic rules.
|
|
394
|
+
|
|
395
|
+
**Input:**
|
|
396
|
+
|
|
397
|
+
| Argument | Type | Required | Notes |
|
|
398
|
+
|---|---|---|---|
|
|
399
|
+
| `rule` | `string` | no | Omit to get the full catalog |
|
|
400
|
+
|
|
401
|
+
Accepted values: a canonical rule ID (`call.undefined-method`), a
|
|
402
|
+
legacy alias (`undefined-method`), or a family prefix (`call`, `flow`,
|
|
403
|
+
`assert`, `dump`, `def`).
|
|
404
|
+
|
|
405
|
+
**Returns:** JSON — an array of rule catalog entries.
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
[
|
|
409
|
+
{
|
|
410
|
+
"id": "call.undefined-method",
|
|
411
|
+
"summary": "Method not found on the inferred receiver type.",
|
|
412
|
+
"severity_authored": "error",
|
|
413
|
+
"since": "0.0.1",
|
|
414
|
+
"fires_when": ["..."],
|
|
415
|
+
"does_not_fire_when": ["..."],
|
|
416
|
+
"suppression": "# rigor:disable call.undefined-method"
|
|
417
|
+
}
|
|
418
|
+
]
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Typical agent use:** explain a diagnostic to the user, or look up
|
|
422
|
+
whether a rule fires in a specific situation before deciding whether a
|
|
423
|
+
finding is a real bug.
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
### rigor_coverage
|
|
428
|
+
|
|
429
|
+
Report type-precision coverage: the ratio of expressions Rigor types
|
|
430
|
+
as `Constant` / `Nominal` / shaped / refined (precise) versus
|
|
431
|
+
`Dynamic[top]` or `top` (opaque).
|
|
432
|
+
|
|
433
|
+
**Input:**
|
|
434
|
+
|
|
435
|
+
| Argument | Type | Required |
|
|
436
|
+
|---|---|---|
|
|
437
|
+
| `paths` | `string[]` | yes |
|
|
438
|
+
| `config` | `string` | no |
|
|
439
|
+
|
|
440
|
+
**Returns:** JSON — the same as `rigor coverage --format json`.
|
|
441
|
+
|
|
442
|
+
```json
|
|
443
|
+
{
|
|
444
|
+
"summary": {
|
|
445
|
+
"files_processed": 12,
|
|
446
|
+
"expressions_typed": 3841,
|
|
447
|
+
"precision_ratio": 0.447
|
|
448
|
+
},
|
|
449
|
+
"tiers": {
|
|
450
|
+
"constant": 312, "nominal": 903, "shaped": 46,
|
|
451
|
+
"refined": 71, "bot": 381,
|
|
452
|
+
"dynamic_specific": 512, "dynamic_top": 1498, "top": 118
|
|
453
|
+
},
|
|
454
|
+
"files": [
|
|
455
|
+
{
|
|
456
|
+
"path": "lib/order.rb",
|
|
457
|
+
"expressions_typed": 214,
|
|
458
|
+
"precision_ratio": 0.612
|
|
459
|
+
}
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Typical agent use:** measure the impact of adding a fold rule or RBS
|
|
465
|
+
annotation — call `rigor_coverage` before and after, compare the
|
|
466
|
+
`precision_ratio` delta.
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Troubleshooting
|
|
471
|
+
|
|
472
|
+
**The MCP server starts but the client shows no tools.**
|
|
473
|
+
|
|
474
|
+
Run `rigor mcp` manually in a terminal and send the handshake:
|
|
475
|
+
|
|
476
|
+
```sh
|
|
477
|
+
echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}' | rigor mcp
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
You should get a JSON response. If you get nothing or a shell error,
|
|
481
|
+
`rigor` is not on your `PATH` — fix the install path first (see
|
|
482
|
+
[Installing Rigor](01-installation.md)).
|
|
483
|
+
|
|
484
|
+
**`rigor_check` / `rigor_triage` return an empty diagnostics array on a project that has errors.**
|
|
485
|
+
|
|
486
|
+
The tool uses `Configuration.discover` from the working directory the
|
|
487
|
+
MCP server was started in. If the client launches `rigor mcp` from a
|
|
488
|
+
home or temp directory, no `.rigor.yml` is found and the configured
|
|
489
|
+
paths default to the empty set. Mitigations:
|
|
490
|
+
|
|
491
|
+
- Pass `--config=/path/to/project/.rigor.yml` when launching:
|
|
492
|
+
`"args": ["mcp", "--config=/path/to/project/.rigor.yml"]`
|
|
493
|
+
- Or pass an absolute `paths` argument in the tool call:
|
|
494
|
+
`{ "name": "rigor_check", "arguments": { "paths": ["/path/to/project/lib"] } }`
|
|
495
|
+
|
|
496
|
+
**`rigor_type_of` reports `isError: true`.**
|
|
497
|
+
|
|
498
|
+
The file path must be the exact on-disk path readable from the server
|
|
499
|
+
process. Relative paths are resolved from the server's working
|
|
500
|
+
directory. Use absolute paths from AI agents to avoid ambiguity.
|
|
501
|
+
|
|
502
|
+
**Tool calls are slow on first call, fast afterward.**
|
|
503
|
+
|
|
504
|
+
The first call in a session cold-boots the Ruby `require` cache;
|
|
505
|
+
subsequent calls reuse it. Expected warm-path latency:
|
|
506
|
+
|
|
507
|
+
| Tool | Cold (first call) | Warm (subsequent calls) |
|
|
508
|
+
|---|---|---|
|
|
509
|
+
| `rigor_explain` | < 200 ms | < 5 ms |
|
|
510
|
+
| `rigor_type_of` | ~1.5 s | ~200 ms |
|
|
511
|
+
| `rigor_check` (small project) | ~2 s | ~500 ms |
|
|
512
|
+
| `rigor_triage` (small project) | ~2 s | ~700 ms |
|
|
513
|
+
|
|
514
|
+
Cold-start is dominated by RBS environment build. A `.rigor/cache`
|
|
515
|
+
warmed by a prior `rigor check` run reduces it significantly.
|
|
516
|
+
|
|
517
|
+
## Status and roadmap
|
|
518
|
+
|
|
519
|
+
`rigor mcp` shipped in v0.1.10 with all seven tools and stdio
|
|
520
|
+
transport. Queued follow-ups are demand-driven:
|
|
521
|
+
|
|
522
|
+
- **HTTP transport** (slice 2) — `--transport=http` for CI / remote
|
|
523
|
+
agent use; a minimal Rack endpoint.
|
|
524
|
+
- **Across-call environment caching** (slice 3) — hold a warm
|
|
525
|
+
`Environment` + `Cache::Store` in the server between calls,
|
|
526
|
+
invalidated by an `mtime`-based check; reduces warm-path latency
|
|
527
|
+
to near-zero for repeated calls against the same project.
|
|
528
|
+
- **`rigor_check` buffer mode** — accept an in-memory source buffer
|
|
529
|
+
instead of (or alongside) a file path; mirrors the `--tmp-file` /
|
|
530
|
+
`--instead-of` editor-mode flags. Useful when an AI agent has
|
|
531
|
+
edited a file's content in-memory and wants to check the modified
|
|
532
|
+
version before writing it.
|
|
533
|
+
- **`rigor_baseline_generate` (write-side, gated)** — explicitly
|
|
534
|
+
opt-in write tool for agents operating with confirmed write
|
|
535
|
+
permissions. Deferred until there is a clear demand signal.
|
|
536
|
+
|
|
537
|
+
To request a queued feature or report an issue, open a GitHub issue
|
|
538
|
+
with: the MCP client + version, the Rigor version (`rigor version`),
|
|
539
|
+
and the JSON-RPC exchange that triggered the problem.
|