sorbet-baml 0.2.0 → 0.3.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +123 -2
  3. data/Rakefile +2 -2
  4. data/docs-site/.gitignore +48 -0
  5. data/docs-site/Gemfile +5 -0
  6. data/docs-site/Gemfile.lock +140 -0
  7. data/docs-site/Rakefile +3 -0
  8. data/docs-site/bridgetown.config.yml +15 -0
  9. data/docs-site/config/initializers.rb +9 -0
  10. data/docs-site/config/puma.rb +9 -0
  11. data/docs-site/config.ru +5 -0
  12. data/docs-site/esbuild.config.js +11 -0
  13. data/docs-site/frontend/javascript/index.js +22 -0
  14. data/docs-site/frontend/styles/index.css +61 -0
  15. data/docs-site/package.json +18 -0
  16. data/docs-site/postcss.config.js +6 -0
  17. data/docs-site/server/roda_app.rb +9 -0
  18. data/docs-site/src/_components/head.liquid +26 -0
  19. data/docs-site/src/_components/nav.liquid +68 -0
  20. data/docs-site/src/_layouts/default.liquid +27 -0
  21. data/docs-site/src/_layouts/doc.liquid +39 -0
  22. data/docs-site/src/advanced-usage.md +598 -0
  23. data/docs-site/src/getting-started.md +170 -0
  24. data/docs-site/src/index.md +183 -0
  25. data/docs-site/src/troubleshooting.md +317 -0
  26. data/docs-site/src/type-mapping.md +236 -0
  27. data/docs-site/tailwind.config.js +85 -0
  28. data/examples/description_parameters.rb +16 -16
  29. data/lib/sorbet_baml/comment_extractor.rb +31 -39
  30. data/lib/sorbet_baml/converter.rb +66 -32
  31. data/lib/sorbet_baml/dependency_resolver.rb +11 -11
  32. data/lib/sorbet_baml/description_extension.rb +5 -5
  33. data/lib/sorbet_baml/description_extractor.rb +8 -10
  34. data/lib/sorbet_baml/dspy_tool_converter.rb +97 -0
  35. data/lib/sorbet_baml/dspy_tool_extensions.rb +23 -0
  36. data/lib/sorbet_baml/enum_extensions.rb +2 -2
  37. data/lib/sorbet_baml/struct_extensions.rb +2 -2
  38. data/lib/sorbet_baml/tool_extensions.rb +23 -0
  39. data/lib/sorbet_baml/type_mapper.rb +35 -37
  40. data/lib/sorbet_baml/version.rb +1 -1
  41. data/lib/sorbet_baml.rb +41 -13
  42. data/sorbet/config +2 -0
  43. data/sorbet/rbi/gems/anthropic@1.5.0.rbi +21252 -0
  44. data/sorbet/rbi/gems/async@2.27.3.rbi +9 -0
  45. data/sorbet/rbi/gems/bigdecimal@3.2.2.rbi +9 -0
  46. data/sorbet/rbi/gems/concurrent-ruby@1.3.5.rbi +424 -0
  47. data/sorbet/rbi/gems/connection_pool@2.5.3.rbi +9 -0
  48. data/sorbet/rbi/gems/console@1.33.0.rbi +9 -0
  49. data/sorbet/rbi/gems/dry-configurable@1.3.0.rbi +672 -0
  50. data/sorbet/rbi/gems/dry-core@1.1.0.rbi +1729 -0
  51. data/sorbet/rbi/gems/dry-logger@1.1.0.rbi +1317 -0
  52. data/sorbet/rbi/gems/dspy@0.19.1.rbi +6677 -0
  53. data/sorbet/rbi/gems/ffi@1.17.2.rbi +2174 -0
  54. data/sorbet/rbi/gems/fiber-annotation@0.2.0.rbi +9 -0
  55. data/sorbet/rbi/gems/fiber-local@1.1.0.rbi +9 -0
  56. data/sorbet/rbi/gems/fiber-storage@1.0.1.rbi +9 -0
  57. data/sorbet/rbi/gems/google-protobuf@4.32.0.rbi +9 -0
  58. data/sorbet/rbi/gems/googleapis-common-protos-types@1.20.0.rbi +9 -0
  59. data/sorbet/rbi/gems/informers@1.2.1.rbi +1875 -0
  60. data/sorbet/rbi/gems/io-event@1.12.1.rbi +9 -0
  61. data/sorbet/rbi/gems/metrics@0.13.0.rbi +9 -0
  62. data/sorbet/rbi/gems/onnxruntime@0.10.0.rbi +304 -0
  63. data/sorbet/rbi/gems/openai@0.16.0.rbi +68055 -0
  64. data/sorbet/rbi/gems/opentelemetry-api@1.6.0.rbi +9 -0
  65. data/sorbet/rbi/gems/opentelemetry-common@0.22.0.rbi +9 -0
  66. data/sorbet/rbi/gems/opentelemetry-exporter-otlp@0.30.0.rbi +9 -0
  67. data/sorbet/rbi/gems/opentelemetry-registry@0.4.0.rbi +9 -0
  68. data/sorbet/rbi/gems/opentelemetry-sdk@1.8.1.rbi +9 -0
  69. data/sorbet/rbi/gems/opentelemetry-semantic_conventions@1.11.0.rbi +9 -0
  70. data/sorbet/rbi/gems/polars-df@0.20.0.rbi +9 -0
  71. data/sorbet/rbi/gems/sorbet-result@1.4.0.rbi +242 -0
  72. data/sorbet/rbi/gems/sorbet-schema@0.9.2.rbi +743 -0
  73. data/sorbet/rbi/gems/sorbet-struct-comparable@1.3.0.rbi +48 -0
  74. data/sorbet/rbi/gems/tokenizers@0.5.5.rbi +754 -0
  75. data/sorbet/rbi/gems/traces@0.17.0.rbi +9 -0
  76. data/sorbet/rbi/gems/zeitwerk@2.7.3.rbi +1429 -0
  77. metadata +63 -2
