Guidance for AI agents working at the root of the ruby-ui/ruby_ui monorepo.
Two sibling projects, each independent (own Gemfile, package.json, tests, lockfiles):
| Path | What it is |
|---|---|
gem/ |
The ruby_ui gem — Phlex components, generators, gemspec, Minitest suite. Published to RubyGems from here. |
docs/ |
Rails 8 app powering https://rubyui.com. Consumes the local gem via path: "../gem". |
.github/workflows/ci.yml |
Unified CI: gem tests (Ruby 3.3 + 3.4), docs Rails tests, docker build for docs devcontainer. |
Subproject-specific instructions live in gem/AGENTS.md and docs/CLAUDE.md (→ docs/AGENTS.md). Read those before editing inside a subdir.
- Component code →
gem/lib/ruby_ui/<component>/. Tests →gem/test/ruby_ui/<component>_test.rb. - Component docs view →
docs/app/views/docs/<component>.rb. Update in same PR as the component. - Generator/installer logic →
gem/lib/generators/ruby_ui/. Dependency map →gem/lib/generators/ruby_ui/dependencies.yml. - Site chrome, routes, marketing pages →
docs/app/.
Run from the relevant subdir, not root.
# Gem
cd gem
bundle exec rake # tests + standardrb
bundle exec rake test TEST=test/ruby_ui/button_test.rb
bundle exec standardrb --fix
# Docs site
cd docs
bin/setup
bin/dev # local server
pnpm build && pnpm build:css # assets
bin/rails db:test:prepare test
bundle exec standardrb- Ruby 3.2+, 2-space indent,
snake_casefiles/methods,CamelCaseclasses. StandardRB enforced. - Components extend
RubyUI::Base < Phlex::HTML; classes merged viatailwind_merge. Invoke asRubyUI.<Name>()(Phlex::Kit). - Stimulus controllers colocated with components:
<component>_controller.js. JS deps declared ingem/package.jsonand per-component independencies.yml. - Tests extend
ComponentTest; render viaphlex { ... }helper.
A release is not done until all four steps below are complete. Skipping the publish, the docs/website reflection, or the git tag leaves the release half-finished.
Decide the bump with SemVer against commits since the last vX.Y.Z tag: new backward-compatible features → minor; bug fixes / docs only → patch. List the range with git log --oneline vX.Y.Z..HEAD.
-
Bump the version (gem). Edit
RubyUI::VERSIONingem/lib/ruby_ui.rb. Then from each app dir regenerate lockfiles so the path dependency tracks the new version:gem/Gemfile.lockanddocs/Gemfile.lockshould both readruby_ui (X.Y.Z). -
Publish the gem to RubyGems. From
gem/:gem build ruby_ui.gemspecthengem push ruby_ui-X.Y.Z.gem. The account has MFA, sogem pushprompts for a one-time password — have the OTP ready (or pass--otp <CODE>). Confirm the publishing account is listed ingem owner ruby_uifirst. Do not commit the built.gemartifact. -
Reflect the version on the docs website (PR against
main). Releases go through a[Release] vX.Y.ZPR (main is protected — no direct pushes). The PR bundles, on arelease/vX.Y.Zbranch:- the
gem/lib/ruby_ui.rbbump + both regeneratedGemfile.locks; docs/app/views/pages/home.rb— update the home hero badge copy to the headline features (the header version badge readsRubyUI::VERSIONand updates automatically; do not hardcode it);mcp/data/registry.json— rebuild withcd mcp && bundle exec rake mcp:build(reads../gem, so it picks up the new version).
- the
-
Tag + GitHub release. After the release PR merges, tag
vX.Y.Zon the merge commit, push the tag, and cut the GitHub release. The git tag and the published gem must both exist — publishing the gem without tagging (or vice versa) is an incomplete release. -
Hand over the announcement URL (final step). As the last step, give the user a ready-to-post X.com (Twitter) share link for the RubyUI account — the user posts it manually. Use the prefilled-tweet intent URL with the body URL-encoded:
https://x.com/intent/post?text=RubyUI%20X.Y.Z%20released%21%20%F0%9F%9A%80%0A%0Ahttps%3A%2F%2Fwww.rubyui.com%2Fdocs%2Fchangelogwhich decodes to:
RubyUI X.Y.Z released! 🚀 https://www.rubyui.com/docs/changelogSubstitute the real full
X.Y.Z(e.g.1.4.0) in the encodedtext— always include all three numbers so patch releases get announced too. Output the link so the user can open and post it.
- Bracketed prefixes (
[Feature],[Bug Fix],[Documentation]) or scoped conventional (feat(scope): ...). - Imperative, focused commits. Reference issues/PRs as
(#123). - PRs: linked issue, concise description, before/after screenshots for UI changes, explicit test steps.
- Don't run commands from repo root expecting them to work —
cd gemorcd docsfirst. - Don't edit a component without updating its
docs/app/views/docs/<component>.rbcounterpart. - Don't bump the gem version from
docs/;RubyUI::VERSIONlives ingem/lib/ruby_ui.rband the gem is published fromgem/. (The release PR also reflects the version intodocs/andmcp/— see Releasing.) - Don't call a release done after only publishing the gem — tag
vX.Y.Zand reflect the version on the website too. - Don't commit secrets; each app uses local env config.