class-metrix 1.0.0 → 1.1.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.prettierrc.json +41 -0
  3. data/.qlty/.gitignore +7 -0
  4. data/.qlty/configs/.yamllint.yaml +8 -0
  5. data/.qlty/qlty.toml +108 -0
  6. data/.rubocop.yml +31 -25
  7. data/.vscode/README.md +255 -47
  8. data/.vscode/extensions.json +8 -13
  9. data/.vscode/keybindings.json +0 -0
  10. data/.vscode/settings.json +81 -11
  11. data/.vscode/tasks.json +231 -0
  12. data/CHANGELOG.md +33 -1
  13. data/README.md +107 -23
  14. data/Rakefile +64 -1
  15. data/Steepfile +26 -0
  16. data/config/brakeman.yml +37 -0
  17. data/docs/ARCHITECTURE.md +90 -48
  18. data/docs/CHANGELOG_EVOLUTION_EXAMPLE.md +95 -0
  19. data/docs/QLTY_INTEGRATION.md +181 -0
  20. data/docs/RELEASE_GUIDE.md +318 -0
  21. data/docs/SLACK_INTEGRATION.md +227 -0
  22. data/examples/README.md +23 -17
  23. data/examples/basic_usage.rb +19 -19
  24. data/examples/debug_levels_demo.rb +15 -16
  25. data/examples/debug_mode_demo.rb +12 -13
  26. data/examples/inheritance_and_modules.rb +45 -45
  27. data/lib/class_metrix/extractor.rb +1 -1
  28. data/lib/class_metrix/extractors/constants_extractor.rb +1 -1
  29. data/lib/class_metrix/extractors/methods_extractor.rb +1 -1
  30. data/lib/class_metrix/extractors/multi_type_extractor.rb +2 -2
  31. data/lib/class_metrix/formatters/base/base_formatter.rb +3 -3
  32. data/lib/class_metrix/formatters/components/footer_component.rb +3 -3
  33. data/lib/class_metrix/formatters/components/generic_header_component.rb +2 -2
  34. data/lib/class_metrix/formatters/components/header_component.rb +4 -4
  35. data/lib/class_metrix/formatters/components/missing_behaviors_component.rb +7 -7
  36. data/lib/class_metrix/formatters/components/table_component/row_processor.rb +8 -5
  37. data/lib/class_metrix/formatters/components/table_component/table_data_extractor.rb +4 -1
  38. data/lib/class_metrix/formatters/components/table_component/table_renderer.rb +2 -2
  39. data/lib/class_metrix/formatters/components/table_component.rb +5 -4
  40. data/lib/class_metrix/formatters/csv_formatter.rb +3 -3
  41. data/lib/class_metrix/formatters/markdown_formatter.rb +3 -4
  42. data/lib/class_metrix/formatters/shared/markdown_table_builder.rb +2 -2
  43. data/lib/class_metrix/formatters/shared/table_builder.rb +8 -6
  44. data/lib/class_metrix/version.rb +1 -1
  45. data/sig/class_metrix.rbs +8 -0
  46. data/sig/extractor.rbs +54 -0
  47. data/sig/extractors.rbs +84 -0
  48. data/sig/formatters_base.rbs +59 -0
  49. data/sig/formatters_components.rbs +133 -0
  50. data/sig/formatters_main.rbs +20 -0
  51. data/sig/formatters_shared.rbs +102 -0
  52. data/sig/manifest.yaml +32 -0
  53. data/sig/utils.rbs +57 -0
  54. data/sig/value_processor.rbs +11 -0
  55. data/sig/version.rbs +4 -0
  56. metadata +94 -4
  57. data/RELEASE_GUIDE.md +0 -158
  58. data/sig/class/metrix.rbs +0 -6
data/docs/ARCHITECTURE.md CHANGED
@@ -11,31 +11,31 @@ graph TD
11
11
  subgraph "Public API Layer"
12
12
  API["ClassMetrix.extract(:constants, :class_methods)<br/>.from([Class1, Class2])<br/>.include_inherited<br/>.expand_hashes<br/>.to_markdown()"]
13
13
  end
14
-
14
+
15
15
  subgraph "Core Extraction Layer"
16
16
  Extractor["Extractor<br/>(Coordinator)"]
17
17
  ClassResolver["Class Resolver<br/>(Utilities)"]
18
18
  ValueProcessor["Value Processor<br/>(Utilities)"]
