A Modern Day Warrior
# macOS
brew install mhasse1/tap/rushRush 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.
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}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 fasterNative 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"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")'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)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 throughNo 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.
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| Block | Engine | Use case |
|---|---|---|
ps | PowerShell 7 | Cmdlets, $_, script blocks, Where-Object |
ps5 | PowerShell 5.1 | Legacy: AD, Exchange, older management |
win32 | 32-bit PS 5.1 | OLEDB/ODBC: Access, Excel, Business Central |
win64 | Rush syntax | Windows-specific Rush code |
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 }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 .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}"Fish tried clean syntax but broke compatibility. Rush keeps both. Unix commands run natively — ls, grep, git, docker just work.
$name vs ${name} vs "$name"name = "world"Variables have no sigils. Interpolation uses "hello #{name}". One pattern everywhere.
endif/then/fi, case/esac, do/doneif/end, for/end, def/endOne block terminator for everything. No fi, esac, done, or bracket matching.
name="Mark" # no spaces allowed!name = "Mark" # works fineLLMs constantly add spaces around =. In Bash that's an error. Rush just allows it.
[ "$x" -gt 5 ] vs (( x > 5 ))if x > 5Use >, <, == naturally. No -gt, -eq, or double-bracket rules.
awk '{print $4}' | grep -E| where Status == "Up"Query properties directly. No regex column extraction or brittle text parsing.
No classes, no error handlingclass, enum, begin/rescue, defClasses, enums, error handling, named arguments, lambdas. A real scripting language that's also your shell.
| Rush | Bash | Zsh | Python | Nushell | PowerShell | |
|---|---|---|---|---|---|---|
| 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 | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
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?
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}"
endFile, 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.hoursSQLite, 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" --csvPython 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." 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.
# 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# 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# 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 fileThe daily-use features that make Rush a pleasure to work in
Full vi mode with W/B/E motions, dot-repeat, undo-all. Emacs mode too. Ctrl+R search, vi / search with n/N cycling.
Detects terminal background at startup. Configures LS_COLORS and syntax highlighting automatically. Dark and light terminals just work.
Branch name and dirty state in your prompt. Real-time syntax highlighting. Tab completion for paths, commands, flags, and pipeline operators.
path add, path rm, path check, path dedupe. Visual editor with existence checks. Changes persist automatically.
Sync your Rush config across machines via GitHub, SSH, or local path. Secrets file is never synced.
Edit your config and reload without restarting. reload --hard restarts the binary while preserving session state.
brew install mhasse1/tap/rush# Download self-contained binary (no runtime needed)
github.com/mhasse1/rush/releasesgit clone https://github.com/mhasse1/rush.git && cd rush
dotnet publish -c Release -r osx-arm64 # or linux-x64, win-x64
./install.shRequires .NET 10 SDK to build. Published binaries are self-contained.
Sign up for release updates, or jump straight in.
License: BSL 1.1 — source-available today, Apache 2.0 in four years. Details