StructuredMerge Ruby
StructuredMerge Ruby provides Ruby gems for building merge-aware tools that need portable structured-merge contracts, fixture-backed behavior, and Ruby-native integration points.
The monorepo includes the core AST/review contracts, parser substrate support, format-specific merge gems, binary/ZIP planning helpers, provider adapters, and a Ruby packaging recipe gem.
Project links:
- Website: https://structuredmerge.org
- Implementations: https://structuredmerge.org/implementations.html
- Specification: https://github.com/structuredmerge/structuredmerge-spec
- Shared fixtures: https://github.com/structuredmerge/structuredmerge-fixtures
Package Family
StructuredMerge Ruby is a layered gem family. The lower layers provide parser, range, AST, merge, and template contracts; format gems apply those contracts to specific languages and data formats; provider gems bind a format family to a parser or serializer; workflow gems package the behavior for Git drivers, release automation, and monorepo maintenance.
Package README files keep this section short and link here. This root guide is the implementation inventory for Ruby users who need to choose gems, understand backend coverage, or wire a focused backend into a test suite.
The family is intentionally layered:
-
tree_haverprovides parser portability, backend discovery, byte ranges, and runtime capability reporting. -
ast-mergeprovides the cross-format merge substrate: shared base classes, layout/comment ownership, diagnostics, review state, and execution reports. - Family gems such as
markdown-merge,yaml-merge, andtoml-mergeown parser-neutral behavior for one format family. - Provider gems such as
markly-merge,psych-merge, andcitrus-toml-mergeregister backend-specific parser/emitter behavior. - Workflow gems such as
ast-merge-git,smorg-rb, andkettle-jempackage the family for Git, release, and templating workflows.
Core and Workflow Gems
| Gem | Layer | What it provides |
|---|---|---|
tree_haver |
Parser substrate | Parser backend registry, byte ranges, node wrappers, source locations, binary tree contracts, and backend selection helpers. |
ast-merge |
Merge substrate | AST merge contracts, diagnostics, structural edit plans, review/replay vocabulary, nested merge orchestration, backend provider registration, and shared spec helpers. |
ast-template |
Template substrate | Template/session transport objects used by recipe tooling and language-specific templating layers. |
ast-merge-git |
Git integration | Merge-driver, diff-driver, conflict inspection, language registry, and command plumbing for smorg-rb. |
smorg-rb |
Command package | Ruby implementation command packaging and executable entry points. |
kettle-jem |
Recipe tooling | Template recipes, monorepo root materialization, gem maintenance helpers, and StructuredMerge Ruby release support. |
Transformation Gems
| Gem | Layer | What it provides |
|---|---|---|
ast-crispr |
Generic AST edits | Structured document surgery recipes for generated blocks and template-owned regions. |
ast-crispr-ruby-prism |
Ruby AST edits | Prism-backed Ruby source edits, including require insertion and template-managed Ruby regions. |
ast-crispr-markdown-markly |
Markdown AST edits | Markly-backed Markdown block replacement and README recipe support. |
Format Gems
| Gem | Family | What it provides |
|---|---|---|
plain-merge |
Text | Plain-text fallback contracts and conflict-preserving merge behavior. |
json-merge |
JSON and JSONC | Object/array-aware JSON merge behavior using the shared StructuredMerge merge substrate and tree-sitter JSON grammar coverage where the selected backend supplies it. |
yaml-merge |
YAML | YAML-family merge contracts, shared provider tags, and provider-neutral behavior. |
toml-merge |
TOML | TOML-family merge contracts and provider-neutral behavior. |
dotenv-merge |
dotenv | Environment-file merge behavior for key/value configuration files. |
markdown-merge |
Markdown | Markdown-family merge contracts, heading/table/list matching, link-reference handling, fenced-code flow, and provider-neutral behavior. |
ruby-merge |
Ruby source | Ruby source merge contracts and parser-backed source-language behavior. |
rbs-merge |
RBS | Ruby signature merge behavior, declaration matching, and template-owned signature updates using RBS and tree-sitter RBS grammar coverage where available. |
bash-merge |
Bash source | Shell source merge contracts and parser-backed shell-language behavior using tree-sitter Bash where available. |
go-merge |
Go source | Go source merge contracts for the cross-language StructuredMerge family. |
rust-merge |
Rust source | Rust source merge contracts for the cross-language StructuredMerge family. |
typescript-merge |
TypeScript source | TypeScript source merge contracts for the cross-language StructuredMerge family. |
binary-merge |
Binary | Binary tree planning contracts, byte-range ownership, diagnostics, and Kaitai Struct oriented structured binary support. |
zip-merge |
Archives | ZIP archive planning helpers, archive member ownership, and archive-aware merge contracts. |
Provider Gems
Provider gems register themselves with the backend tag system used by
ast-merge and tree_haver. That registry lets a spec suite run against a
single selected backend, lets a format gem ask for a capability instead of a
hard dependency, and keeps parser-specific behavior out of provider-neutral
merge gems.
| Gem | Provides | Runtime notes |
|---|---|---|
psych-merge |
YAML provider | Uses Ruby's Psych parser and emitter. |
citrus-toml-merge |
TOML provider | Uses a Citrus grammar and pure-Ruby parser path, commonly paired with toml-rb style TOML data handling. |
parslet-toml-merge |
TOML provider | Uses Parslet and pure-Ruby parser path, commonly paired with toml style TOML data handling. |
commonmarker-merge |
Markdown provider | Uses CommonMarker for CommonMark-oriented Markdown parsing. |
kramdown-merge |
Markdown provider | Uses Kramdown for Ruby-native Markdown parsing. |
markly-merge |
Markdown provider | Uses Markly for cmark-gfm-backed Markdown parsing and README templating support. |
prism-merge |
Ruby provider | Uses Prism for Ruby source parsing and Ruby-specific merge refiners. |
Ruby Backend Notes
Ruby has the broadest backend surface in the StructuredMerge implementation set.
tree_haver owns the parser backend registry and byte-range contracts;
ast-merge owns provider registration and merge orchestration. The backend
tags are capability names, not package preferences.
| Backend or provider path | Used by | Notes |
|---|---|---|
:TSLP |
source-family gems | Uses tree-sitter-language-pack parser aggregation where available. This is the preferred tree-sitter provider path for broad language coverage. |
:MRI |
source-family gems | Uses ruby_tree_sitter; retained as the MRI-native tree-sitter backend name. |
:rust |
source-family gems | Uses tree_stump where that native Rust-backed parser path is selected. |
:ffi |
source-family gems | Uses FFI bindings to libtree-sitter; suitable where the runtime and native library support the needed ABI. |
:java |
source-family gems | Uses JVM tree-sitter bindings through java-tree-sitter / jtreesitter for JRuby-oriented parser runs. |
| Prism |
ruby-merge, prism-merge, ast-crispr-ruby-prism
|
Ruby-native parser path for Ruby source and structured Ruby source edits. |
| Psych |
yaml-merge, psych-merge
|
Ruby standard YAML parser/emitter path. |
| RBS | rbs-merge |
Ruby signature parser path. |
| CommonMarker, Markly, Kramdown |
markdown-merge providers |
Markdown parser families with different CommonMark/GFM/Ruby-native tradeoffs. |
| Citrus, Parslet |
toml-merge providers |
Pure-Ruby TOML parser families used as provider-specific backend paths. |
| Kaitai Struct | binary-merge |
Schema-oriented binary parsing support for structured binary work. |
Backend Platform Compatibility
tree_haver supports multiple Ruby parser backends, but not every backend works
on every Ruby runtime:
| TreeHaver backend | MRI | JRuby | TruffleRuby | Notes |
|---|---|---|---|---|
:TSLP (tree-sitter-language-pack) |
✅ | ❓ | ❓ | Aggregated tree-sitter provider used by StructuredMerge language-family gems where available. |
:MRI (ruby_tree_sitter) |
✅ | ❌ | ❌ | C extension, MRI only. |
:rust (tree_stump) |
✅ | ❌ | ❌ | Rust extension through Ruby native-extension tooling, MRI only. |
:ffi (FFI + libtree-sitter) |
✅ | ✅ | ❌ | TruffleRuby FFI does not support the tree-sitter struct-by-value ABI. |
:java (java-tree-sitter / jtreesitter) |
❌ | ✅ | ❌ | JRuby-oriented path that requires matching grammar JARs. |
| Prism | ✅ | ✅ | ✅ | Ruby parser, standard library in Ruby 3.4+. |
| Psych | ✅ | ✅ | ✅ | YAML parser/emitter, standard library. |
| Citrus | ✅ | ✅ | ✅ | Pure Ruby PEG parser. |
| Parslet | ✅ | ✅ | ✅ | Pure Ruby PEG parser. |
| CommonMarker | ✅ | ❌ | ❓ | Native Markdown parser used through commonmarker-merge. |
| Markly | ✅ | ❌ | ❓ | Native cmark-gfm parser used through markly-merge. |
| Kramdown | ✅ | ✅ | ✅ | Pure Ruby Markdown parser. |
Legend: ✅ = works, ❌ = does not work, ❓ = not part of the supported runtime claim.
Install
Install the gems your tool needs:
bundle add ast-merge json-mergeCommand
The Ruby implementation ships the implementation-specific smorg-rb command.
Use that name in git configuration unless a package manager or local install has
provided a smorg symlink.
Package-manager formulas may expose the selected implementation as smorg.
For a local user-created symlink:
ln -s "$(command -v smorg-rb)" ~/.local/bin/smorggit config merge.smorg-rb.driver 'smorg-rb merge-driver %O %A %B %P'
git config diff.smorg-rb.command 'smorg-rb diff-driver'
smorg-rb conflicts diff path/to/file-with-conflicts.go
smorg-rb languages --gitattributesmerge-driver updates Git's %A file by default, or writes to --output when
used outside git. diff-driver accepts both the two-argument local form and the
seven- or nine-argument forms Git passes to external diff commands.
conflicts diff reports conflict-marker regions in a file that already contains
Git conflict markers.
Semantic merge-driver coverage is fixture-backed for JSON. Other language and format paths are git-compatible command surfaces without semantic driver coverage.
Gems
Core:
-
tree_haver- parser substrate, byte ranges, backend adapters, and binary tree contracts. -
ast-merge- AST merge contracts, diagnostics, planning, review, replay, and nested-merge vocabulary. -
ast-template- template/session transport contracts.
Format libraries:
plain-mergejson-mergeyaml-mergetoml-mergemarkdown-mergeruby-mergego-mergerust-mergetypescript-mergebinary-mergezip-merge
Provider and recipe gems:
psych-mergecitrus-toml-mergeparslet-toml-mergecommonmarker-mergekramdown-mergemarkly-mergeprism-mergekettle-jem
Portability
The Ruby gems are developed against the shared StructuredMerge fixtures. Those fixtures define the cross-language behavior expected from the Go, TypeScript, Rust, and Ruby implementations. Conformance checks live in gem specs and in the shared spec/fixture tooling rather than in a static status document.
Development
Common checks:
mise run checkbundle exec rake- package-specific
bundle exec rspeccommands
Bundler path gems are the default isolation mechanism inside this monorepo. When
this repository needs to consume sibling workspace projects outside the monorepo
itself, prefer nomono-driven Bundler wiring rather than manual Ruby load-path
changes.