0.0
The project is in a healthy, maintained state
Diagram file I/O, omoteura: link resolution and CLI for Omoteura
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

omoteura: code in front, context behind.

Omoteura CI

Code in front, context behind.

The code is the omote (front). Behind it sits an Excalidraw drawing, the ura (back): diagrams, notes and the reasons behind the code, with shapes that link to the tests and methods they describe.

Status: early. The gems are on RubyGems and the extension is on the Visual Studio Marketplace. Until 1.0, minor versions may change how things work; CHANGELOG.md says what changed.

Features

Drawn by You

Omoteura never generates diagrams. Draw them in Obsidian's Excalidraw plugin or on excalidraw.com, the way you would sketch on a whiteboard, and drop the file next to your code.

Linked by Name

A shape's link names a spec description, a method or the start of a statement, not a line number, so links survive the edits around them.

Checked in CI

omoteura check fails the build when a spec is renamed and a diagram still points at the old name, or when a diagram is left behind by a moved file.

Hands Off Your Code

Omoteura only reads files. It runs from the command line and next to RSpec, never inside your application, never rewrites your code and does nothing at all where there is no diagram.

Light

Omoteura reads every Ruby file in a project, so it is measured for allocations as well as time. Files without a magic comment are skipped without allocating.

Supported Versions

  • Ruby 3.4, 4.0

  • Rails 7.1, 7.2, 8.0, 8.1 projects; Omoteura reads their files and never loads Rails

  • RSpec 3.12+ or Minitest 5.21+

  • Excalidraw (.excalidraw) and Obsidian Excalidraw (.excalidraw.md)

Installation

Put this in your Gemfile:

group :development, :test do
  gem "omoteura", require: false
end

require: false keeps Rails from loading Omoteura into your application; the omoteura command and your test framework load what they need. Then bundle:

% bundle

omoteura installs the following gems. You can also pick only the ones you need.

gem contents
omoteura-core Diagram files, omoteura: links and the omoteura command
omoteura-rspec A formatter that records RSpec results for diagrams
omoteura-minitest A reporter that records Minitest results for diagrams

Attaching Diagrams

By Path

Put the diagram under ura/ at the same path as the code. Nothing else is needed.

code diagram
app/models/user.rb ura/app/models/user.excalidraw.md
spec/models/user_spec.rb ura/spec/models/user_spec.excalidraw

When both .excalidraw.md and .excalidraw exist, .excalidraw.md is used.

By Magic Comment

To share one diagram between files or give it any name, write a magic comment on its own line at the top or the bottom of the file:

class User < ApplicationRecord
end

# omoteura: ura/shared/user-validations.excalidraw.md

A path copied from Obsidian without its .md works too.

By .omoteura.yml

To leave the code untouched, map files in .omoteura.yml:

attach:
  app/models/user.rb: ura/shared/user-validations.excalidraw.md

A magic comment wins over .omoteura.yml, which wins over the path.

Drafting a Diagram

A blank page is the hardest part, so Omoteura can draft a diagram to draw on:

% bundle exec omoteura draft spec/models/user_spec.rb
wrote ura/spec/models/user_spec.excalidraw (4 shapes)

A spec gets a column per example group and a box per example; other code gets a column per kind of declaration (validations, associations, callbacks, scopes, enums) and one for public methods. Every box already links to its code, so test results show up straight away. Then make it yours: move, delete, annotate.

A draft never replaces a diagram. When the file already has one, it goes beside it as user_spec.draft.excalidraw for you to copy from, and omoteura check reminds you to delete it. --format md writes an Obsidian .excalidraw.md note instead, and --dry-run, --only methods,validations and --out DIR are available too.

As the code grows, --merge adds what the diagram has no shape for yet, in columns to the right of everything drawn. A shape counts as drawn when its link points at the same code or its label is the same, and nothing drawn is moved or removed:

% bundle exec omoteura draft spec/models/user_spec.rb --merge
added 2 shapes to ura/spec/models/user_spec.excalidraw

Linking Shapes to Code

