AGENTS.md - jsonc-merge Development Guide
๐ฏ Project Overview
jsonc-merge is a format-specific implementation of the *-merge gem family for JSONC (JSON with Comments) files. It provides intelligent JSONC file merging using AST analysis with tree-sitter JSONC parser.
Core Philosophy: Intelligent JSONC merging that preserves structure, comments, and formatting while applying updates from templates.
Repository: https://github.com/kettle-rb/jsonc-merge
Current Version: 1.0.1
Required Ruby: >= 3.2.0 (currently developed against Ruby 4.0.1)
๐๏ธ Architecture: Format-Specific Implementation
What jsonc-merge Provides
-
Jsonc::Merge::SmartMergerโ JSONC-specific SmartMerger implementation -
Jsonc::Merge::FileAnalysisโ JSONC file analysis with object/array extraction -
Jsonc::Merge::NodeWrapperโ Wrapper for JSONC AST nodes -
Jsonc::Merge::MergeResultโ JSONC-specific merge result -
Jsonc::Merge::ConflictResolverโ JSONC conflict resolution -
Jsonc::Merge::FreezeNodeโ JSONC freeze block support -
Jsonc::Merge::DebugLoggerโ JSONC-specific debug logging
Key Dependencies
| Gem | Role |
|---|---|
ast-merge (~> 4.0) |
Base classes and shared infrastructure |
tree_haver (~> 5.0) |
Unified parser adapter (tree-sitter) |
version_gem (~> 1.1) |
Version management |
Parser Backend Support
jsonc-merge works with tree-sitter JSONC parser via TreeHaver:
| Backend | Parser | Platform | Notes |
|---|---|---|---|
:mri |
tree-sitter-jsonc | MRI only | Best performance, requires native library |
:rust |
tree-sitter-jsonc | MRI only | Rust implementation via tree_stump |
:ffi |
tree-sitter-jsonc | All platforms | FFI binding, works on JRuby/TruffleRuby |
๐ Project Structure
lib/jsonc/merge/
โโโ smart_merger.rb # Main SmartMerger implementation
โโโ file_analysis.rb # JSONC file analysis
โโโ node_wrapper.rb # AST node wrapper
โโโ merge_result.rb # Merge result object
โโโ conflict_resolver.rb # Conflict resolution
โโโ freeze_node.rb # Freeze block support
โโโ debug_logger.rb # Debug logging
โโโ version.rb
spec/jsonc/merge/
โโโ smart_merger_spec.rb
โโโ file_analysis_spec.rb
โโโ node_wrapper_spec.rb
โโโ integration/
๐ง Development Workflows
Running Tests
# Full suite
bundle exec rspec
# Single file (disable coverage threshold check)
K_SOUP_COV_MIN_HARD=false bundle exec rspec spec/jsonc/merge/smart_merger_spec.rb
# Specific backend tests
bundle exec rspec --tag mri_backend
bundle exec rspec --tag rust_backend
bundle exec rspec --tag ffi_backend
Coverage Reports
cd /home/pboling/src/kettle-rb/ast-merge/vendor/jsonc-merge
bin/rake coverage && bin/kettle-soup-cover -d
๐ Project Conventions
API Conventions
SmartMerger API
-
mergeโ Returns a String (the merged JSONC content) -
merge_resultโ Returns a MergeResult object -
to_son MergeResult returns the merged content as a string
JSONC-Specific Features
Comment Support:
{
// Line comment
"key": "value",
/* Block comment */
"another": "value"
}
Freeze Blocks:
{
"config": {
// jsonc-merge:freeze
"customValue": "don't override",
"preserveThis": 42
// jsonc-merge:unfreeze
}
}
๐งช Testing Patterns
TreeHaver Dependency Tags
Available tags:
-
:jsonc_grammarโ Requires JSONC grammar (any backend) -
:mri_backendโ Requires tree-sitter MRI backend -
:rust_backendโ Requires tree-sitter Rust backend -
:ffi_backendโ Requires tree-sitter FFI backend -
:jsonc_parsingโ Requires any JSONC parser
โ CORRECT:
RSpec.describe Jsonc::Merge::SmartMerger, :jsonc_grammar do
# Skipped if no JSONC parser available
end
โ WRONG:
before do
skip "Requires tree-sitter" unless tree_sitter_available? # DO NOT DO THIS
end
๐ก Key Insights
- JSONC = JSON + Comments: Full comment support unlike plain JSON
- Comment preservation: Comments are associated with nodes and preserved during merge
-
Freeze blocks use
// jsonc-merge:freeze: Standard comment syntax - Multi-backend support: Works with MRI, Rust, and FFI backends
-
Backend isolation is critical: Always use
TreeHaver.with_backend
๐ซ Common Pitfalls
-
NEVER mix FFI and MRI backends โ Use
TreeHaver.with_backendfor isolation -
NEVER use manual skip checks โ Use dependency tags (
:jsonc_grammar,:mri_backend) - Do NOT load vendor gems โ They are not part of this project; they do not exist in CI
-
Use
tmp/for temporary files โ Never use/tmpor other system directories
๐ง JSONC-Specific Notes
Comment Types
// Single-line comment
/* Multi-line
comment */
{
"key": "value" // Trailing comment
}
Merge Behavior
- Objects: Matched by key name; deep merging of nested objects
- Arrays: Can be merged or replaced based on preference
- Comments: Preserved and associated with their nodes
- Freeze blocks: Protect customizations from template updates