Skip to content

patrickclery/ruly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

450 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

██████╗░██╗░░░██╗██╗░░░░░██╗░░░██╗
██╔══██╗██║░░░██║██║░░░░░╚██╗░██╔╝
██████╔╝██║░░░██║██║░░░░░░╚████╔╝░
██╔══██╗██║░░░██║██║░░░░░░░╚██╔╝░░
██║░░██║╚██████╔╝███████╗░░░██║░░░
╚═╝░░╚═╝░╚═════╝░╚══════╝░░░╚═╝░░░

🚀 Quick Install

One-Line Installation

curl -fsSL https://raw.githubusercontent.com/patrickclery/ruly/main/setup.rb -o /tmp/ruly_setup.rb && ruby /tmp/ruly_setup.rb

This will:

  • Install Ruly to ~/ruly
  • Add ruly command to your PATH
  • Set up initial configuration at ~/.config/ruly/recipes.yml

Manual Installation

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 init

Uninstall

To remove Ruly:

rm -rf ~/ruly
# Remove the PATH export from your shell configuration file

Getting Started

After 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 version

🌟 How It Works

Standalone CLI Tool

Ruly is a standalone command-line tool that manages AI assistant rules:

  1. Simple Installation: One-line install with curl
  2. Self-Contained: Everything runs from ~/ruly
  3. Recipe System: Use pre-configured recipes or create your own
  4. Smart Caching: Cache compiled recipes for performance
  5. 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

What Ruly Does

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 .mdc files
  • Custom: Specify with --agent and --output-file options

About Ruly

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.

⚠️ Important: Rules Not Included

This repository does not include rule files. You need to:

  1. Create your own rules repository (private or public)
  2. Configure recipes to point to your rule sources
  3. Use the ruly init command to get started with a template

🎯 Setting Up Your Rules

Option 1: Create Your Own Rules Repository

  1. 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
  2. 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.md
    

    Directory conventions:

    • commands/ - User-invocable slash commands (e.g., /ms-teams:dm). Must be listed under the commands: recipe key to be output as .claude/commands/ files.
    • skills/ - Skill files that become SKILL.md in .claude/skills/. Must be listed under the skills: recipe key.
    • agents/ - Subagent instruction files (dispatched by orchestrator, not user-invocable)
    • bin/ - Shell scripts and executables. Must be listed under the scripts: recipe key to be copied to .claude/scripts/.
    • Root files - Common patterns and shared configuration

Option 2: Use Multiple Rule Sources

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.md

Option 3: Quick Start with Init

After 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 sources

Option 4: Use Remote Sources Only

If 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/testing

Example: Setting Up Like patrickclery/rules

Here's how the maintainer set up their private rules repository:

  1. Created a private repository:

    gh repo create patrickclery/rules --private --description "Private rules for Ruly gem"
  2. Created your rules content and pushed to GitHub

  3. 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

📝 Using Ruly Commands

Ruly provides a powerful CLI for managing and compiling your AI assistant rules.

Basic Commands

Combine all rules into one file:

ruly squash

Use a specific recipe:

# Recipe name as positional parameter
ruly squash rails
ruly squash api

Custom 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.md

Analyze token usage:

# Analyze a specific recipe
ruly analyze rails
ruly analyze api

# Analyze all recipes
ruly analyze --all
ruly analyze -a

Clean 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 --deepclean

Generate 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 -a

Subagents

Subagents 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.

Defining Subagents in Recipes

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/

How It Works

When you run ruly squash -r full:

  1. MCP servers collected: Recursively collects mcp_servers from all subagent recipes
  2. .mcp.json written: Parent's .mcp.json includes all collected servers (deduplicated)
  3. Main rules generated: CLAUDE.local.md with the main recipe content
  4. Agent files created: .claude/agents/{name}.md for each subagent
  5. 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

MCP Server Propagation

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:
      - Ref

Running 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.

Agent File Format

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*

Model Specification

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.

Subagent-Level 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'
Recipe-Level Default Model

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)
Inheritance Chain

Model is resolved in this order:

  1. Subagent model — if specified on the subagent entry
  2. Parent recipe model — if set on the recipe containing the subagents
  3. inherit — the default (inherits from the calling session)

Valid values: haiku, sonnet, opus, or inherit.

Note: Skills can also specify model in their frontmatter — this is already supported and preserved during squash.

Directory Structure for Subagents

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-name
  • agents/ - Dispatched programmatically by the orchestrator

When to Use Subagents

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

Example: Development Workflow

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]

Recipe System

Recipes allow you to define collections of rules to combine, rather than always including all files.

List available recipes:

ruly list-recipes

Use 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 minimal

Available Recipes

Recipes 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.

Custom Recipes

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/*.md

Recipe Keys: Skills, Commands, and Bins

Recipes 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.sh

Key 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: and commands: directories expand to all *.md files
  • scripts: directories expand to all *.sh files

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
  • Directories: Use /tree/ URLs to include all .md files in a directory
    • Example: https://github.com/owner/repo/tree/branch/path/to/directory
    • Automatically expands to include all markdown files in that directory
  • 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 the commands: recipe key are saved to .claude/commands/
  • For other agents, command files are included in the main output file
  • Files in /commands/ paths under files: are treated as regular content (squashed into main output)

Caching:

  • Use --cache flag 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 clean to 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

Recipe Inheritance (extends:)

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:
      - atlassian

After 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.

Context Isolation (isolate)

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

Commands

  • 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 --toc or -t to 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 --deepclean to remove all Claude artifacts before squashing (overrides --clean). Use --verbose or -v to 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 --all to 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 --deepclean to 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 any requires: 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

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:

  1. A table of contents with links to all headers in the combined document
  2. Unique anchors for headers (prefixed with the source file path) to handle duplicate header names across files
  3. 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).

Available Ruly Commands

  • /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 ticket WA-XXXX, or PR number PR: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.

Examples

# 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 introspect

Ruly will automatically:

  • Load recipes from both recipes.yml and ~/.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

Example Recipes

Multi-Repo Orchestrator

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.

Directory Layout

~/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

Recipe Configuration

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: comms

What append: true Does

When 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.

Generated Agent Frontmatter

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'
---

Generated Agent Body (append sections)

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*

With vs Without append

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.json from their CWD. The append feature exists specifically to bridge this gap by baking repo configuration into the agent file at squash time.


🔧 Troubleshooting

Common Issues

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-recipes to see available recipes
  • Check ~/.config/ruly/recipes.yml for user-defined recipes
  • Ensure recipe names match exactly (case-sensitive)

Files not being cleaned:

  • Use ruly clean --dry-run to preview what will be deleted
  • Specify agent with --agent option if not using Claude
  • Ensure you're using the correct recipe name if specified

About

CLI tool for managing AI assistant rules and configurations

Resources

License

Stars

5 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages