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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7365a5b287722edcac66ce63fa3ef411f6a6761e17ebb12cdfaf982e1e71c03d
4
- data.tar.gz: 01cbce16f56b0ca80523014d20caee64a90cd4b82e478c9ebbf85e0cb255397a
3
+ metadata.gz: 003724dd47fae4de46be5fc319fb0b72f7154fff97f491dcca2251abadf81f32
4
+ data.tar.gz: 4df5f0cc01cb38310a3c2d1a27e3beedcb8c6bb3538a2dd109702fa7a8d9c261
5
5
  SHA512:
6
- metadata.gz: 374d094408606c87c9c7886d3e5bb22f05794076d001054d703431e604740fb914596d2c75dbb4bc7a07eb0461f3ac660ea121d134c850b0439d18f0fe7f9542
7
- data.tar.gz: 793eca82f7a52d56e65134366ed300d07d07bb9331daa49f566294e9f14af46d40ada269ebd4efcfd0a8f65733ee8981a0cbc039d3520eec4f4c43c500e3421c
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 "rbs"
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
@@ -1,3 +1,3 @@
1
1
  module McpAuthorization
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.3"
3
3
  end
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.1
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-05-27 00:00:00.000000000 Z
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