Set a shape's link to text starting with omoteura:. Both Excalidraw and Obsidian let you edit a shape's link.

link points to
omoteura:#email is unique the spec whose description ends with "email is unique", in the attached file
omoteura:#display_name the describe "#display_name" group, or the method
omoteura:spec/models/user_spec.rb#validations email is unique the same, in another file
omoteura:app/models/user.rb#validates :email the statement that starts with that text
omoteura:app/models/user.rb the whole file

A fragment is tried as a spec description, then a method name, then the start of a statement. A link that matches nothing, or more than one place, is broken.

Checking Links

% bundle exec omoteura check
ura/app/models/user.excalidraw: omoteura:#full_name matches nothing in app/models/user.rb (shape "Display name")
Checked 12 diagrams and 48 links: 1 problem.

It reports broken links, missing or unreadable diagrams and diagrams no code file is attached to, and exits with status 1 when there are any. In GitHub Actions, add --format github to see the problems as annotations.

Recording Test Results

With RSpec, add the formatter to .rspec, next to your usual one:

--format progress
--format Omoteura::RSpec::Formatter --out tmp/omoteura/results.json

With Minitest, including Rails' bin/rails test, require the reporter in test/test_helper.rb:

require "omoteura/minitest"

Each test's status and failure message go to tmp/omoteura/results.json (for Minitest, OMOTEURA_RESULTS names another path). Keep tmp/omoteura/ out of version control.

Minitest tests link like RSpec examples: in a test class such as UserTest < ActiveSupport::TestCase, test "requires an email" is omoteura:#requires an email, and def test_display_name is omoteura:#test_display_name. The coverage panel looks for test/models/user_test.rb as well as spec/models/user_spec.rb.

When something already measures coverage, as SimpleCov does, the formatter and the reporter also record which lines of your code ran, so the coverage panel can tell which methods the tests called. They never start coverage themselves.

In VS Code

The Omoteura extension (source) marks each line a shape links to with the result of the tests behind it, explains it on hover, and flips between a file and its diagram with ⌥⌘U (Ctrl+Alt+U). The diagram opens in Excalidraw with linked shapes outlined by test status; clicking a link opens the code. Saving writes the file's own format, so an Obsidian note keeps everything around the drawing, and a change made elsewhere since it opened is never overwritten. A coverage panel lists which declarations and public methods of the open file its tests cover.

Commands

command does
omoteura check Report broken links and diagrams not attached to code
omoteura draft FILE... Draft a diagram from code, as a starting point to draw on
omoteura inspect FILE Print one file's diagram, links and test results as JSON, for editors
omoteura diagram FILE Print one diagram's drawing, links and test results as JSON, for editors
omoteura links FILE Print the places in one code file a shape can link to, with their links, as JSON, for editors
omoteura coverage FILE Print which declarations and public methods of one file its tests cover, as JSON, for editors
omoteura save FILE Save a drawing an editor changed, read as JSON from stdin, in the file's format
omoteura version Print the version

Run omoteura <command> --help for options.

Configuring Omoteura

.omoteura.yml at the project root is optional:

key default meaning
diagrams_dir ura Where diagrams live, relative to the root
attach none Code paths mapped to diagram paths
coverage_panel true false turns off the editor's list of tested and untested declarations and methods

.omoteura.local.yml is read on top of it, entry by entry, for settings of your own. Keep it out of version control.

Questions, Feedback

Open an issue on GitHub. Report security problems privately as described in SECURITY.md.

Contributing to Omoteura

Fork, fix, then send a pull request. CONTRIBUTING.md has the details.

To run the specs and lint:

% nix develop          # or use Ruby 3.4+ without Nix
% bundle install
% bundle exec rake

To run the specs against the oldest supported rspec-core:

% BUNDLE_GEMFILE=gemfiles/rspec_3_12.gemfile bundle install
% BUNDLE_GEMFILE=gemfiles/rspec_3_12.gemfile bundle exec rake spec

To measure allocations and time of the main code paths:

% bundle exec rake bench

Copyright

Copyright (c) 2026- KAIBYAKU K.K. See LICENSE for further details.