Crush: An AI Coding Agent for Your Terminal
Crush is an AI coding agent designed to live right in your terminal. It's built by Charmbracelet, the same team behind popular TUI (Terminal User Interface) tools like Bubble Tea and Glow. It provides a way to interact with powerful large language models (LLMs) directly from your command line, which can be a game-changer for your daily workflow.
From a software engineering standpoint, Crush isn't just a fancy chatbot; it's a productivity tool. Here's how it can be genuinely useful
Generating Boilerplate Code
Need a quick script in a language you're not super familiar with? Or a basic function for a specific task? You can ask Crush to generate it for you. This saves you from having to search online and stitch together code snippets.
Refactoring and Explaining Code
Paste in a block of code and ask Crush to refactor it to be more idiomatic or efficient. You can also ask it to explain a complex function or regular expression you've inherited. This is great for understanding legacy codebases.
Debugging Assistance
While it won't replace a debugger, Crush can offer suggestions based on error messages or a snippet of code. For example, you can give it a stack trace and ask what the most likely cause is.
Automating Repetitive Tasks
Instead of manually creating a series of Git commands or cURL requests, you can describe the task in natural language and have Crush generate the command for you.
Learning and Exploring
You can use it as a personal tutor to explore new libraries, design patterns, or system architectures. Ask it to "Explain how a B-tree works" or "Give me an example of the factory design pattern in Python."
Think of it as a pair programmer that's always available, doesn't need a fancy IDE plugin, and works seamlessly with your terminal-based workflow.
The installation process is straightforward and, like other Charmbracelet tools, designed to be very simple.
First, you'll need to install a few things
Go
Crush is written in Go, and having the Go toolchain installed makes it easy to get.
Access to an AI Model
Crush requires a model endpoint. The most common way to get started is by using an OpenAI API key, but it also supports other APIs.
Open your terminal and run the following command to install Crush
go install github.com/charmbracelet/crush@latest
This command fetches the source code and compiles it, placing the executable in your $GOPATH/bin directory.
Next, you need to configure Crush with your API key. The easiest way is to set an environment variable. For example, if you're using OpenAI
export OPENAI_API_KEY="your-api-key-here"
You can add this line to your shell's configuration file (like .zshrc or .bashrc) so you don't have to set it every time.
Once configured, you're ready to start using it!
Crush is designed to be used conversationally, right from your command line. The main command is simply crush.
To start a new conversation, just type crush followed by your prompt.
Prompt
"Generate a simple shell script to list all files in the current directory and its subdirectories that have a .log extension."
crush "Generate a simple shell script to list all files in the current directory and its subdirectories that have a .log extension."
Crush's Response
find . -type f -name "*.log"
Let's say you need a Python function to read a JSON file.
Prompt
"Write a Python function that takes a file path and returns the parsed JSON data."
crush "Write a Python function that takes a file path and returns the parsed JSON data."
Crush's Response
import json
def read_json_file(file_path):
"""
Reads a JSON file from the given path and returns the parsed data.
"""
try:
with open(file_path, 'r') as f:
data = json.load(f)
return data
except FileNotFoundError:
print(f"Error: The file '{file_path}' was not found.")
return None
except json.JSONDecodeError:
print(f"Error: Could not decode JSON from the file '{file_path}'.")
return None
Notice how it provides a complete, well-commented, and robust function, including error handling.
You can also pipe content directly to Crush for quick analysis.
Prompt
"Refactor this Go function to use a more idiomatic way of checking for an error."
echo "
func getPerson() (Person, error) {
p, err := fetchPersonFromDB()
if err != nil {
return Person{}, err
}
return p, nil
}
" | crush "Refactor this Go function to use a more idiomatic way of checking for an error."
Crush's Response
func getPerson() (Person, error) {
p, err := fetchPersonFromDB()
if err != nil {
return Person{}, fmt.Errorf("failed to get person: %w", err)
}
return p, nil
}
This example shows a better practice for wrapping errors with more context, a common pattern in Go.