| layout | default |
|---|---|
| title | Chapter 1: Getting Started |
| nav_order | 1 |
| parent | Crush Tutorial |
Welcome to Chapter 1: Getting Started. In this part of Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
This chapter gets Crush installed and ready for real coding work in minutes.
- install Crush using your preferred platform path
- authenticate a provider and run first prompt
- validate session baseline in a local project
- fix common startup misconfigurations quickly
| Path | Command | Best For |
|---|---|---|
| Homebrew | brew install charmbracelet/tap/crush |
macOS/Linux package-managed setup |
| NPM | npm install -g @charmland/crush |
Node-centric environments |
| Winget | winget install charmbracelet.crush |
Windows environments |
| Go install | go install github.com/charmbracelet/crush@latest |
Go-native toolchain users |
- launch
crush - configure provider credentials when prompted (or set env vars first)
- open a project directory and ask for a scoped code task
- verify tool calls and file operations behave as expected
export ANTHROPIC_API_KEY=...
# or OPENAI_API_KEY, OPENROUTER_API_KEY, etc.
crush| Symptom | Cause | First Fix |
|---|---|---|
| provider not available | missing env var | set provider key and restart Crush |
| unstable output quality | model mismatch for coding tasks | switch to coding-optimized model |
| unexpected filesystem actions | loose permissions/tool policy | set explicit permission controls in config |
You now have Crush installed and running with a valid provider path.
Next: Chapter 2: Architecture and Session Model
The main function in main.go handles a key part of this chapter's functionality:
// Package main is the entry point for the Crush CLI.
//
// @title Crush API
// @version 1.0
// @description Crush is a terminal-based AI coding assistant. This API is served over a Unix socket (or Windows named pipe) and provides programmatic access to workspaces, sessions, agents, LSP, MCP, and more.
// @contact.name Charm
// @contact.url https://charm.sh
// @license.name MIT
// @license.url https://github.com/charmbracelet/crush/blob/main/LICENSE
// @BasePath /v1
package main
import (
"log/slog"
"net/http"
_ "net/http/pprof"
"os"
"github.com/charmbracelet/crush/internal/cmd"
_ "github.com/joho/godotenv/autoload"
)
func main() {
if os.Getenv("CRUSH_PROFILE") != "" {
go func() {
slog.Info("Serving pprof at localhost:6060")
if httpErr := http.ListenAndServe("localhost:6060", nil); httpErr != nil {
slog.Error("Failed to pprof listen", "error", httpErr)
}
}()This function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
The options interface in schema.json handles a key part of this chapter's functionality:
"description": "Language Server Protocol configurations"
},
"options": {
"$ref": "#/$defs/Options",
"description": "General application options"
},
"permissions": {
"$ref": "#/$defs/Permissions",
"description": "Permission settings for tool usage"
},
"tools": {
"$ref": "#/$defs/Tools",
"description": "Tool configurations"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"tools"
]
},
"LSPConfig": {
"properties": {
"disabled": {
"type": "boolean",
"description": "Whether this LSP server is disabled",
"default": false
},
"command": {
"type": "string",
"description": "Command to execute for the LSP server",
"examples": [This interface is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
The NewSessionAgent function in internal/agent/agent.go handles a key part of this chapter's functionality:
}
func NewSessionAgent(
opts SessionAgentOptions,
) SessionAgent {
return &sessionAgent{
largeModel: csync.NewValue(opts.LargeModel),
smallModel: csync.NewValue(opts.SmallModel),
systemPromptPrefix: csync.NewValue(opts.SystemPromptPrefix),
systemPrompt: csync.NewValue(opts.SystemPrompt),
isSubAgent: opts.IsSubAgent,
sessions: opts.Sessions,
messages: opts.Messages,
disableAutoSummarize: opts.DisableAutoSummarize,
tools: csync.NewSliceFrom(opts.Tools),
isYolo: opts.IsYolo,
notify: opts.Notify,
messageQueue: csync.NewMap[string, []SessionAgentCall](),
activeRequests: csync.NewMap[string, context.CancelFunc](),
}
}
func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy.AgentResult, error) {
if call.Prompt == "" && !message.ContainsTextAttachment(call.Attachments) {
return nil, ErrEmptyPrompt
}
if call.SessionID == "" {
return nil, ErrSessionMissing
}
// Queue the message if busy
if a.IsSessionBusy(call.SessionID) {This function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
The Run function in internal/agent/agent.go handles a key part of this chapter's functionality:
type SessionAgent interface {
Run(context.Context, SessionAgentCall) (*fantasy.AgentResult, error)
SetModels(large Model, small Model)
SetTools(tools []fantasy.AgentTool)
SetSystemPrompt(systemPrompt string)
Cancel(sessionID string)
CancelAll()
IsSessionBusy(sessionID string) bool
IsBusy() bool
QueuedPrompts(sessionID string) int
QueuedPromptsList(sessionID string) []string
ClearQueue(sessionID string)
Summarize(context.Context, string, fantasy.ProviderOptions) error
Model() Model
}
type Model struct {
Model fantasy.LanguageModel
CatwalkCfg catwalk.Model
ModelCfg config.SelectedModel
}
type sessionAgent struct {
largeModel *csync.Value[Model]
smallModel *csync.Value[Model]
systemPromptPrefix *csync.Value[string]
systemPrompt *csync.Value[string]
tools *csync.Slice[fantasy.AgentTool]
isSubAgent bool
sessions session.ServiceThis function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
flowchart TD
A[main]
B[options]
C[NewSessionAgent]
D[Run]
E[Summarize]
A --> B
B --> C
C --> D
D --> E