@@ -0,0 +1,236 @@
1
+ ---
2
+ layout: doc
3
+ title: "Type Mapping Reference"
4
+ description: "Complete mapping between Sorbet types and BAML output. Learn how every Sorbet type converts to efficient BAML format."
5
+ ---
6
+
7
+ # Type Mapping Reference
8
+
9
+ Complete mapping between Sorbet types and BAML output for autonomous LLM workflows. All listed types are **fully supported** with automatic field descriptions.
10
+
11
+ ## Basic Types
12
+
13
+ | Sorbet Type | BAML Output | Example |
14
+ |-------------|-------------|---------|
15
+ | `String` | `string` | `name string` |
16
+ | `Integer` | `int` | `age int` |
17
+ | `Float` | `float` | `price float` |
18
+ | `T::Boolean` | `bool` | `active bool` |
19
+ | `NilClass` | `null` | `null` |
20
+ | `Symbol` | `string` | `status string` |
21
+ | `Date/DateTime/Time` | `string` | `created_at string` |
22
+
23
+ ## Optional Types (T.nilable)
24
+
25
+ | Sorbet Type | BAML Output | Example |
26
+ |-------------|-------------|---------|
27
+ | `T.nilable(String)` | `string?` | `email string?` |
28
+ | `T.nilable(Integer)` | `int?` | `age int?` |
29
+ | `T.nilable(MyStruct)` | `MyStruct?` | `address Address?` |
30
+
31
+ ## Collection Types
32
+
33
+ | Sorbet Type | BAML Output | Example |
34
+ |-------------|-------------|---------|
35
+ | `T::Array[String]` | `string[]` | `tags string[]` |
36
+ | `T::Array[Integer]` | `int[]` | `scores int[]` |
37
+ | `T::Array[MyStruct]` | `MyStruct[]` | `addresses Address[]` |
38
+
39
+ ## Hash/Map Types
40
+
41
+ | Sorbet Type | BAML Output | Example |
42
+ |-------------|-------------|---------|
43
+ | `T::Hash[String, String]` | `map<string, string>` | `metadata map<string, string>` |
44
+ | `T::Hash[String, Integer]` | `map<string, int>` | `counts map<string, int>` |
45
+ | `T::Hash[Symbol, String]` | `map<string, string>` | `config map<string, string>` |
46
+
47
+ ## Union Types (T.any)
48
+
49
+ | Sorbet Type | BAML Output | Example |
50
+ |-------------|-------------|---------|
51
+ | `T.any(String, Integer)` | `string \| int` | `value string \| int` |
52
+ | `T.any(String, Integer, Float)` | `string \| int \| float` | `mixed string \| int \| float` |
53
+ | `T.nilable(T.any(String, Integer))` | `(string \| int)?` | `optional (string \| int)?` |
54
+
55
+ ## Complex Collection Types
56
+
57
+ | Sorbet Type | BAML Output | Example |
58
+ |-------------|-------------|---------|
59
+ | `T::Array[T.any(String, Integer)]` | `(string \| int)[]` | `mixed_array (string \| int)[]` |
60
+ | `T::Hash[String, T.any(String, Integer)]` | `map<string, string \| int>` | `settings map<string, string \| int>` |
61
+ | `T::Hash[String, T::Array[String]]` | `map<string, string[]>` | `labels map<string, string[]>` |
62
+
63
+ ## Structured Types
64
+
65
+ ### T::Struct to BAML Classes (Research Workflow Example)
66
+
67
+ ```ruby
68
+ class ConfidenceLevel < T::Enum
69
+ enums do
70
+ # Low confidence, requires further verification
71
+ Low = new('low')
72
+ # High confidence, strongly supported by evidence
73
+ High = new('high')
74
+ end
75
+ end
76
+
77
+ class ResearchFindings < T::Struct
78
+ # Detailed research findings and analysis
79
+ const :findings, String
80
+ # Key actionable insights extracted
81
+ const :key_insights, T::Array[String]
82
+ # Assessment of evidence quality
83
+ const :evidence_quality, ConfidenceLevel
84
+ # Confidence score (1-10 scale)
85
+ const :confidence_score, Integer
86
+ end
87
+ ```
88
+
89
+ ```ruby
90
+ ResearchFindings.to_baml
91
+ ```
92
+
93
+ **Generated BAML:**
94
+ ```baml
95
+ enum ConfidenceLevel {
96
+ "low" @description("Low confidence, requires further verification")
97
+ "high" @description("High confidence, strongly supported by evidence")
98
+ }
99
+
100
+ class ResearchFindings {
101
+ findings string @description("Detailed research findings and analysis")
102
+ key_insights string[] @description("Key actionable insights extracted")
103
+ evidence_quality ConfidenceLevel @description("Assessment of evidence quality")
104
+ confidence_score int @description("Confidence score (1-10 scale)")
105
+ }
106
+ ```
107
+
108
+ ### T::Enum to BAML Enums (Task Classification)
109
+
110
+ ```ruby
111
+ class TaskType < T::Enum
112
+ enums do
113
+ # Literature review and information gathering
114
+ Research = new('research')
115
+ # Data analysis and statistical interpretation
116
+ Analysis = new('analysis')
117
+ # Combining multiple sources into coherent insights
118
+ Synthesis = new('synthesis')
119
+ end
120
+ end
121
+
122
+ class ResearchTask < T::Struct
123
+ # Clear description of the research objective
124
+ const :objective, String
125
+ # Type of research task to be performed
126
+ const :task_type, TaskType
127
+ end
128
+ ```
129
+
130
+ ```ruby
131
+ [TaskType, ResearchTask].map(&:to_baml).join("\n\n")
132
+ ```
133
+
134
+ **Generated BAML:**
135
+ ```baml
136
+ enum TaskType {
137
+ "research" @description("Literature review and information gathering")
138
+ "analysis" @description("Data analysis and statistical interpretation")
139
+ "synthesis" @description("Combining multiple sources into coherent insights")
140
+ }
141
+
142
+ class ResearchTask {
143
+ objective string @description("Clear description of the research objective")
144
+ task_type TaskType @description("Type of research task to be performed")
145
+ }
146
+ ```
147
+
148
+ ### Complex Real-World Example (Autonomous Research Agent)
149
+
150
+ ```ruby
151
+ class ComplexityLevel < T::Enum
152
+ enums do
153
+ # Basic analysis requiring straightforward research
154
+ Basic = new('basic')
155
+ # Advanced analysis requiring deep domain expertise
156
+ Advanced = new('advanced')
157
+ end
158
+ end
159
+
160
+ class TaskDecomposition < T::Struct
161
+ # The main research topic being investigated
162
+ const :research_topic, String
163
+ # Target complexity level for the decomposition
164
+ const :complexity_level, ComplexityLevel
165
+ # Autonomously generated list of research subtasks
166
+ const :subtasks, T::Array[String]
167
+ # Strategic priority rankings (1-5 scale) for each subtask
168
+ const :priority_order, T::Array[Integer]
169
+ # Task dependency relationships for optimal sequencing
170
+ const :dependencies, T::Array[String]
171
+ # Key-value metadata for agent coordination
172
+ const :agent_metadata, T::Hash[String, T.any(String, Integer)]
173
+ end
174
+ ```
175
+
176
+ ```ruby
177
+ [ComplexityLevel, TaskDecomposition].map(&:to_baml).join("\n\n")
178
+ ```
179
+
180
+ **Generated BAML:**
181
+ ```baml
182
+ enum ComplexityLevel {
183
+ "basic" @description("Basic analysis requiring straightforward research")
184
+ "advanced" @description("Advanced analysis requiring deep domain expertise")
185
+ }
186
+
187
+ class TaskDecomposition {
188
+ research_topic string @description("The main research topic being investigated")
189
+ complexity_level ComplexityLevel @description("Target complexity level for the decomposition")
190
+ subtasks string[] @description("Autonomously generated list of research subtasks")
191
+ priority_order int[] @description("Strategic priority rankings (1-5 scale) for each subtask")
192
+ dependencies string[] @description("Task dependency relationships for optimal sequencing")
193
+ agent_metadata map<string, string | int> @description("Key-value metadata for agent coordination")
194
+ }
195
+ ```
196
+
197
+ ## Advanced Features
198
+
199
+ ### Dependency Management
200
+
201
+ ```ruby
202
+ # Dependencies automatically included with smart defaults
203
+ TaskDecomposition.to_baml
204
+ # Outputs ComplexityLevel enum, then TaskDecomposition class in correct order
205
+ ```
206
+
207
+ ### Field Descriptions (Included by Default)
208
+
209
+ ```ruby
210
+ # Smart defaults extract field descriptions from comments
211
+ TaskDecomposition.to_baml
212
+ # Outputs BAML with @description() annotations for LLM context
213
+ ```
214
+
215
+ ### Custom Formatting
216
+
217
+ ```ruby
218
+ # Smart defaults include dependencies and descriptions automatically
219
+ TaskDecomposition.to_baml(indent_size: 4)
220
+ # Disable features if needed:
221
+ TaskDecomposition.to_baml(include_descriptions: false)
222
+ ```
223
+
224
+ ## ✅ Completed Features
225
+
226
+ - ✅ `T::Struct` → `class Name { ... }` with field descriptions
227
+ - ✅ `T::Enum` → `enum Name { ... }` with value descriptions
228
+ - ✅ Automatic dependency resolution and ordering
229
+ - ✅ Smart defaults (descriptions and dependencies enabled)
230
+ - ✅ Full type safety with Sorbet type checking
231
+
232
+ ## Future Enhancements (Optional)
233
+
234
+ - `T.type_alias` → `type Name = ...`
235
+ - Custom naming strategies (snake_case ↔ camelCase)
236
+ - Self-referential type handling
@@ -0,0 +1,85 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: [
4
+ "./src/**/*.{html,md,liquid,erb}",
5
+ "./frontend/**/*.js",
6
+ ],
7
+ darkMode: 'media',
8
+ theme: {
9
+ extend: {
10
+ typography: {
11
+ DEFAULT: {
12
+ css: {
13
+ maxWidth: 'none',
14
+ color: 'inherit',
15
+ a: {
16
+ color: '#3b82f6',
17
+ textDecoration: 'underline',
18
+ fontWeight: '500',
19
+ },
20
+ '[class~="lead"]': {
21
+ color: 'inherit',
22
+ },
23
+ strong: {
24
+ color: 'inherit',
25
+ },
26
+ 'ol > li::before': {
27
+ color: 'inherit',
28
+ },
29
+ 'ul > li::before': {
30
+ backgroundColor: 'currentColor',
31
+ },
32
+ hr: {
33
+ borderColor: 'currentColor',
34
+ opacity: 0.3,
35
+ },
36
+ blockquote: {
37
+ color: 'inherit',
38
+ borderLeftColor: 'currentColor',
39
+ opacity: 0.8,
40
+ },
41
+ h1: {
42
+ color: 'inherit',
43
+ },
44
+ h2: {
45
+ color: 'inherit',
46
+ },
47
+ h3: {
48
+ color: 'inherit',
49
+ },
50
+ h4: {
51
+ color: 'inherit',
52
+ },
53
+ 'figure figcaption': {
54
+ color: 'inherit',
55
+ },
56
+ code: {
57
+ color: 'inherit',
58
+ backgroundColor: 'rgba(156, 163, 175, 0.2)',
59
+ padding: '0.125rem 0.25rem',
60
+ borderRadius: '0.25rem',
61
+ fontWeight: '400',
62
+ },
63
+ 'code::before': {
64
+ content: '""',
65
+ },
66
+ 'code::after': {
67
+ content: '""',
68
+ },
69
+ pre: {
70
+ backgroundColor: '#1f2937',
71
+ color: '#f9fafb',
72
+ },
73
+ 'pre code': {
74
+ backgroundColor: 'transparent',
75
+ color: 'inherit',
76
+ },
77
+ },
78
+ },
79
+ },
80
+ },
81
+ },
82
+ plugins: [
83
+ require('@tailwindcss/typography'),
84
+ ],
85
+ }
@@ -3,15 +3,15 @@
3
3
 
