all_in_ruby

Tell your AI coding agents to write scripts in Ruby.

Adds a "write throwaway and utility scripts in Ruby" instruction to agent instruction files - CLAUDE.md for Claude Code, AGENTS.md for Codex, OpenCode, and Cursor. Additive and idempotent: your existing instructions are never modified.

Installation

gem install all_in_ruby

Quick Start

Add the instruction to the current repo:

all-in-ruby install

Or add it globally, for every project:

all-in-ruby install --global

This writes to ~/.claude/CLAUDE.md, ~/.codex/AGENTS.md, and ~/.config/opencode/AGENTS.md. If CODEX_HOME is set, it is used instead of ~/.codex, matching Codex's own resolution.

Cursor has no global rules file — its global "User Rules" live only in the app settings. For --global, the instruction text is printed so you can paste it into Cursor Settings > Rules.

Usage

Target one or more agents:

all-in-ruby install --claude
all-in-ruby install --codex --opencode
all-in-ruby install --cursor

Codex, OpenCode, and Cursor all read AGENTS.md from the project root, so locally they share one file: installing for any of them covers all three, and uninstalling removes the block for all three.

Check where the instruction is installed. With no scope flag, status reports both the current repo and the global files:

all-in-ruby status
local:
  claude   /path/to/repo/CLAUDE.md: installed
  codex    /path/to/repo/AGENTS.md: not installed
  ...
global:
  claude   ~/.claude/CLAUDE.md: not installed
  codex    ~/.codex/AGENTS.md: installed
  ...

Pass --local or --global to check a single scope.

Remove it:

all-in-ruby uninstall

Backups

Before install or uninstall modifies a file that already exists, it writes a timestamped copy next to the original and lists the backups at the end of the run:

claude   /path/to/repo/CLAUDE.md: instructions added

Backups created:
  /path/to/repo/CLAUDE.md.20260802-153000.bak

Only existing files are backed up — creating a brand-new CLAUDE.md or AGENTS.md makes no backup, since there is nothing to preserve. Each run uses a fresh timestamp, so an earlier backup is never overwritten. Pass --no-backup to skip them, or --dry-run to see which backups would be made without writing anything.

Dry run

Preview what install or uninstall would change without writing anything:

all-in-ruby install --dry-run
all-in-ruby uninstall -n

For each file, dry run prints the status a real run would produce, followed by a unified diff showing the exact location of the change:

claude   /path/to/repo/CLAUDE.md: instructions would be added
codex    /path/to/repo/AGENTS.md: would be created
opencode /path/to/repo/AGENTS.md: would already be covered, no change
cursor   /path/to/repo/AGENTS.md: would already be covered, no change

--- /path/to/repo/CLAUDE.md
+++ /path/to/repo/CLAUDE.md
@@ -1,3 +1,19 @@
 # My project
 
 Always use tabs.
+
+<!-- BEGIN all_in_ruby -->
+## Scripts
+
+Write throwaway and utility scripts (data munging, one-off migrations,
...
+<!-- END all_in_ruby -->

--- /dev/null
+++ /path/to/repo/AGENTS.md
@@ -0,0 +1,15 @@
+<!-- BEGIN all_in_ruby -->
+## Scripts
...

A dry run simulates its own writes, so the statuses match what a real run would report - above, creating AGENTS.md for Codex also covers OpenCode and Cursor, so only one diff is shown for it. New files appear as --- /dev/null.

The diffs are standard unified format: pipe the output to delta or bat -l diff for coloring, or apply it with patch -p0.

Options

--local         Target the current repo (default for install/uninstall)
--global        Target global files instead of the current repo
--claude        Claude Code (CLAUDE.md)
--codex         Codex (AGENTS.md)
--opencode      OpenCode (AGENTS.md)
--cursor        Cursor (AGENTS.md; no global file)
-n, --dry-run   Preview changes as diffs without writing any file
--no-backup     Skip backing up existing files before modifying them
-v, --version   Print version

With no agent flags, all agents are targeted. Scope flags combine too: install --local --global installs in both places. Without a scope flag, install and uninstall stay local, while status reports both scopes.

How It Works

The instruction is appended inside marker comments:

<!-- BEGIN all_in_ruby -->
## Scripts

Write throwaway and utility scripts (data munging, one-off migrations,
file renames, glue code) in Ruby — even in projects written in another
language. If it needs a pipe, a loop, a conditional, or more than one
line, it is a script: write it in Ruby, not Python, Node, or bash.
Single self-contained commands (`grep`, `git status`) are fine as-is.

Use only the Ruby standard library. If a gem would clearly save
significant effort, stop and ask before using it.

Put temporary scripts in a scratch or temp directory, not the repo
root, and delete them when done unless asked to keep them.
<!-- END all_in_ruby -->

Existing file content is preserved verbatim. Running install twice is a no-op. uninstall removes only the marked block.

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/lucianghinda/all-in-ruby.git
cd all-in-ruby
bundle install
bundle exec rake test