19
19
  end
20
-
20
+
21
21
  subgraph "Specialized Extractors"
22
22
  ConstantsExtractor["Constants<br/>Extractor"]
23
23
  MethodsExtractor["Methods<br/>Extractor"]
24
24
  MultiTypeExtractor["Multi-Type<br/>Extractor"]
25
25
  end
26
-
26
+
27
27
  subgraph "Formatting Layer"
28
28
  MarkdownFormatter["Markdown<br/>Formatter"]
29
29
  CsvFormatter["CSV<br/>Formatter"]
30
30
  end
31
-
31
+
32
32
  subgraph "Component Layer"
33
33
  subgraph "Report Components"
34
34
  HeaderComponent["Header<br/>Component"]
35
35
  TableComponent["Table<br/>Component"]
36
36
  FooterComponent["Footer<br/>Component"]
37
37
  end
38
-
38
+
39
39
  subgraph "Table Sub-Components"
40
40
  TableDataExtractor["Table Data<br/>Extractor"]
41
41
  RowProcessor["Row<br/>Processor"]
@@ -43,31 +43,31 @@ graph TD
43
43
  TableRenderer["Table<br/>Renderer"]
44
44
  end
45
45
  end
46
-
46
+
47
47
  API --> Extractor
48
48
  Extractor --> ClassResolver
49
49
  Extractor --> ValueProcessor
50
50
  Extractor --> ConstantsExtractor
51
51
  Extractor --> MethodsExtractor
52
52
  Extractor --> MultiTypeExtractor
53
-
53
+
54
54
  ConstantsExtractor --> MarkdownFormatter
55
55
  MethodsExtractor --> MarkdownFormatter
56
56
  MultiTypeExtractor --> MarkdownFormatter
57
-
57
+
58
58
  ConstantsExtractor --> CsvFormatter
59
59
  MethodsExtractor --> CsvFormatter
60
60
  MultiTypeExtractor --> CsvFormatter
61
-
61
+
62
62
  MarkdownFormatter --> HeaderComponent
63
63
  MarkdownFormatter --> TableComponent
64
64
  MarkdownFormatter --> FooterComponent
65
-
65
+
66
66
  TableComponent --> TableDataExtractor
67
67
  TableComponent --> RowProcessor
68
68
  TableComponent --> ColumnWidthCalculator
69
69
  TableComponent --> TableRenderer
70
-
70
+
71
71
  style API fill:#e1f5fe
72
72
  style Extractor fill:#f3e5f5
73
73
  style MarkdownFormatter fill:#e8f5e8
@@ -134,7 +134,7 @@ ClassMetrix includes robust safety measures for handling unusual objects:
134
134
  ```ruby
135
135
  # Safe inspection methods that handle problematic objects
136
136
  logger.safe_inspect(value) # Won't crash on inspect failures
137
- logger.safe_class(value) # Won't crash on class failures
137
+ logger.safe_class(value) # Won't crash on class failures
138
138
  logger.safe_keys(hash) # Won't crash on keys failures
139
139
  logger.safe_to_s(value) # Won't crash on to_s failures
140
140
  ```
