██████╗░██╗░░░██╗██╗░░░░░██╗░░░██╗
██╔══██╗██║░░░██║██║░░░░░╚██╗░██╔╝
██████╔╝██║░░░██║██║░░░░░░╚████╔╝░
██╔══██╗██║░░░██║██║░░░░░░░╚██╔╝░░
██║░░██║╚██████╔╝███████╗░░░██║░░░
╚═╝░░╚═╝░╚═════╝░╚══════╝░░░╚═╝░░░
curl -fsSL https://raw.githubusercontent.com/patrickclery/ruly/main/setup.rb -o /tmp/ruly_setup.rb && ruby /tmp/ruly_setup.rbThis will:
- Install Ruly to
~/ruly - Add
rulycommand to your PATH - Set up initial configuration at
~/.config/ruly/recipes.yml
If you prefer to install manually:
# Clone the repository
git clone https://github.com/patrickclery/ruly.git ~/ruly
cd ~/ruly
# Install dependencies
bundle config set --local path 'vendor/bundle'
bundle install
# Add to PATH (add to your ~/.bashrc or ~/.zshrc)
export PATH="$HOME/ruly/bin:$PATH"
# Initialize configuration
ruly initTo remove Ruly:
rm -rf ~/ruly
# Remove the PATH export from your shell configuration fileAfter installation, you can immediately start using Ruly:
# Initialize configuration (if not done during install)
$ ruly init
# List available commands
$ ruly help
# Combine all rules into one file
$ ruly squash
# Use a specific recipe
$ ruly squash starter
# Clean up generated files
$ ruly clean
# List available recipes
$ ruly list-recipes
# Show version
$ ruly versionRuly is a standalone command-line tool that manages AI assistant rules:
- Simple Installation: One-line install with curl
- Self-Contained: Everything runs from
~/ruly - Recipe System: Use pre-configured recipes or create your own
- Smart Caching: Cache compiled recipes for performance
- Multiple Formats: Support for different AI assistants (Claude, Cursor, etc.)
Benefits:
- ✅ Standalone: No gem installation required
- ✅ Easy updates: Just pull the latest changes
- ✅ No system dependencies: Self-contained in your home directory
- ✅ Flexible rules system: Define your own rules repository or use remote sources
- ✅ Cross-platform: Works anywhere Ruby is installed
The ruly command provides:
- ✅ Combine multiple rule files into one document
- ✅ Use recipe collections for different contexts
- ✅ Fetch and include remote GitHub files
- ✅ Cache compiled recipes for performance
- ✅ Support for Claude, Cursor, and other AI assistants
- ✅ Clean up all agent-related files automatically
Generated Files:
your-project/
├── CLAUDE.local.md # Generated by ruly squash (default)
├── .ruly/
│ └── bin/ # Executable scripts (from scripts: key)
└── .claude/
├── commands/ # Command files for Claude agent
│ ├── bug/ # Bug-related commands
│ ├── pr/ # PR management commands
│ └── workflow/ # Workflow commands
└── skills/ # Skill files for Claude agent
├── debugging/
│ └── SKILL.md
└── pr-review-loop/
└── SKILL.md
For other agents:
- Cursor: Uses
.cursor/directory with.mdcfiles - Custom: Specify with
--agentand--output-fileoptions
Ruly is a powerful CLI tool that manages AI assistant rules and configurations for software development projects. It provides a framework for organizing and combining rule files from various sources - your own private repositories, public GitHub repos, or local files - into a single document for AI assistants like Claude or Cursor.
This repository does not include rule files. You need to:
- Create your own rules repository (private or public)
- Configure recipes to point to your rule sources
- Use the
ruly initcommand to get started with a template
-
Create a new repository for your rules:
# Create a private repository gh repo create yourusername/rules --private --description "My AI assistant rules" # Clone it locally git clone git@github.com:yourusername/rules.git cd rules
-
Organize your rules:
rules/ ├── ruby/ │ ├── common.md │ ├── rspec.md │ └── best-practices.md ├── testing/ │ └── patterns.md ├── commands/ │ ├── bug/ │ │ └── diagnose.md │ └── pr/ │ └── create.md ├── comms/ │ ├── jira/ │ │ ├── common.md # Shared Jira patterns │ │ └── bin/ # Shell scripts for Jira operations │ │ └── fetch-jira-details.sh │ └── ms-teams/ │ ├── common.md # Shared Teams patterns │ ├── commands/ │ │ └── dm.md # User-facing command │ └── agents/ │ └── ms-teams-dm.md # Subagent instructions ├── github/ │ ├── pr/ │ │ └── bin/ # Shell scripts for PR operations │ │ └── fetch-pr-details.sh │ └── bin/ # General GitHub scripts │ └── git_prettycommit.rb └── core/ └── debugging.mdDirectory conventions:
commands/- User-invocable slash commands (e.g.,/ms-teams:dm). Must be listed under thecommands:recipe key to be output as.claude/commands/files.skills/- Skill files that becomeSKILL.mdin.claude/skills/. Must be listed under theskills:recipe key.agents/- Subagent instruction files (dispatched by orchestrator, not user-invocable)bin/- Shell scripts and executables. Must be listed under thescripts:recipe key to be copied to.claude/scripts/.- Root files - Common patterns and shared configuration
Create ~/.config/ruly/recipes.yml to combine rules from different repositories:
recipes:
my-complete-rules:
description: "Combines personal and company rules"
sources:
# Your personal rules repository
- github: yourusername/rules
branch: main
rules:
- ruby
- testing
- commands
# Company rules (e.g., "FakeCorp")
- github: fakecorp/development-standards
branch: main
rules:
- guidelines/code-review.md
- guidelines/security.md
# Individual files from public repos
- https://github.com/thoughtbot/guides/blob/main/ruby/README.mdAfter installing Ruly, you can quickly get started with a basic configuration:
# Initialize Ruly with a starter configuration
ruly init
# This creates ~/.config/ruly/recipes.yml with example recipes
# Edit this file to add your own rule sourcesIf you don't want to maintain your own rules repository, you can use rules directly from GitHub:
recipes:
remote-only:
description: "Rules from various GitHub sources"
sources:
# Individual files
- https://github.com/rubocop/ruby-style-guide/blob/master/README.md
- https://github.com/testdouble/standard/blob/main/docs/README.md
# Entire directories (expands to all .md files)
- https://github.com/fakecorp/standards/tree/main/ruby
- https://github.com/fakecorp/standards/tree/main/testingHere's how the maintainer set up their private rules repository:
-
Created a private repository:
gh repo create patrickclery/rules --private --description "Private rules for Ruly gem" -
Created your rules content and pushed to GitHub
-
Updated your Ruly configuration:
# ~/.config/ruly/recipes.yml recipes: complete: description: "Personal + FakeCorp rules" sources: - github: patrickclery/rules branch: main rules: - ruby - testing - commands - github: fakecorp/cursor-rules branch: main rules: - workflow - jira
Ruly provides a powerful CLI for managing and compiling your AI assistant rules.
Combine all rules into one file:
ruly squashUse a specific recipe:
# Recipe name as positional parameter
ruly squash rails
ruly squash apiCustom output file:
# Squash mode with custom output
ruly squash --output-file=combined-rules.md
# or using short option
ruly squash -o docs/my-rules.md
# Combine with recipe
ruly squash rails -o RAILS.mdAnalyze token usage:
# Analyze a specific recipe
ruly analyze rails
ruly analyze api
# Analyze all recipes
ruly analyze --all
ruly analyze -aClean up generated files:
# Clean all agent-related files for current agent
ruly clean
# Clean files from specific recipe
ruly clean rails
# Clean files for specific agent
ruly clean --agent cursor
# Dry run to see what would be deleted
ruly clean --dry-run
ruly clean -d
# Clean before squashing (remove old files first)
ruly squash --clean
ruly squash rails --clean
ruly squash -c # Short form
# Deep clean before squashing (remove ALL Claude artifacts)
ruly squash --deepclean
ruly squash rails --deepcleanGenerate MCP server configuration:
# Create .mcp.json with specific servers (must exist in ~/.config/ruly/mcp.json)
ruly mcp atlassian teams playwright
# Use MCP servers from a recipe
ruly mcp -r workaxle-spike
ruly mcp --recipe workaxle-bug
# Append to existing .mcp.json instead of overwriting
ruly mcp playwright -a
ruly mcp --append teams
# Combine recipe servers with additional servers
ruly mcp -r workaxle-bug playwright
# Append recipe servers to existing config
ruly mcp -r workaxle-spike -aSubagents allow you to generate specialized agent files that Claude can dispatch to for specific tasks. Each subagent is a self-contained agent with its own rules, commands, and MCP server access.
Add a subagents array to any recipe. Each subagent references another recipe:
recipes:
# Main recipe that spawns subagents
full:
description: "Complete development environment"
files:
- /path/to/rules/core.md
subagents:
- name: bug_investigator
recipe: bug
- name: test_runner
recipe: testing
- name: pr_manager
recipe: pr
# Recipes used by subagents
bug:
description: "Bug investigation and debugging"
files:
- /path/to/rules/bug/
- /path/to/rules/debugging.md
mcp_servers:
- teams
testing:
description: "Testing and QA workflows"
files:
- /path/to/rules/testing/
mcp_servers:
- playwright
pr:
description: "PR management"
files:
- /path/to/rules/github/pr/When you run ruly squash -r full:
- MCP servers collected: Recursively collects
mcp_serversfrom all subagent recipes .mcp.jsonwritten: Parent's.mcp.jsonincludes all collected servers (deduplicated)- Main rules generated:
CLAUDE.local.mdwith the main recipe content - Agent files created:
.claude/agents/{name}.mdfor each subagent - Commands organized:
.claude/commands/{agent_name}/for agent-specific commands
your-project/
├── CLAUDE.local.md # Main rules (from 'full' recipe)
├── .mcp.json # MCP servers (parent + all subagent servers)
├── .ruly/
│ └── bin/ # Bin files (from scripts: key)
└── .claude/
├── agents/
│ ├── bug_investigator.md # Squashed 'bug' recipe
│ ├── test_runner.md # Squashed 'testing' recipe
│ └── pr_manager.md # Squashed 'pr' recipe
├── commands/
│ ├── bug_investigator/ # Commands for bug agent
│ ├── test_runner/ # Commands for testing agent
│ └── pr_manager/ # Commands for PR agent
└── skills/ # Skills (from skills: key)
└── debugging/
└── SKILL.md
Claude Code subagents inherit the parent session's MCP configuration — they cannot have independent MCP servers. Ruly handles this automatically: during ruly squash, MCP servers from all subagent recipes (recursively, including nested subagents) are collected and merged into the parent's .mcp.json.
For example, given this recipe configuration:
recipes:
core:
description: "Main orchestrator"
files:
- /path/to/rules/core.md
# Note: no mcp_servers defined here
subagents:
- name: comms
recipe: comms
- name: feature
recipe: feature
comms:
description: "Communication agent"
files:
- /path/to/rules/comms/
mcp_servers:
- teams
feature:
description: "Feature development"
files:
- /path/to/rules/feature/
mcp_servers:
- RefRunning ruly squash core produces a .mcp.json containing teams and Ref — all propagated from the subagent recipes — even though core itself defines no MCP servers. The console output shows which servers were propagated:
🔌 Propagated MCP servers from subagents: teams, Ref
🔌 Updated .mcp.json with MCP servers
This propagation is recursive: if comms itself has subagents with additional MCP servers, those are collected too. Circular references are handled safely.
Generated agent files have YAML frontmatter that Claude understands:
---
name: bug_investigator
description: Bug investigation and debugging
tools: inherit
model: haiku # Set via subagent or recipe config (default: inherit)
# Auto-generated from recipe: bug
# Do not edit manually - regenerate using 'ruly squash full'
---
# Bug Investigator
Bug investigation and debugging
## Recipe Content
[squashed content from bug recipe]
## MCP Servers
This subagent has access to the following MCP servers:
- teams
---
*Last generated: 2026-02-04 12:30:00*
*Source recipe: bug*Control which Claude model each subagent uses. Route lightweight tasks (context fetching, DMs) to faster/cheaper models while keeping complex tasks on the most capable model.
Specify model directly on a subagent entry:
subagents:
- name: context_grabber
recipe: context-grabber
model: haiku # Fast, cheap — just fetching data
- name: core_engineer
recipe: core-engineer
model: opus # Most capable — complex implementation
- name: comms
recipe: comms # No model — inherits from recipe or defaults to 'inherit'Set a default model for all subagents in a recipe:
recipes:
core:
description: "Main orchestrator"
model: sonnet # Default for all subagents
files:
- /path/to/rules/core.md
subagents:
- name: fast_agent
recipe: fast-tasks
model: haiku # Overrides recipe default
- name: smart_agent
recipe: complex-tasks
# Uses recipe default (sonnet)Model is resolved in this order:
- Subagent
model— if specified on the subagent entry - Parent recipe
model— if set on the recipe containing the subagents inherit— the default (inherits from the calling session)
Valid values: haiku, sonnet, opus, or inherit.
Note: Skills can also specify
modelin their frontmatter — this is already supported and preserved during squash.
Subagent instruction files should be organized in agents/ directories:
rules/
└── comms/
├── ms-teams/
│ ├── common.md # Shared patterns (loaded by both)
│ ├── commands/
│ │ └── dm.md # User command: /ms-teams:dm
│ └── agents/
│ └── ms-teams-dm.md # Subagent: dispatched on "send it"
Key distinction:
commands/- User-invocable via/command-nameagents/- Dispatched programmatically by the orchestrator
| Use Case | Benefit |
|---|---|
| Specialized tasks | Each agent has focused rules for its domain |
| Parallel work | Dispatch multiple agents for independent tasks |
| Context isolation | Agents only load rules they need |
| MCP server propagation | Subagent MCP servers are automatically propagated to parent |
recipes:
workaxle:
description: "Main WorkAxle development"
files:
- /path/to/rules/core.md
subagents:
- name: comms
recipe: comms # Jira, Teams, GitHub communications
- name: merger
recipe: merger # PR merging operations
- name: dashboard
recipe: dashboard # PR status dashboard
comms:
description: "Communication via Jira, Teams, GitHub"
files:
- /path/to/rules/comms/
mcp_servers:
- teams
- atlassian
merger:
description: "PR merging commands"
files:
- /path/to/rules/github/pr/
mcp_servers: []
dashboard:
description: "Open PRs dashboard"
files:
- /path/to/rules/dashboard.md
mcp_servers: []Then Claude can dispatch to these agents:
User: "Update all my PRs with latest main"
Claude: [Dispatches to merger agent which has PR merge rules]
User: "Send a Teams message about WA-1234"
Claude: [Dispatches to comms agent which has Teams MCP access]
User: "Show me my open PRs"
Claude: [Dispatches to dashboard agent]
Recipes allow you to define collections of rules to combine, rather than always including all files.
List available recipes:
ruly list-recipesUse a specific recipe:
# Use the 'core' recipe
ruly squash --recipe core
# Use 'testing' recipe with custom output
ruly squash --recipe testing -o testing-rules.md
# Short form
ruly squash -r minimalRecipes depend on having access to rule files. If you cloned with the default rules submodule, you'll have access to the recipes defined in recipes.yml. Otherwise, create your own recipes in ~/.config/ruly/recipes.yml pointing to your rule sources.
- qa — WorkAxle QA acceptance testing. Write and run Playwright specs in the automation-test-qa repo against dev.workaxle.com. Includes skills for running acceptance tests and syncing the QA repo.
Create a ~/.config/ruly/recipes.yml file to define your own recipes or override existing ones:
# ~/.config/ruly/recipes.yml
---
tier: claude_max
recipes:
# Complete development environment combining multiple sources
my_company_core:
description: Complete development environment with Ruby, testing, and workflow rules
tier: claude_max
sources:
# John's private rules repository
- github: john/private-rules
branch: main
rules:
- rules/commands/bug
- rules/commands/pr
- rules/bug
- rules/commands.md
- rules/core
- rules/core/debugging
- rules/pr
- rules/ruby
- rules/testing
- rules/commands/testing
- rules/commands/workflow
# Company's shared rules repository
- github: my_company/development-standards
branch: main
rules:
- rules/commands/jira/details.md
- rules/workflow
- rules/jira
# Local files from various projects
development_local:
description: Auto-generated from local sources
files:
- /Users/john/Projects/my_app/rules/ruby/common.md
- /Users/john/Projects/my_app/rules/ruby/monads.md
- /Users/john/Projects/my_app/rules/ruby/rspec.md
- /Users/john/Projects/my_app/rules/ruby/sequel.md
- /Users/john/Projects/my_app/rules/testing/common.md
- /Users/john/Projects/my_app/rules/commands.md
- /Users/john/Projects/my_app/rules/commands/bug/diagnose.md
- /Users/john/Projects/my_app/rules/commands/bug/fix.md
- /Users/john/Projects/my_app/rules/commands/pr/create.md
tier: claude_max
# Simple recipe for specific context
testing_only:
description: Testing and QA rules
tier: claude_max
files:
- /Users/john/Projects/my_app/rules/testing/*.md
- /Users/john/Projects/my_app/rules/commands/testing/*.mdRecipes support explicit keys for files that need special treatment. Files listed under files: are always squashed into the main output (CLAUDE.local.md) regardless of their path. To output files as skills, commands, or bins, use the dedicated keys:
recipes:
my-recipe:
description: "Example with explicit keys"
files:
# Regular rule files — squashed into CLAUDE.local.md
- /path/to/rules/core.md
- /path/to/rules/frameworks/ruby.md
skills:
# Output as .claude/skills/{name}/SKILL.md
- /path/to/rules/skills/debugging.md
- /path/to/rules/github/pr/skills/pr-review-loop.md
commands:
# Output as .claude/commands/{path}.md
- /path/to/rules/github/pr/commands/create.md
- /path/to/rules/comms/jira/commands/comment.md
scripts:
# Copied to .claude/scripts/ as executables
- /path/to/rules/bin/deploy.shKey behavior:
| Recipe key | Output location | What it does |
|---|---|---|
files: |
CLAUDE.local.md |
Squashed into main output (always, regardless of path) |
skills: |
.claude/skills/{name}/SKILL.md |
Creates individual skill files |
commands: |
.claude/commands/{path}.md |
Creates slash command files |
scripts: |
.claude/scripts/ |
Copies scripts as executables |
All four keys support both individual file paths and directory paths. Directories are expanded:
skills:andcommands:directories expand to all*.mdfilesscripts:directories expand to all*.shfiles
Frontmatter skills: references in individual rule files still work independently. If a rule file declares skills: in its frontmatter, those referenced files are automatically resolved and output as SKILL.md files during squash, regardless of which recipe key they appear under.
Remote Sources:
- Supports pulling rules directly from GitHub repositories
- Automatically converts GitHub blob URLs to raw URLs
- Non-Claude agents include all files in the main output
GitHub URL Formats:
- Individual files: Use
/blob/URLs for specific files- Example:
https://github.com/owner/repo/blob/branch/path/to/file.md
- Example:
- Directories: Use
/tree/URLs to include all.mdfiles in a directory- Example:
https://github.com/owner/repo/tree/branch/path/to/directory - Automatically expands to include all markdown files in that directory
- Example:
- Important: Files with extensions (like
.md) in/tree/URLs are treated as individual files, not directories
Command File Handling:
- When
--agent claude(default), files listed under thecommands:recipe key are saved to.claude/commands/ - For other agents, command files are included in the main output file
- Files in
/commands/paths underfiles:are treated as regular content (squashed into main output)
Caching:
- Use
--cacheflag to enable caching for any recipe - Cached files are stored in
cache/<agent>/directory - Remote files are cached separately in
cache/remote/(7-day expiration) - Cache is disabled by default
- Use
ruly cleanto remove cache files
User recipes:
- Are automatically loaded from
~/.config/ruly/recipes.yml - Override base recipes with the same name
- Are stored in your home directory configuration
- Allow user-specific or team-specific customizations
Recipes can extend other recipes using the extends: key. The child recipe inherits all keys from the parent, with:
- Array keys (
files,skills,commands,scripts,sources,mcp_servers,omit_command_prefix): Merged via union — parent entries first, then child entries, deduplicated - Scalar keys (
description,model,tier): Child wins — parent value only used if child doesn't define it - Subagents: Merged by
name— child entry overrides parent entry with same name
recipes:
base:
description: "Base development recipe"
files:
- rules/core.md
- rules/common.md
mcp_servers:
- teams
extended:
extends: base
description: "Extended recipe with extra tools"
files:
- rules/extra.md
mcp_servers:
- atlassianAfter resolution, extended will have:
files:[rules/core.md, rules/common.md, rules/extra.md]mcp_servers:[teams, atlassian]description:"Extended recipe with extra tools"
Multi-level inheritance is supported (A extends B extends C). Circular references are detected and produce an error.
When running Claude Code in a subdirectory, it walks up the directory tree loading every CLAUDE.md and CLAUDE.local.md it finds. This can cause context bloat when worktrees or submodules are nested inside directories that have their own Claude instructions.
The isolate: true recipe option prevents this inheritance by populating claudeMdExcludes in .claude/settings.local.json with every parent CLAUDE.md and CLAUDE.local.md file found between the output directory and the filesystem root.
recipes:
my-isolated-recipe:
description: "Engineer with no parent context inheritance"
isolate: true
files:
- /path/to/rules/core.md
- /path/to/rules/frameworks/After ruly squash my-isolated-recipe, the generated .claude/settings.local.json will contain:
{
"claudeMdExcludes": [
"/Users/you/agents/orchestrator/CLAUDE.local.md",
"/Users/you/agents/orchestrator/workaxle-core/CLAUDE.md",
"/Users/you/agents/orchestrator/workaxle-core/CLAUDE.local.md"
]
}When to use:
- Worktrees nested inside parent projects with large CLAUDE files
- Submodules that should only use their own squashed rules
- Any recipe where you want a clean, self-contained context
-
Squash (
squash [RECIPE]): Combines all rule content into a single large file. Recipe is optional positional parameter. Supports fetching remote GitHub files and caching for performance. Use--tocor-tto generate a table of contents with unique anchors for all headers, ensuring proper navigation even when multiple files have identical header names. Also includes a list of available slash commands. Use--deepcleanto remove all Claude artifacts before squashing (overrides--clean). Use--verboseor-vto show detailed per-file processing output (file paths, token counts, requires discovery). Default output shows only recipe, subagents, errors, and summary. -
Analyze (
analyze [RECIPE]): Analyzes token usage for recipes without generating files. Shows detailed file breakdown and total token count. Use--allto analyze all recipes at once. -
Clean (
clean [RECIPE]): Deletes output files created by the squash command. Recipe is optional. Removes main output file and command files directory. Use--deepcleanto remove all Claude artifacts (.claude/ directory, CLAUDE.local.md, CLAUDE.md) regardless of recipe. -
Introspect (
introspect [FILE_PATH]): Analyzes a markdown file to extract its frontmatter metadata and identify anyrequires:dependencies. Shows the YAML frontmatter, lists required files, and displays their resolved paths. Useful for understanding file dependencies and debugging the requires system. If no file path is provided, it will look for a file in the current directory. -
List Recipes (
list-recipes): Shows all available recipes with file counts and cache indicators. -
Version (
version): Shows the current Ruly version.
Slash commands are special commands that can be defined in your rule files to provide quick actions for AI assistants. When you include command files in your rules (typically in a commands/ directory), they become available as slash commands in the generated output.
For example, if you have a file commands/bug/diagnose.md in your rules, it would become available as /bug:diagnose when using the generated rules with Claude or other AI assistants.
The --toc option will automatically generate:
- A table of contents with links to all headers in the combined document
- Unique anchors for headers (prefixed with the source file path) to handle duplicate header names across files
- A list of all available slash commands in your squashed output
This ensures proper navigation even when multiple rule files contain headers with identical names (e.g., multiple files with "# Introduction" sections).
/ruly:compress- Analyze markdown rules to find redundancies and make them more DRY/ruly:decompose- Decompose a markdown file into a directory using git mv (preserves history)/run-acceptance-test- Takes acceptance criteria (direct text, Jira ticketWA-XXXX, or PR numberPR:NNNN), reads page objects from automation-test-qa, writes a Playwright spec, runs it, and reports results./sync-qa-repo- Pulls latest from automation-test-qa, reports new/changed page objects, specs, and API helpers.
# Generate CLAUDE.local.md with all rules
ruly squash
# Dry run - see what would be created without creating it
ruly squash --dry-run
ruly squash -d
# Generate core rules only
ruly squash --recipe core
ruly squash -r core
# Generate squashed testing rules to a custom file
ruly squash -r testing -o test/testing-rules.md
# Generate rules for a different agent (e.g., cursor)
ruly squash -r rails --agent cursor -o CURSOR.md
ruly squash -r rails -a cursor -o CURSOR.md
# Generate with remote sources (command files go to .claude/commands/)
ruly squash -r example_mixed
# Use cached version (if recipe has cache: true)
ruly squash rails
# Bypass cache for one run
ruly squash rails --no-cache
# Clean up generated files
ruly clean
# Dry run - see what would be deleted
ruly clean --dry-run
ruly clean -d
# Deep clean - remove all Claude artifacts
ruly clean --deepclean
# Clean specific output file
ruly clean -o test/testing-rules.md
# Introspect a markdown file to see its frontmatter and requires
ruly introspect rules/ruby/ruby-practices.md
# Introspect a file in the current directory
ruly introspect README.md
# List what recipes are available
ruly list-recipes
# Show version
ruly version
# View help
ruly help
ruly help squash
ruly help clean
ruly help introspectRuly will automatically:
- Load recipes from both
recipes.ymland~/.config/ruly/recipes.yml - Support glob patterns in recipe definitions
- Create parent directories if using custom output paths
- Display file count and output size
- Show which recipe was used in the output
An orchestrator that manages multiple repositories, each with their own CLAUDE.md and hooks. Subagents dispatched into each repo automatically pick up the repo's configuration.
~/agents/orchestrator/
├── CLAUDE.local.md # Generated orchestrator rules
├── .mcp.json # MCP servers (collected from all subagents)
├── .claude/
│ ├── agents/
│ │ ├── backend_engineer.md # Has acme-api's CLAUDE.md + hooks baked in
│ │ ├── frontend_engineer.md # Has acme-web's CLAUDE.md + rules + hooks baked in
│ │ └── comms.md # Pure ruly recipe (no repo append)
│ ├── scripts/
│ │ └── worktree-create.sh # Propagated to all submodule dirs
│ └── settings.local.json # Parent hooks (WorktreeCreate)
├── acme-api/ # Backend repo (git submodule)
│ ├── CLAUDE.md # 1800-line repo-specific guidance
│ └── .claude/
│ └── settings.json # No custom hooks
├── acme-web/ # Frontend repo (git submodule)
│ ├── CLAUDE.md # 500-line repo-specific guidance
│ └── .claude/
│ ├── rules/
│ │ └── command-timeouts.md # Repo-specific rules
│ ├── hooks/
│ │ └── eslint-fix.sh # Repo-specific hook script
│ └── settings.json # PostToolUse hook for ESLint
recipes:
orchestrator:
description: "Multi-repo dispatcher"
hooks:
WorktreeCreate:
- hooks:
- type: command
command: ".claude/scripts/worktree-create.sh"
timeout: 120
files:
- /path/to/rules/orchestrator/dispatch.md
scripts:
- /path/to/rules/orchestrator/bin/worktree-create.sh
subagents:
# Backend — reads acme-api's CLAUDE.md and hooks
- name: backend_engineer
recipe: backend-engineer
cwd: acme-api
append: true
# Frontend — reads acme-web's CLAUDE.md, rules, and hooks
- name: frontend_engineer
recipe: frontend-engineer
cwd: acme-web
append: true
# Comms — pure ruly recipe, no repo to append
- name: comms
recipe: commsWhen a subagent has both cwd: and append: true, ruly reads from the repo directory during squash:
| Source | What's read | Where it goes |
|---|---|---|
{cwd}/CLAUDE.md |
Repo's main guidance doc | Appended to agent body as ## Repository Context |
{cwd}/.claude/rules/*.md |
Repo-specific rules | Appended to agent body as ## Repository Rules |
{cwd}/.claude/settings.json |
Repo's hooks | Merged into agent frontmatter hooks: |
Each subagent gets only its own repo's hooks — no cross-contamination between subagents.
The frontend_engineer subagent gets the parent's WorktreeCreate hook merged with the repo's PostToolUse hook:
---
name: frontend_engineer
description: Frontend feature development - React/TypeScript with TDD
tools: Bash, Read, Write, Edit, Glob, Grep
model: inherit
mcpServers: "[playwright, Ref]"
permissionMode: bypassPermissions
hooks:
WorktreeCreate:
- hooks:
- type: command
command: ".claude/scripts/worktree-create.sh"
timeout: 120
PostToolUse:
- matcher: Edit|Write
hooks:
- type: command
command: ".claude/hooks/eslint-fix.sh"
# Auto-generated from recipe: frontend-engineer
# Do not edit manually - regenerate using 'ruly squash orchestrator'
---The backend_engineer subagent only gets the parent's hook (since acme-api has no custom hooks):
---
name: backend_engineer
description: Backend feature development - Ruby/Sequel with TDD
tools: Bash, Read, Write, Edit, Glob, Grep
model: inherit
hooks:
WorktreeCreate:
- hooks:
- type: command
command: ".claude/scripts/worktree-create.sh"
timeout: 120
# Auto-generated from recipe: backend-engineer
# Do not edit manually - regenerate using 'ruly squash orchestrator'
---After the recipe's squashed content, each subagent with append: true gets additional sections:
## Recipe Content
[squashed content from frontend-engineer recipe]
---
## Repository Context
# CLAUDE.md
This file provides guidance for the acme-web frontend application...
## Development
- Use `yarn dev` for development server
- Use `yarn typecheck` for type checking
- Use `yarn lint --fix` for linting
---
## Repository Rules
## Command Timeouts
### Rule
Always use a **5-minute timeout** (300000ms) for:
- `yarn typecheck`
- `yarn lint`
---
*Last generated: 2026-03-06 10:43:25*
*Source recipe: frontend-engineer*| Feature | append: true |
No append |
|---|---|---|
| Recipe content | Included | Included |
| Repo CLAUDE.md | Baked into agent body | Not visible to subagent |
| Repo .claude/rules/ | Baked into agent body | Not visible to subagent |
| Repo hooks (settings.json) | Merged into frontmatter | Not applied |
| Parent hooks | Always included | Always included |
| MCP servers | From recipe (propagated to parent) | From recipe (propagated to parent) |
Note: Claude Code subagents do not automatically discover
CLAUDE.md,.claude/rules/, or.claude/settings.jsonfrom their CWD. Theappendfeature exists specifically to bridge this gap by baking repo configuration into the agent file at squash time.
Permission denied:
- Ensure you have write access to your project directory
- Check that Ruby gems can be installed globally
Recipe not found:
- Run
ruly list-recipesto see available recipes - Check
~/.config/ruly/recipes.ymlfor user-defined recipes - Ensure recipe names match exactly (case-sensitive)
Files not being cleaned:
- Use
ruly clean --dry-runto preview what will be deleted - Specify agent with
--agentoption if not using Claude - Ensure you're using the correct recipe name if specified