Open Source

Rush

A Modern Day Warrior

Built for Humans and AI Alike Clean, Intentional Syntax One Shell, Every Platform
macOS Linux Windows x64 + ARM64
# macOS
brew install mhasse1/tap/rush
rush
# Pipe anything to AI
$ cat error.log | ai "what went wrong?"
3 categories of errors found:
Connection timeouts (47), Auth failures (12), OOM (3)
# Structured pipelines — objects, not text
$ ps aux | where CPU > 50 | select Name, CPU | sort --desc
Name CPU
node 87.3
postgres 62.1
# Clean scripting — no sigils, no ceremony
$ files = Dir.list(".", :files)
$ large = files.select { |f| File.size(f) > 1.mb }
$ large.each { |f| puts "#{f}: #{File.size(f).to_filesize}" }
# LLM agent mode — structured JSON I/O
$ rush --llm
{"ready":true,"host":"web-prod","user":"deploy","cwd":"/var/www"}
# SQL built in
$ sql @prod "SELECT * FROM orders WHERE status='failed'" | ai "summarize"
12 failed orders in the last 24h, all from payment gateway timeouts.

The Shell LLMs Were Waiting For

Rush was designed from the ground up for AI agents. The entire language spec fits in a single LLM context window. No other shell was built with this constraint.

🔌

LLM Wire Protocol

rush --llm — purpose-built JSON protocol for AI agents. Structured input/output, typed errors, output spooling, TTY blocklist. Agents get data, not raw terminal text.

# Start LLM mode
$ rush --llm

# Rush sends context with every response — the LLM always knows where it is:
{"ready":true,"host":"web-prod","user":"deploy",
 "cwd":"/var/www","git_branch":"main"}

# Agent runs a command:
ps aux | where CPU > 50 | as json

# Rush returns structured data (not terminal text):
{"status":"success","exit_code":0,
 "stdout":"[{\"Name\":\"node\",...}]",
 "duration_ms":45}

# When something fails, the agent gets a typed error:
cat /nonexistent
{"status":"error","exit_code":1,
 "stderr":"No such file or directory",
 "duration_ms":3}
🤖

MCP Servers

One command installs both local and SSH gateway MCP servers for Claude Code and Claude Desktop.

# Install both servers
rush install mcp --claude

# Local: persistent session
# → rush_execute, rush_read_file, rush_context

# SSH Gateway: multi-host management
# → persistent connections, parallel execution, 10x faster
💬

Pipe Anything to AI

Native AI assistant with Anthropic, OpenAI, Gemini, and Ollama support. Pipe logs, diffs, query results, command output — get answers in context.

cat /var/log/syslog | ai "prioritize critical errors in the last hour"
git diff | ai "review this change for security issues"
sql @prod "SELECT * FROM orders WHERE status='failed'" \
  | ai "summarize these failures"

# Multi-turn autonomous agent
cat ~/servers.txt | ai --agent "find servers with disk > 80% and report"
📦

One-Shot Language Learning

rush-lang-spec.yaml is ~300 lines, ~3.5K tokens. An LLM reads it once and generates correct Rush code. Compare to Python's 400+ page reference and the LLM having to search questionable Reddit and Stack Overflow posts.

# The spec includes common LLM mistakes:
common_mistakes:
  - wrong: 'foreach ($x in $list) { }'
    right: 'for x in list ... end'

  - wrong: '[System.IO.File]::ReadAllText("path")'
    right: 'File.read("path")'
📚

Built-in Help for Agents (and Humans)

22 embedded reference topics the LLM can query on demand. Reduces context burn — the agent asks for help only when it needs it.

# Agent queries help mid-session:
help pipelines
help platform-blocks
help sql

# Training hints after bash-style commands:
$ name="world"
hint: in Rush, use: name = "world" (spaces allowed)
🛡️

Agent Safety Built In

Output capped at 4KB with spool buffer for paging. TTY blocklist prevents vim, top, less from hanging agents. Structured errors with exit codes in every response.

# Agent tries to open vim:
→ vim config.json
← {"status":"blocked",
   "reason":"interactive TUI program",
   "suggestion":"use File.read/File.write instead"}

# Output exceeds 4KB:
← {"status":"success","stdout":"[first 4KB]",
   "spooled":true,"spool_lines":847}
→ spool 1-50    # page through
brew install mhasse1/tap/rush or download from GitHub

One Shell, Every Platform, Every Windows Layer

No other shell wraps all Windows execution environments in one syntax. Rush is the first shell where a sysadmin can write one script that targets PS 7, PS 5.1, and 32-bit PS 5.1 — alongside macOS and Linux.

🪟

Every Windows Layer in One Script

ps, ps5, and win32 blocks target different PowerShell engines. Raw passthrough — $_, script blocks, and cmdlets survive untouched.

# PowerShell 7 — raw passthrough
ps
  Get-Service | Where-Object { $_.Status -eq "Running" }
  $fw = Get-NetFirewallProfile
  $fw | Format-Table Name, Enabled
end

# PowerShell 5.1 — legacy modules
ps5
  Import-Module ActiveDirectory
  Get-ADUser -Filter * | Select-Object Name, Enabled
end

# 32-bit PS 5.1 — OLEDB/ODBC drivers
win32
  $conn = New-Object System.Data.OleDb.OleDbConnection(
    "Provider=Microsoft.ACE.OLEDB.12.0;...")
  $conn.Open()
end
BlockEngineUse case
psPowerShell 7Cmdlets, $_, script blocks, Where-Object
ps5PowerShell 5.1Legacy: AD, Exchange, older management
win3232-bit PS 5.1OLEDB/ODBC: Access, Excel, Business Central
win64Rush syntaxWindows-specific Rush code
🌍

Platform Blocks

Target any OS with clean blocks. Property conditions for architecture and version gating. No if [[ "$(uname)" == ... ]] gymnastics.

macos
  brew update && brew upgrade
end

macos.arch == "arm64"
  puts "Apple Silicon"
end

linux.version >= "6.8.0"
  puts "Modern kernel"
end

linux  { sudo apt update && sudo apt upgrade -y }
win64  { winget upgrade --all }
📁

Network & SSH Paths

Windows SMB shares with forward slashes — Rush translates to native UNC. SSH remote files work on all platforms. No backslashes ever.

# SMB shares — forward slashes always
cd //fileserver/shared/docs
ls //nas/backups/2026/
cp //server/share/report.xlsx ./

# SSH remote files — all platforms
cat //ssh:server/etc/hosts
cp //ssh:server/data/backup.sql .
📝

One Script, Every Platform

The same script runs on macOS, Linux, and Windows. Platform blocks handle the differences. Rush translates the rest.

db_name = "production"

macos
  driver = "/usr/local/lib/libmyodbc8a.so"
end

linux
  driver = "/usr/lib/x86_64-linux-gnu/odbc/libmyodbc8a.so"
end

win64
  driver = "{MySQL ODBC 8.0 Unicode Driver}"
end

sql @db "SELECT count(*) FROM orders
  WHERE date > #{Time.now - 24.hours}"
brew install mhasse1/tap/rush or download from GitHub

Clean Syntax That Keeps Unix Working

Fish tried clean syntax but broke compatibility. Rush keeps both. Unix commands run natively — ls, grep, git, docker just work.

No Sigil Confusion

Bash $name vs ${name} vs "$name"
Rush name = "world"

Variables have no sigils. Interpolation uses "hello #{name}". One pattern everywhere.

Blocks Use end

Bash if/then/fi, case/esac, do/done
Rush if/end, for/end, def/end

One block terminator for everything. No fi, esac, done, or bracket matching.

Spaces That Make Sense

Bash name="Mark" # no spaces allowed!
Rush name = "Mark" # works fine

LLMs constantly add spaces around =. In Bash that's an error. Rush just allows it.

Natural Comparisons

Bash [ "$x" -gt 5 ] vs (( x > 5 ))
Rush if x > 5

Use >, <, == naturally. No -gt, -eq, or double-bracket rules.

Objects, Not Text Parsing

Bash awk '{print $4}' | grep -E
Rush | where Status == "Up"

Query properties directly. No regex column extraction or brittle text parsing.

Not a Toy Language

Bash No classes, no error handling
Rush class, enum, begin/rescue, def

Classes, enums, error handling, named arguments, lambdas. A real scripting language that's also your shell.

How Rush Compares

RushBashZshPythonNushellPowerShell
Clean syntax
Unix commands native~
Structured pipelines~
LLM wire protocol
MCP servers
PS 7/5.1/32-bit blocks~
Cross-platform scripts~~
Native AI integration~
Spec fits in LLM context

Python Replacement for DevOps

Rush is Python without the ceremony. No virtualenv, no pip, no import blocks, no if __name__ == '__main__'. For sysadmin and devops scripting, the question should be: why Python when there's a lighter tool?