@@ -160,6 +160,7 @@ This prevents objects like `Delayed::Backend::ActiveRecord::Job` (which may resp
160
160
  ## 🔄 Data Flow
161
161
 
162
162
  ### 1. **API Entry Point**
163
+
163
164
  ```ruby
164
165
  ClassMetrix.extract(:constants, :class_methods)
165
166
  .from([DatabaseService, CacheService])
@@ -172,40 +173,40 @@ ClassMetrix.extract(:constants, :class_methods)
172
173
 
173
174
  ```mermaid
174
175
  graph TD
175
- UserRequest["User Request<br/>ClassMetrix.extract()"]
176
-
176
+ UserRequest["User Request<br/>ClassMetrix.extract()"]
177
+
177
178
  ClassMetrix["ClassMetrix<br/>.extract()"]
178
179
  Extractor["Extractor<br/>(Main Coordinator)"]
179
180
  ClassResolver["ClassResolver<br/>.normalize()"]
180
-
181
+
181
182
  Router["Route to<br/>Appropriate<br/>Extractor"]
182
-
183
+
183
184
  ConstantsExtractor["Constants<br/>Extractor"]
184
- MethodsExtractor["Methods<br/>Extractor"]
185
+ MethodsExtractor["Methods<br/>Extractor"]
185
186
  MultiTypeExtractor["Multi-Type<br/>Extractor"]
186
-
187
+
187
188
  RawTableData["Raw Table Data<br/>{headers:[], rows:[]}"]
188
-
189
+
189
190
  Formatter["Formatter<br/>(Markdown/CSV)"]
190
-
191
+
191
192
  FormattedOutput["Formatted Output<br/>(String)"]
192
-
193
+
193
194
  UserRequest --> ClassMetrix
194
195
  ClassMetrix --> Extractor
195
196
  Extractor --> ClassResolver
196
197
  Extractor --> Router
197
-
198
+
198
199
  Router --> ConstantsExtractor
199
200
  Router --> MethodsExtractor
200
201
  Router --> MultiTypeExtractor
201
-
202
+
202
203
  ConstantsExtractor --> RawTableData
203
204
  MethodsExtractor --> RawTableData
204
205
  MultiTypeExtractor --> RawTableData
205
-
206
+
206
207
  RawTableData --> Formatter
207
208
  Formatter --> FormattedOutput
208
-
209
+
209
210
  style UserRequest fill:#e3f2fd
210
211
  style Extractor fill:#f3e5f5
211
212
  style Router fill:#fff3e0
@@ -218,32 +219,32 @@ graph TD
218
219
  ```mermaid
219
220
  graph TD
220
221
  TableDataInput["Table Data Input<br/>{headers:[], rows:[]}"]
221
-
222
+
222
223
  TableComponent["TableComponent<br/>(Main Coordinator)<br/>- Orchestrates<br/>- Delegates"]
223
-
224
+
224
225
  TableDataExtractor["TableDataExtractor<br/>• has_type_column?()<br/>• extract_row_data()<br/>• collect_hash_keys()"]
225
-
226
+
226
227
  RowProcessor["RowProcessor<br/>• process_simple_rows()<br/>• process_expanded_rows()<br/>• expand_row() (hash expansion)"]
227
-
228
+
228
229
  ColumnWidthCalculator["ColumnWidthCalculator<br/>• calculate_widths()<br/>• initialize_column_widths()<br/>• apply_minimum_widths()"]
229
-
230
+
230
231
  TableRenderer["TableRenderer<br/>• render_table()<br/>• build_row()<br/>• format_cells()"]
231
-
232
+
232
233
  FinalRenderedTable["Final Rendered Table<br/>(Markdown/CSV String)"]
233
-
234
+
234
235
  TableDataInput --> TableComponent
235
-
236
+
236
237
  TableComponent --> TableDataExtractor
237
238
  TableComponent --> RowProcessor
238
239
  TableComponent --> ColumnWidthCalculator
239
240
  TableComponent --> TableRenderer
240
-
241
+
241
242
  TableDataExtractor --> RowProcessor
242
243
  RowProcessor --> ColumnWidthCalculator
243
244
  ColumnWidthCalculator --> TableRenderer
244
-
245
+
245
246
  TableRenderer --> FinalRenderedTable
246
-
247
+
247
248
  style TableDataInput fill:#e3f2fd
248
249
  style TableComponent fill:#fff3e0
249
250
  style TableDataExtractor fill:#e8f5e8
@@ -256,6 +257,7 @@ graph TD
256
257
  ## 🧩 Core Components
257
258
 
258
259
  ### **1. Extractor (Coordinator)**
260
+
259
261
  - **Purpose**: Main API interface and request coordination
260
262
  - **Responsibilities**:
261
263
  - Parse user configuration
@@ -267,22 +269,29 @@ graph TD
267
269
  ### **2. Specialized Extractors**
268
270
 
269
271
  #### **ConstantsExtractor**
272
+
270
273
  - **Purpose**: Extract constants with inheritance/module support
271
274
  - **Key Features**:
275
+
272
276
  - Own constants: `Class.constants(false)`
273
277
  - Inherited constants: Walk superclass chain
274
- - Module constants: Scan `included_modules`
278
+ - Module constants: Sca `included_modules`
279
+
275
280
  - Source tracking for debugging
276
281
 
277
- #### **MethodsExtractor**
282
+ #### **MethodsExtractor**
283
+
278
284
  - **Purpose**: Extract class methods with inheritance/module support
279
285
  - **Key Features**:
286
+
280
287
  - Own methods: `Class.singleton_methods(false)`
281
288
  - Inherited methods: Walk superclass chain
289
+
282
290
  - Module methods: Scan `singleton_class.included_modules`
283
291
  - Method resolution order handling
284
292
 
285
293
  #### **MultiTypeExtractor**
294
+
286
295
  - **Purpose**: Combine multiple extraction types into unified table
287
296
  - **Key Features**:
288
297
  - Add "Type" column to distinguish behavior types
@@ -294,26 +303,32 @@ graph TD
294
303
  The table component was recently refactored from a monolithic 269-line class into focused, reusable components:
295
304
 
296
305
  #### **TableComponent** (Main Coordinator - 42 lines)
306
+
297
307
  - **Purpose**: Orchestrate table generation process
298
308
  - **Responsibilities**: Initialize sub-components, coordinate data flow
299
309
  - **Pattern**: Composition over inheritance
300
310
 
301
311
  #### **TableDataExtractor** (55 lines)
312
+
302
313
  - **Purpose**: Data structure analysis and extraction utilities
303
314
  - **Key Methods**: `has_type_column?()`, `extract_row_data()`, `collect_hash_keys()`
304
315
  - **Responsibility**: Understand table structure and extract metadata
305
316
 
306
317
  #### **RowProcessor** (125 lines)
318
+
307
319
  - **Purpose**: Process table rows and handle hash expansion
308
320
  - **Key Methods**: `process_simple_rows()`, `process_expanded_rows()`, `expand_row()`
321
+
309
322
  - **Responsibility**: Transform raw data into renderable format
310
323
 
311
324
  #### **ColumnWidthCalculator** (57 lines)
325
+
312
326
  - **Purpose**: Calculate optimal column widths for table rendering
313
327
  - **Key Methods**: `calculate_widths()`, `apply_minimum_widths()`
314
328
  - **Responsibility**: Ensure proper table formatting
315
329
 
316
330
  #### **TableRenderer** (56 lines)
331
+
317
332
  - **Purpose**: Render final table with proper formatting
318
333
  - **Key Methods**: `render_table()`, `build_row()`, `format_cells()`
319
334
  - **Responsibility**: Generate final markdown table output
@@ -321,6 +336,7 @@ The table component was recently refactored from a monolithic 269-line class int
321
336
  ### **4. Formatters**
322
337
 
323
338
  #### **MarkdownFormatter**
339
+
324
340
  - **Purpose**: Generate rich markdown reports
325
341
  - **Key Features**:
326
342
  - Modular component architecture
@@ -329,8 +345,10 @@ The table component was recently refactored from a monolithic 269-line class int
329
345
  - Missing behavior analysis
330
346
 
331
347
  #### **CsvFormatter**
348
+
332
349
  - **Purpose**: Generate CSV output for data analysis
333
350
  - **Key Features**:
351
+
334
352
  - Clean CSV structure
335
353
  - Configurable separators and quotes
336
354
  - Hash flattening options
@@ -338,56 +356,69 @@ The table component was recently refactored from a monolithic 269-line class int
338
356
  ### **5. Support Components**
339
357
 
340
358
  #### **ValueProcessor**
359
+
341
360
  - **Purpose**: Process all Ruby value types consistently
342
361
  - **Handles**: Strings, numbers, booleans, arrays, hashes, nil, errors
343
362
  - **Visual Indicators**: ✅ (true), ❌ (false/nil), 🚫 (errors), ⚠️ (warnings)
344
363
 
345
364
  #### **ClassResolver**
365
+
346
366
  - **Purpose**: Normalize class inputs (strings vs class objects)
347
367
  - **Handles**: Class objects, string class names, error cases
348
368
 
349
369
  ## 🔧 Key Design Patterns
350
370
 
351
371
  ### **1. Fluent Interface**
372
+
352
373
  ```ruby
353
374
  ClassMetrix.extract(:constants)
354
375
  .from([Class1, Class2])
355
376
  .include_inherited
356
377
  .filter(/config/)
378
+
357
379
  .expand_hashes
358
380
  .to_markdown()
359
381
  ```
360
382
 
361
383
  ### **2. Strategy Pattern**
384
+
362
385
  - Different extractors for different extraction types
386
+
363
387
  - Different formatters for different output formats
364
388
  - Pluggable components for different behaviors
365
389
 
366
390
  ### **3. Composition Pattern**
391
+
367
392
  - Table component composed of focused sub-components
393
+
368
394
  - Formatters composed of reusable components
369
395
  - Modular architecture throughout
370
396
 
371
397
  ### **4. Template Method Pattern**
398
+
372
399
  - Base classes define structure
400
+
373
401
  - Subclasses implement specific behaviors
374
402
  - Consistent interfaces across components
375
403
 
376
404
  ## 🚀 Extension Points
377
405
 
378
406
  ### **Adding New Extraction Types**
407
+
379
408
  1. Create new extractor in `extractors/`
380
409
  2. Implement standard interface (`extract` method)
381
410
  3. Add type routing in `MultiTypeExtractor`
382
411
  4. Add API method in `Extractor`
383
412
 
384
413
  ### **Adding New Output Formats**
414
+
385
415
  1. Create new formatter in `formatters/`
386
416
  2. Extend base formatter class
387
417
  3. Implement format-specific logic
388
418
  4. Add API method in `Extractor`
389
419
 
390
420
  ### **Adding New Components**
421
+
391
422
  1. Create component in `formatters/components/`
392
423
  2. Extend `BaseComponent`
393
424
  3. Implement `generate` method
@@ -402,7 +433,7 @@ graph TD
402
433
  subgraph "Test Structure"
403
434
  APITests["API Integration Tests<br/>class_metrix_spec.rb"]
404
435
  ExtractorTests["Core Coordinator Tests<br/>extractor_spec.rb"]
405
-
436
+
406
437
  subgraph "Unit Tests"
407
438
  ExtractorUnitTests["Extractor Unit Tests<br/>extractors/"]
408
439
  FormatterUnitTests["Formatter Tests<br/>formatters/"]
@@ -410,33 +441,34 @@ graph TD
410
441
  UtilsUnitTests["Utility Tests<br/>utils/"]
411
442
  end
412
443
  end
413
-
444
+
414
445
  subgraph "Test Classes Hierarchy"
415
446
  TestParent["TestParent<br/>PARENT_CONSTANT<br/>parent_method()"]
416
447
  TestChild["TestChild<br/>CHILD_CONSTANT<br/>child_method()"]
417
448
  TestGrandchild["TestGrandchild<br/>GRANDCHILD_CONSTANT<br/>grandchild_method()"]
418
-
449
+
419
450
  TestParent --> TestChild
420
451
  TestChild --> TestGrandchild
421
452
  end
422
-
453
+
423
454
  subgraph "Test Modules"
424
455
  TestModule["TestModule<br/>TEST_MODULE_CONSTANT<br/>module_method()"]
425
456
  AnotherTestModule["AnotherTestModule<br/>ANOTHER_CONSTANT<br/>another_module_method()"]
426
457
  end
427
-
458
+
428
459
  subgraph "Realistic Examples"
429
460
  TestUser["TestUser<br/>ROLE_NAME = 'user'<br/>config()"]
430
461
  TestAdmin["TestAdmin<br/>ROLE_NAME = 'admin'<br/>admin_config()"]
431
462
  end
432
-
463
+
433
464
  TestChild -.->|includes| TestModule
434
465
  TestGrandchild -.->|includes| AnotherTestModule
435
-
466
+
436
467
  APITests --> ExtractorTests
468
+
437
469
  ExtractorTests --> ExtractorUnitTests
438
470
  ExtractorTests --> FormatterUnitTests
439
-
471
+
440
472
  ExtractorUnitTests -.->|uses| TestParent
441
473
  ExtractorUnitTests -.->|uses| TestChild
442
474
  ExtractorUnitTests -.->|uses| TestGrandchild
@@ -444,37 +476,44 @@ graph TD
444
476
  ExtractorUnitTests -.->|uses| AnotherTestModule
445
477
  ExtractorUnitTests -.->|uses| TestUser
446
478
  ExtractorUnitTests -.->|uses| TestAdmin
447
-
479
+
480
+
448
481
  style APITests fill:#e3f2fd
449
482
  style ExtractorTests fill:#f3e5f5
450
483
  style TestParent fill:#e8f5e8
451
484
  style TestChild fill:#fff3e0
485
+
452
486
  style TestGrandchild fill:#fce4ec
453
487
  style TestModule fill:#e1f5fe
454
488
  style AnotherTestModule fill:#e1f5fe
455
489
  ```
456
490
 
457
491
  ### **Test Coverage**
492
+
458
493
  - ✅ **Basic Extraction**: Constants and methods from simple classes
459
494
  - ✅ **Inheritance**: Multi-level inheritance chains
460
495
  - ✅ **Modules**: Module inclusion and method resolution
461
496
  - ✅ **Error Handling**: Missing methods, constants, class resolution failures
462
497
  - ✅ **Value Types**: All Ruby value types and edge cases
498
+
463
499
  - ✅ **Integration**: End-to-end functionality with real-world scenarios
464
500
 
465
501
  ## 📈 Performance Considerations
466
502
 
467
503
  ### **Lazy Evaluation**
504
+
468
505
  - Extractors only process data when `to_markdown()`/`to_csv()` is called
469
506
  - Filters applied efficiently during extraction
470
507
  - Minimal memory usage for large class sets
471
508
 
472
509
  ### **Inheritance Optimization**
510
+
473
511
  - Superclass chain traversal is optimized
474
512
  - Core Ruby classes (`Object`, `BasicObject`) are skipped
475
513
  - Module resolution uses efficient set operations
476
514
 
477
515
  ### **Table Rendering Optimization**
516
+
478
517
  - Column width calculation is performed once
479
518
  - Row processing is streamlined
480
519
  - String operations are minimized
@@ -482,20 +521,23 @@ graph TD
482
521
  ## 🔄 Future Architecture Plans
483
522
 
484
523
  ### **Plugin System**
524
+
485
525
  - Plugin architecture for custom extractors
486
526
  - Extension points for custom components
487
527
  - Configuration system for plugin management
488
528
 
489
529
  ### **Caching Layer**
530
+
490
531
  - Cache class metadata for performance
491
532
  - Invalidation strategies for development
492
533
  - Configurable caching backends
493
534
 
494
535
  ### **Parallel Processing**
536
+
495
537
  - Parallel extraction for large class sets
496
538
  - Worker pool for I/O operations
497
539
  - Memory-efficient streaming for large datasets
498
540
 
499
541
  ---
500
542
 
501
- *This architecture document is maintained alongside code changes.*
543
+ _This architecture document is maintained alongside code changes._
@@ -0,0 +1,95 @@
1
+ # ClassMetrix Changelog Evolution Example
2
+
3
+ ## Current State (v1.0.0 released)
4
+
5
+ ```markdown
6
+ ## [Unreleased]
7
+
8
+ ## [1.0.0] - 2025-06-07
9
+
10
+ ### Added
11
+
12
+ - Advanced Debug System
13
+ - Enhanced Hash Expansion
14
+
15
+ # ... existing content
16
+ ```
17
+
18
+ ## After working on some features
19
+
20
+ ```markdown
21
+ ## [Unreleased]
22
+
23
+ ### Added
24
+
25
+ - Instance variable extraction support
26
+ - New output format: JSON
27
+ - CLI interface for command-line usage
28
+
29
+ ### Changed
30
+
31
+ - Improved performance for large class hierarchies
32
+ - Better error messages with suggestions
33
+
34
+ ### Fixed
35
+
36
+ - Memory leak in hash expansion
37
+ - CSV encoding issues with special characters
38
+
39
+ ## [1.0.0] - 2025-06-07
40
+
41
+ # ... existing content
42
+ ```
43
+
44
+ ## Ready for v1.1.0 release
45
+
46
+ ```markdown
47
+ ## [Unreleased]
48
+
49
+ ## [1.1.0] - 2025-07-15
50
+
51
+ ### Added
52
+
53
+ - Instance variable extraction support
54
+ - New output format: JSON
55
+ - CLI interface for command-line usage
56
+
57
+ ### Changed
58
+
59
+ - Improved performance for large class hierarchies
60
+ - Better error messages with suggestions
61
+
62
+ ### Fixed
63
+
64
+ - Memory leak in hash expansion
65
+ - CSV encoding issues with special characters
66
+
67
+ ## [1.0.0] - 2025-06-07
68
+
69
+ # ... existing content
70
+ ```
71
+
72
+ ## Working on next features
73
+
74
+ ```markdown
75
+ ## [Unreleased]
76
+
77
+ ### Added
78
+
79
+ - Plugin system for custom extractors
80
+ - Web UI for interactive analysis
81
+
82
+ ### Changed
83
+
84
+ - Refactored formatter architecture
85
+
86
+ ## [1.1.0] - 2025-07-15
87
+
88
+ ### Added
89
+
90
+ - Instance variable extraction support
91
+ - New output format: JSON
92
+ - CLI interface for command-line usage
93
+
94
+ # ... etc
95
+ ```