mbeditor
Mbeditor (Mini Browser Editor) is a mountable Rails engine that adds a browser-based editor UI to a Rails app.
Features
- Two-pane tabbed editor with drag-to-move tabs
- File tree and project search
- Git panel with working tree changes, unpushed file changes, and branch commit titles
- Optional RuboCop lint and format endpoints (uses host app RuboCop)
- Optional test runner with inline failure markers and a dedicated results panel (Minitest and RSpec)
Security Warning
Mbeditor exposes read and write access to your Rails application directory over HTTP. It is intended only for local development.
- Never install mbeditor in production or staging.
- Never run it on infrastructure accessible to untrusted users.
- Always keep it in the development group in your Gemfile.
- The engine enforces environment restrictions at runtime, and Gemfile scoping is a second line of defense that keeps the gem out of deploy builds.
Installation
- Add the gem to the host app Gemfile in development only:
gem 'mbeditor', group: :development- Install dependencies:
bundle install- Mount the engine in host app routes:
mount Mbeditor::Engine, at: "/mbeditor"-
Create
config/initializers/mbeditor.rbusing the configuration options below. -
Boot your app and open
/mbeditor.
Configuration
Use a single initializer to set the engine options you need:
Mbeditor.configure do |config|
config.allowed_environments = [:development]
# config.workspace_root = Rails.root
config.excluded_paths = %w[.git tmp log node_modules .bundle coverage vendor/bundle]
config.rubocop_command = "bundle exec rubocop"
# Optional authentication (runs as a before_action in the engine controllers)
# config.authenticate_with = proc { redirect_to login_path unless UserSession.find }
# Optional test runner (Minitest or RSpec)
# config.test_framework = :minitest # :minitest or :rspec — auto-detected when nil
# config.test_command = "bundle exec rails test" # defaults to bin/rails test or bundle exec ruby -Itest
# config.test_timeout = 60
# Optional Redmine integration
# config.redmine_enabled = true
# config.redmine_url = "https://redmine.example.com/"
# config.redmine_api_key = "optional_api_key_override"
# config.redmine_ticket_source = :commit # :commit (scan recent commit messages for #123) or :branch (leading digits of branch name)
endAvailable options:
-
allowed_environmentscontrols which Rails environments can access the engine. Default:[:development]. -
authenticate_withaccepts a proc that runs as abefore_actionin all engine controllers. Use it to plug in the host app's authentication. The proc executes viainstance_execinside the engine controller, so it has access tosession,cookies,redirect_to, and auth library class methods (e.g. Authlogic'sUserSession.find), but not helper methods defined in the host app'sApplicationController. Default:nil(no authentication). -
workspace_rootsets the root directory exposed by Mbeditor. Default:Rails.rootfrom the host app. -
excluded_pathshides files and directories from the tree and path-based operations. Entries without/match names anywhere in the workspace path; entries with/match relative paths and their descendants. Default:%w[.git tmp log node_modules .bundle coverage vendor/bundle]. -
rubocop_commandsets the command used for inline Ruby linting and formatting. Default:"rubocop". -
test_frameworksets the test framework.:minitestor:rspec. Auto-detected from file suffix,.rspec, ortest/specdirectory whennil. Default:nil. -
test_commandoverrides the full command used to run a test file. Whennil, the engine picksbin/rails test(Minitest) orbin/rspec/bundle exec rspec(RSpec). Default:nil. -
test_timeoutsets the maximum seconds a test run may take before being killed. Default:60. -
redmine_enabledenables issue lookup integration. Default:false. -
redmine_urlsets the Redmine base URL. Required whenredmine_enabledistrue. -
redmine_api_keysets the Redmine API key. Required whenredmine_enabledistrue. -
redmine_ticket_sourcecontrols how the current Redmine ticket is identified.:commitscans the 100 most recent branch commits for a#123reference in the commit message.:branchreads the leading digits from the branch name (e.g.123-my-feature→ ticket 123). Default::commit.
Test Runner
The Test button appears in the editor toolbar for any .rb file when a test/ or spec/ directory exists in the workspace root. Clicking it:
- Resolves the active source file to its matching test file using standard Rails conventions (
app/models/user.rb→test/models/user_test.rb). If the open file is already a test file, it runs that file directly. - Runs the test file using the configured command in a subprocess with a timeout.
- Shows a Test Results panel with pass/fail counts, per-test status icons, and error messages.
- Optionally overlays inline failure markers in the Monaco editor (separate from RuboCop markers — the two never interfere). Use the marker icon in the panel header to toggle them.
Framework auto-detection order:
- File suffix:
_spec.rb→ RSpec,_test.rb→ Minitest -
.rspecfile present → RSpec -
spec/directory present → RSpec -
test/directory present → Minitest
Default commands (when test_command is not set):
- Minitest:
bin/rails test <file>ifbin/railsexists, otherwisebundle exec ruby -Itest <file> - RSpec:
bin/rspec <file>ifbin/rspecexists, otherwisebundle exec rspec --format json <file>
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Ctrl+P |
Quick-open file by name |
Ctrl+S |
Save the active file |
Ctrl+Shift+S |
Save all dirty files |
Alt+Shift+F |
Format the active file |
Ctrl+Shift+G |
Toggle the git panel |
Ctrl+Z / Ctrl+Y
|
Undo / Redo (Monaco built-in) |
Host Requirements (Optional)
The gem keeps host/tooling responsibilities in the host app:
-
rubocopandrubocop-railsgems (optional, required for Ruby lint/format endpoints) -
haml_lintgem (optional, required for HAML lint — add to your app's Gemfile if needed) -
gitinstalled in environment (for Git panel data) -
minitestorrspecin the host app's bundle (required for the test runner)
All lint and test tools are auto-detected at runtime. The engine gracefully disables features if the tools are not available. Neither rubocop, haml_lint, nor any test framework are runtime dependencies of the gem itself — they are discovered from the host app's environment.
Syntax Highlighting Support
Monaco runtime assets are served from the engine route namespace (/mbeditor/monaco-editor/* and /mbeditor/monaco_worker.js).
The gem includes syntax highlighting for common Rails and React development file types:
Web & Template Languages:
- Ruby (.rb, Gemfile, gemspec, Rakefile)
- HTML
- ERB (.html.erb, .erb) — Handlebars-based template syntax
- HAML (.haml) — plaintext syntax highlighting (no dedicated HAML grammar in Monaco; haml-lint provides inline error markers when available)
- CSS and SCSS stylesheets
JavaScript & React:
- JavaScript (.js, .jsx)
- TypeScript for JSX with full language server support
Configuration & Documentation:
- YAML (.yml, .yaml)
- Markdown (.md)
These language modules are packaged locally with the gem for true offline operation. No network fallback is needed—all highlighting works without internet connectivity.
Asset Pipeline
Mbeditor requires Sprockets (sprockets-rails >= 3.4). Host apps using Propshaft as their asset pipeline are not supported — the engine depends on Sprockets directives to load its JavaScript and CSS assets.
Development
A minimal dummy Rails app is included for local development and testing:
cd test/dummy && rails serverThen visit http://localhost:3000/mbeditor.
Testing
The test suite uses Minitest via the dummy Rails app. Run all tests from the project root:
bundle exec rake testRun a single test file:
bundle exec ruby -Itest test/controllers/mbeditor/editors_controller_test.rbRun a single test by name:
bundle exec ruby -Itest test/controllers/mbeditor/editors_controller_test.rb -n test_ping_returns_ok