🏗️

Classes & Error Handling

Real OOP, not a toy. Define classes with typed attributes, methods, and constructors. Structured error handling with begin/rescue.

class Server
  attr host: String, port: Int = 8080

  def initialize(host)
    self.host = host
  end

  def url
    return "http://#{self.host}:#{self.port}"
  end
end

s = Server.new("localhost")
puts s.url

# Error handling
begin
  data = File.read_json("config.json")
rescue => e
  die "config error: #{e.message}"
end
📚

Standard Library

File, Dir, and Time built in. Duration literals. No imports needed — it's all there.

# File I/O
content = File.read("data.txt")
lines = File.read_lines("log.txt")
config = File.read_json("config.json")
File.write("/tmp/out.txt", "hello")

# Directory operations
Dir.list(".", :files)
Dir.list("src", :recurse)
Dir.mkdir("/tmp/myapp/logs")

# Time and durations
t = Time.now
recent = Time.now - 24.hours
🗄️

SQL Built In

SQLite, PostgreSQL, ODBC — no driver installations, no ORMs. Named connections and direct query results.

# Add a named connection
sql add @logs --driver sqlite --path ~/data.db

# Query directly
sql @logs "SELECT * FROM events
  WHERE level = 'ERROR' LIMIT 10"

# Pipeline integration
sql @logs "SELECT path, count FROM requests" \
  | where count > 100

# Multiple output formats
sql @logs "SELECT * FROM users" --json
sql @logs "SELECT * FROM users" --csv

Plus It's Your Shell

Python can't cleanly run shell commands. Rush is your shell and your scripting language. No subprocess.run() gymnastics.

#!/usr/bin/env rush
target = ARGV[0] || die("usage: deploy.rush ")
branch = $(git rev-parse --abbrev-ref HEAD).strip

unless branch == "main" || target == "staging"
  die "can only deploy to production from main"
end

puts "deploying #{branch} to #{target}..."
git pull origin #{branch}
npm run build
rsync -avz --delete dist/ "#{target}.example.com:/var/www/"
puts "done."

Objectify — Structure Without Replacing Your Tools

Other shells (Nushell, Oil) replace ls, ps, grep with custom commands. Rush takes the opposite approach: keep the real Unix tools, structure their output after the fact. Your existing tools stay. Rush makes them smarter.

Auto-Objectify for Known Commands

# These just work — Rush knows the output format
ps aux | where CPU > 50 | select Name, CPU | sort --desc
docker ps | where Status =~ /Up/ | select Names, Status
netstat | where State == "ESTABLISHED" | count

Works With Any Text Output

# Objectify arbitrary command output
my-tool | objectify --delim "," | select name, value

# Format conversions
cat data.csv | from csv | where age > 30 | as json
ls /var/log | as json

Full Pipeline Operators

# Filter, aggregate, transform
| where, | select, | sort, | sort --desc
| count, | first N, | last N, | distinct
| sum, | avg, | as json, | as csv
| from json, | from csv, | tee file

Shell Features

The daily-use features that make Rush a pleasure to work in

⌨️

Vi & Emacs Modes

Full vi mode with W/B/E motions, dot-repeat, undo-all. Emacs mode too. Ctrl+R search, vi / search with n/N cycling.

🎨

Auto-Theming

Detects terminal background at startup. Configures LS_COLORS and syntax highlighting automatically. Dark and light terminals just work.

🔄

Git-Aware Prompt

Branch name and dirty state in your prompt. Real-time syntax highlighting. Tab completion for paths, commands, flags, and pipeline operators.

🛤️

PATH Management

path add, path rm, path check, path dedupe. Visual editor with existence checks. Changes persist automatically.

🔗

Config Sync

Sync your Rush config across machines via GitHub, SSH, or local path. Secrets file is never synced.

Hot Reload

Edit your config and reload without restarting. reload --hard restarts the binary while preserving session state.

Installation

macOS (Homebrew)

brew install mhasse1/tap/rush

All Platforms — GitHub Releases

# Download self-contained binary (no runtime needed)
github.com/mhasse1/rush/releases

Build from Source

git clone https://github.com/mhasse1/rush.git && cd rush
dotnet publish -c Release -r osx-arm64    # or linux-x64, win-x64
./install.sh

Requires .NET 10 SDK to build. Published binaries are self-contained.

🍎 macOS arm64, x64
🐧 Linux x64, arm64
🪟 Windows x64, ARM64