4
4
  require_relative '../lib/sorbet_baml'
5
5
 
6
- puts "🎯 Description Parameter Support Demo"
7
- puts "=" * 50
6
+ puts '🎯 Description Parameter Support Demo'
7
+ puts '=' * 50
8
8
 
9
9
  # Example 1: Basic description parameters
10
10
  class User < T::Struct
11
11
  const :name, String, description: "User's full legal name"
12
- prop :age, Integer, description: "Age in years"
13
- const :email, T.nilable(String), description: "Optional email address for notifications"
14
- const :interests, T::Array[String], description: "List of user hobbies and interests"
12
+ prop :age, Integer, description: 'Age in years'
13
+ const :email, T.nilable(String), description: 'Optional email address for notifications'
14
+ const :interests, T::Array[String], description: 'List of user hobbies and interests'
15
15
  end
16
16
 
17
17
  puts "\n1. Basic T::Struct with description parameters:"
@@ -21,13 +21,13 @@ puts User.to_baml
21
21
  class Product < T::Struct
22
22
  # This comment will be used as fallback
23
23
  const :id, String
24
-
25
- const :name, String, description: "Product name for display"
26
-
24
+
25
+ const :name, String, description: 'Product name for display'
26
+
27
27
  # Price in USD cents
28
28
  prop :price_cents, Integer
