mcp_authorization 0.5.1 → 0.5.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/CHANGELOG.md +20 -0
- data/lib/mcp_authorization/rbs_schema_compiler.rb +80 -4
- data/lib/mcp_authorization/version.rb +1 -1
- metadata +2 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 003724dd47fae4de46be5fc319fb0b72f7154fff97f491dcca2251abadf81f32
|
|
4
|
+
data.tar.gz: 4df5f0cc01cb38310a3c2d1a27e3beedcb8c6bb3538a2dd109702fa7a8d9c261
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 96ec8e376316d4fd63ed9cb1350b730138c233152f54dd1fea15ff8608dada5679efbefb0d698bb32eaa6d843a1b15f62d54e5a342f425aaba6dd50cab71c1e7
|
|
7
|
+
data.tar.gz: 7215cf662c1bf0a87aab6887fbc88cb59cd5cac24f48d96dc7f490fd99acf7835a813bc9f621b36904a09c1ac9639cf2a66330ff189b1dee0350e57f45cc50fb
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ All notable changes to this gem are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.5.3] - 2026-06-03
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **`#` comments inside an RBS record type no longer break schema compilation.** ([#20](https://github.com/onboardiq/mcp_authorization/issues/20))
|
|
11
|
+
|
|
12
|
+
A comment line inside a record body — whether in an inline `# @rbs type` annotation or an imported `sig/shared/*.rbs` alias — raised `ArgumentError: invalid field name token`. The line-based readers (`find_raw_type_body`, `parse_type_aliases`, `parse_rbs_file`) concatenate record-body lines without a newline separator, so a comment folded into the next field name (`"# a note describing the fields belowid"`). Comments are valid anywhere in RBS — the official lexer discards `#`-to-end-of-line everywhere — so the readers now strip line comments before splitting fields, via a new `strip_rbs_comment` helper that leaves `#` inside string literals and bracketed annotation values (e.g. `@desc(...)`) untouched.
|
|
13
|
+
|
|
14
|
+
**Impact:** because `tools/list` maps `to_mcp_definition` over every tool in a domain, a single tool with an in-record comment took down discovery for the entire domain — and the offending comment could live far away in a shared `.rbs` alias that several tools import.
|
|
15
|
+
|
|
16
|
+
- **Narrowed `rbs` require set now loads under `rbs` 4.x.** The 0.5.2 narrowing (16-file subset instead of `require "rbs"`) was validated against `rbs` 3.x but raised `NameError: uninitialized constant RBS::AST::Ruby` on a fresh install resolving `rbs` 4.x — the same 4.x that 0.5.2's loosened `>= 3.0` constraint explicitly allows. `rbs` 4.x's C extension references the new `RBS::AST::Ruby::*` namespace and its `parser_aux` references `Pathname` at load time. The require block now loads `pathname` and the `rbs/ast/ruby/*` files when present (guarded by `rescue LoadError` so `rbs` 3.x, which lacks them, is unaffected). Verified against `rbs` 3.10 and 4.0.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **CI workflow** (`.github/workflows/ci.yml`) running `bundle exec rake test` across Ruby 3.1–3.4 on push and pull request, plus a `sentinel check` job that fails if the committed `sig/generated/*.rbs` drift from the inline `#:` annotations. `rbs-sentinel` is now pinned as a development dependency so the signature formatting CI checks against is reproducible.
|
|
20
|
+
|
|
21
|
+
## [0.5.2] - 2026-05-28
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **Narrowed the `rbs` require set.** `require "rbs"` pulled in ~144 files (CLI, environment loader, definition builder, prototype generators, stdlib type signatures, validator, resolver, ...) — none of which this gem touches. Replaced with a 16-file subset covering only `RBS::Parser.parse_type` and the `RBS::Types::*` AST classes the schema visitor actually visits. Measured against this gem's load path: ~1.2 MB RSS vs ~15 MB, 18 files loaded vs 144. No behavior change — same parser, same AST.
|
|
25
|
+
- **Loosened the `rbs` version constraint** from `>= 3.0, < 4.0` to `>= 3.0`. The upper bound locked consumers out of `rbs 4.x` even though `RBS::Parser.parse_type` is part of rbs's stable surface. Consumers who already depend on `rbs 4` for their own Steep / type-check toolchain can now use this gem without a downgrade. If a future rbs major actually breaks our parser-API usage, we'll add the upper bound back at that point — not preemptively.
|
|
26
|
+
|
|
7
27
|
## [0.5.1] - 2026-05-27
|
|
8
28
|
|
|
9
29
|
### Fixed
|
|
@@ -1,4 +1,44 @@
|
|
|
1
|
-
require
|
|
1
|
+
# Narrow require set: we use only RBS::Parser.parse_type and a handful of
|
|
2
|
+
# RBS::Types::* AST classes. Avoid `require "rbs"`, which pulls in ~144
|
|
3
|
+
# files (CLI, environment loader, definition builder, prototype generators,
|
|
4
|
+
# stdlib type signatures, ...) we never touch — ~15 MB RSS vs ~1.2 MB for
|
|
5
|
+
# the subset below. Load order matters: location_aux uses the C-defined
|
|
6
|
+
# RBS::Location, and rbs_extension assumes RBS::AST::* namespaces exist.
|
|
7
|
+
require "pathname" # rbs 4.x's parser_aux references Pathname at load time
|
|
8
|
+
require "rbs/version"
|
|
9
|
+
require "rbs/errors"
|
|
10
|
+
require "rbs/buffer"
|
|
11
|
+
require "rbs/namespace"
|
|
12
|
+
require "rbs/type_name"
|
|
13
|
+
require "rbs/types"
|
|
14
|
+
require "rbs/method_type"
|
|
15
|
+
require "rbs/ast/type_param"
|
|
16
|
+
require "rbs/ast/directives"
|
|
17
|
+
require "rbs/ast/declarations"
|
|
18
|
+
require "rbs/ast/members"
|
|
19
|
+
require "rbs/ast/annotation"
|
|
20
|
+
require "rbs/ast/comment"
|
|
21
|
+
# rbs 4.x's C extension (rbs_extension) references the RBS::AST::Ruby::*
|
|
22
|
+
# namespace, which did not exist on rbs 3.x. Require those files when the
|
|
23
|
+
# installed rbs ships them so the narrow load path stays correct across
|
|
24
|
+
# the gemspec's supported range (rbs >= 3.0); ignore on versions that
|
|
25
|
+
# predate the namespace, where rbs_extension does not need it.
|
|
26
|
+
%w[
|
|
27
|
+
rbs/ast/ruby/helpers/constant_helper
|
|
28
|
+
rbs/ast/ruby/helpers/location_helper
|
|
29
|
+
rbs/ast/ruby/annotations
|
|
30
|
+
rbs/ast/ruby/comment_block
|
|
31
|
+
rbs/ast/ruby/declarations
|
|
32
|
+
rbs/ast/ruby/members
|
|
33
|
+
].each do |feature|
|
|
34
|
+
require feature
|
|
35
|
+
rescue LoadError
|
|
36
|
+
# rbs < 4: file absent and rbs_extension does not reference it.
|
|
37
|
+
end
|
|
38
|
+
require "rbs_extension"
|
|
39
|
+
require "rbs/location_aux"
|
|
40
|
+
require "rbs/parser_aux"
|
|
41
|
+
|
|
2
42
|
require_relative "diagnostics"
|
|
3
43
|
|
|
4
44
|
module McpAuthorization
|
|
@@ -1054,7 +1094,7 @@ module McpAuthorization
|
|
|
1054
1094
|
elsif stripped =~ /\Atype (\w+) = "([^"]+)"/
|
|
1055
1095
|
aliases[$1.to_s] = parse_rbs_string_union($2.to_s, line, content)
|
|
1056
1096
|
elsif current_name
|
|
1057
|
-
current_body << stripped
|
|
1097
|
+
current_body << strip_rbs_comment(stripped)
|
|
1058
1098
|
if brace_balanced?(current_body)
|
|
1059
1099
|
aliases[current_name] = current_body
|
|
1060
1100
|
current_name = nil
|
|
@@ -1116,7 +1156,7 @@ module McpAuthorization
|
|
|
1116
1156
|
if line =~ /# @rbs type #{pattern} = \{/
|
|
1117
1157
|
body = "{"
|
|
1118
1158
|
rest.each do |next_line|
|
|
1119
|
-
stripped = next_line.strip.sub(/^#\s*/, "")
|
|
1159
|
+
stripped = strip_rbs_comment(next_line.strip.sub(/^#\s*/, ""))
|
|
1120
1160
|
body << stripped
|
|
1121
1161
|
return { kind: :record, body: body } if brace_balanced?(body)
|
|
1122
1162
|
end
|
|
@@ -1165,7 +1205,7 @@ module McpAuthorization
|
|
|
1165
1205
|
elsif line =~ /# @rbs type (\w+) = "([^"]+)"/
|
|
1166
1206
|
aliases[$1.to_s] = parse_string_union($2.to_s, line, content)
|
|
1167
1207
|
elsif current_name
|
|
1168
|
-
stripped = line.strip.sub(/^#\s*/, "")
|
|
1208
|
+
stripped = strip_rbs_comment(line.strip.sub(/^#\s*/, ""))
|
|
1169
1209
|
current_body << stripped
|
|
1170
1210
|
if brace_balanced?(current_body)
|
|
1171
1211
|
aliases[current_name] = current_body
|
|
@@ -1302,6 +1342,42 @@ module McpAuthorization
|
|
|
1302
1342
|
# which silently dropped any field whose type string contained a
|
|
1303
1343
|
# comma — or worse, split that field at the comma.
|
|
1304
1344
|
#
|
|
1345
|
+
# Strip an RBS line comment (+#+ to end-of-line) from a single line.
|
|
1346
|
+
#
|
|
1347
|
+
# RBS treats +#+ as a comment marker everywhere outside string
|
|
1348
|
+
# literals — the official lexer discards it before parsing. The
|
|
1349
|
+
# line-based readers here (+find_raw_type_body+, +parse_type_aliases+,
|
|
1350
|
+
# +parse_rbs_file+) concatenate record-body lines *without* a newline
|
|
1351
|
+
# separator, so a comment authored inside a record body
|
|
1352
|
+
# (+{ # note\n id: String }+) would otherwise fold into the next
|
|
1353
|
+
# field name and blow up +parse_field_name+ (issue #20).
|
|
1354
|
+
#
|
|
1355
|
+
# We scan character by character so a +#+ inside a string literal or
|
|
1356
|
+
# inside a bracketed annotation value (e.g. +@desc(a # b)+) is left
|
|
1357
|
+
# untouched; only a +#+ at bracket depth 0 outside any string starts
|
|
1358
|
+
# a comment.
|
|
1359
|
+
#: (String) -> String
|
|
1360
|
+
def strip_rbs_comment(line)
|
|
1361
|
+
depth = 0
|
|
1362
|
+
in_string = nil #: String?
|
|
1363
|
+
|
|
1364
|
+
line.each_char.with_index do |ch, i|
|
|
1365
|
+
if in_string
|
|
1366
|
+
in_string = nil if ch == in_string
|
|
1367
|
+
elsif ch == '"' || ch == "'"
|
|
1368
|
+
in_string = ch
|
|
1369
|
+
elsif ch == "(" || ch == "[" || ch == "{"
|
|
1370
|
+
depth += 1
|
|
1371
|
+
elsif ch == ")" || ch == "]" || ch == "}"
|
|
1372
|
+
depth -= 1
|
|
1373
|
+
elsif ch == "#" && depth <= 0
|
|
1374
|
+
return line[0...i].to_s.rstrip
|
|
1375
|
+
end
|
|
1376
|
+
end
|
|
1377
|
+
|
|
1378
|
+
line
|
|
1379
|
+
end
|
|
1380
|
+
|
|
1305
1381
|
#: (String) { (String, String) -> void } -> void
|
|
1306
1382
|
def each_field_in_record(body)
|
|
1307
1383
|
inner = body.strip.sub(/\A\{/, "").sub(/\}\z/, "").strip
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mcp_authorization
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- AndyGauge
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -45,9 +45,6 @@ dependencies:
|
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
47
|
version: '3.0'
|
|
48
|
-
- - "<"
|
|
49
|
-
- !ruby/object:Gem::Version
|
|
50
|
-
version: '4.0'
|
|
51
48
|
type: :runtime
|
|
52
49
|
prerelease: false
|
|
53
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -55,9 +52,6 @@ dependencies:
|
|
|
55
52
|
- - ">="
|
|
56
53
|
- !ruby/object:Gem::Version
|
|
57
54
|
version: '3.0'
|
|
58
|
-
- - "<"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '4.0'
|
|
61
55
|
- !ruby/object:Gem::Dependency
|
|
62
56
|
name: minitest
|
|
63
57
|
requirement: !ruby/object:Gem::Requirement
|