29
-
30
- const :category, String, description: "Product category classification"
29
+
30
+ const :category, String, description: 'Product category classification'
31
31
  end
32
32
 
33
33
  puts "\n2. Mixed description sources (parameters take priority):"
@@ -35,15 +35,15 @@ puts Product.to_baml
35
35
 
36
36
  # Example 3: Complex nested types with descriptions
37
37
  class Order < T::Struct
38
- const :id, String, description: "Unique order identifier"
39
- const :customer, User, description: "Customer who placed the order"
40
- const :items, T::Array[Product], description: "List of ordered products"
41
- const :total_cents, Integer, description: "Total order value in USD cents"
42
- const :status, String, description: "Current order processing status"
38
+ const :id, String, description: 'Unique order identifier'
39
+ const :customer, User, description: 'Customer who placed the order'
40
+ const :items, T::Array[Product], description: 'List of ordered products'
41
+ const :total_cents, Integer, description: 'Total order value in USD cents'
42
+ const :status, String, description: 'Current order processing status'
43
43
  end
44
44
 
45
45
  puts "\n3. Complex nested types with dependencies:"
46
46
  puts Order.to_baml
47
47
 
48
48
  puts "\n✨ Beautiful, readable, and LLM-friendly!"
49
- puts "🚀 Perfect for DSPy.rb, autonomous agents, and structured LLM outputs"
49
+ puts '🚀 Perfect for DSPy.rb, autonomous agents, and structured LLM outputs'
@@ -10,67 +10,63 @@ module SorbetBaml
10
10
  def self.extract_field_comments(klass)
11
11
  # First try to get descriptions from the description extractor (extra field)
12
12
  descriptions = DescriptionExtractor.extract_prop_descriptions(klass)
13
-
13
+
14
14
  # Then fall back to comment-based extraction for any missing descriptions
15
15
  comments = {}
16
16
  source_file = find_source_file(klass)
17
-
17
+
18
18
  if source_file && File.exist?(source_file)
19
19
  lines = File.readlines(source_file)
20
20
  extract_comments_from_lines(lines, T.must(T.must(klass.name).split('::').last), comments)
21
21
  end
22
-
22
+
23
23
  # Merge with priority: description parameters > comments
24
- descriptions.merge(comments) { |key, desc_param, comment| desc_param }
24
+ descriptions.merge(comments) { |_key, desc_param, _comment| desc_param }
25
25
  end
26
26
 
27
27
  sig { params(klass: T.class_of(T::Enum)).returns(T::Hash[String, T.nilable(String)]) }
28
28
  def self.extract_enum_comments(klass)
29
29
  comments = {}
30
30
  source_file = find_source_file(klass)
31
-
31
+
32
32
  return comments unless source_file && File.exist?(source_file)
33
-
33
+
34
34
  lines = File.readlines(source_file)
35
35
  extract_enum_comments_from_lines(lines, T.must(T.must(klass.name).split('::').last), comments)
36
-
36
+
37
37
  comments
38
38
  end
39
39
 
40
- private
41
-
42
40
  sig { params(klass: T::Class[T.anything]).returns(T.nilable(String)) }
43
41
  def self.find_source_file(klass)
44
42
  # Try to find where the class was defined
45
43
  # This is a heuristic approach since Ruby doesn't provide reliable source location for classes
46
-
44
+
47
45
  # Method 1: Check if any methods have source location
48
46
  begin
49
47
  if klass.respond_to?(:new) && klass.method(:new).respond_to?(:source_location)
50
48
  location = klass.method(:new).source_location
51
49
  return location[0] if location
52
50
  end
53
- rescue
51
+ rescue StandardError
54
52
  # Ignore errors
55
53
  end
56
-
54
+
57
55
  # Method 2: Look at the current call stack for files that might contain the class
58
56
  caller_locations.each do |location|
59
57
  file_path = location.absolute_path || location.path
60
58
  next unless file_path && File.exist?(file_path)
61
-
59
+
62
60
  # Read the file and check if it contains the class definition
63
61
  begin
64
62
  content = File.read(file_path)
65
63
  class_name = T.must(klass.name).split('::').last
66
- if content.match(/class\s+#{Regexp.escape(T.must(class_name))}\s*</)
67
- return file_path
68
- end
69
- rescue
64
+ return file_path if content.match(/class\s+#{Regexp.escape(T.must(class_name))}\s*</)
65
+ rescue StandardError
70
66
  # Ignore file read errors
71
67
  end
72
68
  end
73
-
69
+
74
70
  nil
75
71
  end
76
72
 
@@ -79,28 +75,26 @@ module SorbetBaml
79
75
  in_target_class = T.let(false, T::Boolean)
80
76
  current_comment = T.let(nil, T.nilable(String))
81
77
  brace_depth = 0
82
-
78
+
83
79
  lines.each do |line|
84
80
  stripped = line.strip
85
-
81
+
86
82
  # Check if we're entering the target class
87
83
  if stripped.match(/^class\s+#{Regexp.escape(class_name)}\s*<\s*T::Struct/)
88
84
  in_target_class = true
89
85
  brace_depth = 0
90
86
  next
91
87
  end
92
-
88
+
93
89
  next unless in_target_class
94
-
90
+
95
91
  # Track brace depth to handle nested classes
96
92
  brace_depth += stripped.count('{')
97
93
  brace_depth -= stripped.count('}')
98
-
94
+
99
95
  # Exit when we reach the end of the class
100
- if stripped == 'end' && brace_depth == 0
101
- break
102
- end
103
-
96
+ break if stripped == 'end' && brace_depth == 0
97
+
104
98
  # Extract comment
105
99
  if stripped.start_with?('#')
106
100
  comment_text = T.must(stripped[1..-1]).strip
@@ -121,37 +115,35 @@ module SorbetBaml
121
115
  in_target_class = T.let(false, T::Boolean)
122
116
  in_enums_block = T.let(false, T::Boolean)
123
117
  current_comment = T.let(nil, T.nilable(String))
124
-
118
+
125
119
  lines.each do |line|
126
120
  stripped = line.strip
127
-
121
+
128
122
  # Check if we're entering the target enum class
129
123
  if stripped.match(/^class\s+#{Regexp.escape(class_name)}\s*<\s*T::Enum/)
130
124
  in_target_class = true
131
125
  next
132
126
  end
133
-
127
+
134
128
  next unless in_target_class
135
-
129
+
136
130
  # Check if we're in the enums block
137
131
  if stripped == 'enums do'
138
132
  in_enums_block = true
139
133
  next
140
134
  end
141
-
135
+
142
136
  # Exit enums block
143
137
  if in_enums_block && stripped == 'end'
144
138
  in_enums_block = false
145
139
  next
146
140
  end
147
-
141
+
148
142
  # Exit class
149
- if stripped == 'end' && !in_enums_block
150
- break
151
- end
152
-
143
+ break if stripped == 'end' && !in_enums_block
144
+
153
145
  next unless in_enums_block
154
-
146
+
155
147
  # Extract comment
156
148
  if stripped.start_with?('#')
157
149
  comment_text = T.must(stripped[1..-1]).strip
@@ -167,4 +159,4 @@ module SorbetBaml
167
159
  end
168
160
  end
169
161
  end
170
- end
162
+ end