on main help sign in
chore: rename opencode -> crush
commit5baebf702d0cf3da94cd4167636755660a875bea authorKujtim Hoxha <kujtimii.h@gmail.com> dateSat 7 Jun 2025, 21:09 (1 year ago) parent06e8c75
20 files changed+80−80
README.md+22−22 cmd/root.go+7−7 cmd/schema/README.md+3−3 cmd/schema/main.go+5−5 cspell.json+1−1 install+11−11 internal/config/config.go+5−5 internal/db/connect.go+1−1 internal/fileutil/fileutil.go+1−1 internal/fileutil/ls.go+1−1 internal/llm/prompt/coder.go+2−2 internal/llm/provider/provider.go+1−1 internal/llm/tools/bash.go+5−5 internal/llm/tools/fetch.go+1−1 internal/llm/tools/shell/shell.go+4−4 internal/llm/tools/sourcegraph.go+1−1 internal/logging/logger.go+1−1 internal/tui/components/dialogs/commands/commands.go+1−1 internal/tui/components/dialogs/commands/loader.go+2−2 opencode-schema.json+5−5
README.md+22−22
@@ -43,17 +43,17 @@ curl -fsSL https://raw.githubusercontent.com/charmbracelet/crush/refs/heads/main
4343### Using Homebrew (macOS and Linux)
4444
4545```bash
46−brew install opencode-ai/tap/opencode
46+brew install crush-ai/tap/crush
4747```
4848
4949### Using AUR (Arch Linux)
5050
5151```bash
5252# Using yay
53−yay -S opencode-ai-bin
53+yay -S crush-ai-bin
5454
5555# Using paru
56−paru -S opencode-ai-bin
56+paru -S crush-ai-bin
5757```
5858
5959### Using Go
@@ -66,9 +66,9 @@ go install github.com/charmbracelet/crush@latest
6666
6767OpenCode looks for configuration in the following locations:
6868
69−- `$HOME/.opencode.json`
70−- `$XDG_CONFIG_HOME/opencode/.opencode.json`
71−- `./.opencode.json` (local directory)
69+- `$HOME/.crush.json`
70+- `$XDG_CONFIG_HOME/crush/.crush.json`
71+- `./.crush.json` (local directory)
7272
7373### Auto Compact Feature
7474
@@ -130,7 +130,7 @@ This is useful if you want to use a different shell than your default system she
130130```json
131131{
132132 "data": {
133− "directory": ".opencode"
133+ "directory": ".crush"
134134 },
135135 "providers": {
136136 "openai": {
@@ -248,13 +248,13 @@ OpenCode supports a variety of AI models from different providers:
248248
249249```bash
250250# Start OpenCode
251−opencode
251+crush
252252
253253# Start with debug logging
254−opencode -d
254+crush -d
255255
256256# Start with a specific working directory
257−opencode -c /path/to/project
257+crush -c /path/to/project
258258```
259259
260260## Non-interactive Prompt Mode
@@ -263,13 +263,13 @@ You can run OpenCode in non-interactive mode by passing a prompt directly as a c
263263
264264```bash
265265# Run a single prompt and print the AI's response to the terminal
266−opencode -p "Explain the use of context in Go"
266+crush -p "Explain the use of context in Go"
267267
268268# Get response in JSON format
269−opencode -p "Explain the use of context in Go" -f json
269+crush -p "Explain the use of context in Go" -f json
270270
271271# Run without showing the spinner (useful for scripts)
272−opencode -p "Explain the use of context in Go" -q
272+crush -p "Explain the use of context in Go" -q
273273```
274274
275275In this mode, OpenCode will process your prompt, print the result to standard output, and then exit. All permissions are auto-approved for the session.
@@ -419,26 +419,26 @@ Custom commands are predefined prompts stored as Markdown files in one of three
4194191. **User Commands** (prefixed with `user:`):
420420
421421 ```
422− $XDG_CONFIG_HOME/opencode/commands/
422+ $XDG_CONFIG_HOME/crush/commands/
423423 ```
424424
425− (typically `~/.config/opencode/commands/` on Linux/macOS)
425+ (typically `~/.config/crush/commands/` on Linux/macOS)
426426
427427 or
428428
429429 ```
430− $HOME/.opencode/commands/
430+ $HOME/.crush/commands/
431431 ```
432432
4334332. **Project Commands** (prefixed with `project:`):
434434
435435 ```
436− <PROJECT DIR>/.opencode/commands/
436+ <PROJECT DIR>/.crush/commands/
437437 ```
438438
439439Each `.md` file in these directories becomes a custom command. The file name (without extension) becomes the command ID.
440440
441−For example, creating a file at `~/.config/opencode/commands/prime-context.md` with content:
441+For example, creating a file at `~/.config/crush/commands/prime-context.md` with content:
442442
443443```markdown
444444RUN git ls-files
@@ -472,7 +472,7 @@ When you run a command with arguments, OpenCode will prompt you to enter values
472472You can organize commands in subdirectories:
473473
474474```
475−~/.config/opencode/commands/git/commit.md
475+~/.config/crush/commands/git/commit.md
476476```
477477
478478This creates a command with ID `user:git:commit`.
@@ -614,13 +614,13 @@ You can also configure a self-hosted model in the configuration file under the `
614614```bash
615615# Clone the repository
616616git clone https://github.com/charmbracelet/crush.git
617−cd opencode
617+cd crush
618618
619619# Build
620−go build -o opencode
620+go build -o crush
621621
622622# Run
623−./opencode
623+./crush
624624```
625625
626626## Acknowledgments
cmd/root.go+7−7
@@ -21,29 +21,29 @@ import (
2121)
2222
2323var rootCmd = &cobra.Command{
24− Use: "opencode",
24+ Use: "crush",
2525 Short: "Terminal-based AI assistant for software development",
2626 Long: `OpenCode is a powerful terminal-based AI assistant that helps with software development tasks.
2727It provides an interactive chat interface with AI capabilities, code analysis, and LSP integration
2828to assist developers in writing, debugging, and understanding code directly from the terminal.`,
2929 Example: `
3030 # Run in interactive mode
31− opencode
31+ crush
3232
3333 # Run with debug logging
34− opencode -d
34+ crush -d
3535
3636 # Run with debug logging in a specific directory
37− opencode -d -c /path/to/project
37+ crush -d -c /path/to/project
3838
3939 # Print version
40− opencode -v
40+ crush -v
4141
4242 # Run a single non-interactive prompt
43− opencode -p "Explain the use of context in Go"
43+ crush -p "Explain the use of context in Go"
4444
4545 # Run a single non-interactive prompt with JSON output format
46− opencode -p "Explain the use of context in Go" -f json
46+ crush -p "Explain the use of context in Go" -f json
4747 `,
4848 RunE: func(cmd *cobra.Command, args []string) error {
4949 // If the help flag is set, show the help message
cmd/schema/README.md+3−3
@@ -5,7 +5,7 @@ This tool generates a JSON Schema for the OpenCode configuration file. The schem
55## Usage
66
77```bash
8−go run cmd/schema/main.go > opencode-schema.json
8+go run cmd/schema/main.go > crush-schema.json
99```
1010
1111This will generate a JSON Schema file that can be used to validate configuration files.
@@ -24,7 +24,7 @@ The generated schema includes:
2424
2525You can use the generated schema in several ways:
2626
27−1. **Editor Integration**: Many editors (VS Code, JetBrains IDEs, etc.) support JSON Schema for validation and autocompletion. You can configure your editor to use the generated schema for `.opencode.json` files.
27+1. **Editor Integration**: Many editors (VS Code, JetBrains IDEs, etc.) support JSON Schema for validation and autocompletion. You can configure your editor to use the generated schema for `.crush.json` files.
2828
29292. **Validation Tools**: You can use tools like [jsonschema](https://github.com/Julian/jsonschema) to validate your configuration files against the schema.
3030
@@ -37,7 +37,7 @@ Here's an example configuration that conforms to the schema:
3737```json
3838{
3939 "data": {
40− "directory": ".opencode"
40+ "directory": ".crush"
4141 },
4242 "debug": false,
4343 "providers": {
cmd/schema/main.go+5−5
@@ -52,7 +52,7 @@ func generateSchema() map[string]any {
5252 "directory": map[string]any{
5353 "type": "string",
5454 "description": "Directory where application data is stored",
55− "default": ".opencode",
55+ "default": ".crush",
5656 },
5757 },
5858 "required": []string{"directory"},
@@ -89,8 +89,8 @@ func generateSchema() map[string]any {
8989 ".cursor/rules/",
9090 "CLAUDE.md",
9191 "CLAUDE.local.md",
92− "opencode.md",
93− "opencode.local.md",
92+ "crush.md",
93+ "crush.local.md",
9494 "OpenCode.md",
9595 "OpenCode.local.md",
9696 "OPENCODE.md",
@@ -105,9 +105,9 @@ func generateSchema() map[string]any {
105105 "theme": map[string]any{
106106 "type": "string",
107107 "description": "TUI theme name",
108− "default": "opencode",
108+ "default": "crush",
109109 "enum": []string{
110− "opencode",
110+ "crush",
111111 "catppuccin",
112112 "dracula",
113113 "flexoki",
cspell.json+1−1
@@ -1 +1 @@
1−{"flagWords":[],"language":"en","words":["opencode","charmbracelet","lipgloss","bubbletea","textinput","Focusable","lsps","Sourcegraph","filepicker","imageorient","rasterx","oksvg","termenv","trashhalo","lucasb","nfnt","srwiley","Lanczos"],"version":"0.2"}
1+{"flagWords":[],"language":"en","words":["crush","charmbracelet","lipgloss","bubbletea","textinput","Focusable","lsps","Sourcegraph","filepicker","imageorient","rasterx","oksvg","termenv","trashhalo","lucasb","nfnt","srwiley","Lanczos"],"version":"0.2"}
install+11−11
@@ -1,6 +1,6 @@
11#!/usr/bin/env bash
22set -euo pipefail
3−APP=opencode
3+APP=crush
44
55RED='\033[0;31m'
66GREEN='\033[0;32m'
@@ -36,7 +36,7 @@ case "$filename" in
3636 ;;
3737esac
3838
39−INSTALL_DIR=$HOME/.opencode/bin
39+INSTALL_DIR=$HOME/.crush/bin
4040mkdir -p "$INSTALL_DIR"
4141
4242if [ -z "$requested_version" ]; then
@@ -67,12 +67,12 @@ print_message() {
6767}
6868
6969check_version() {
70− if command -v opencode >/dev/null 2>&1; then
71− opencode_path=$(which opencode)
70+ if command -v crush >/dev/null 2>&1; then
71+ crush_path=$(which crush)
7272
7373
7474 ## TODO: check if version is installed
75− # installed_version=$(opencode version)
75+ # installed_version=$(crush version)
7676 installed_version="0.0.1"
7777 installed_version=$(echo $installed_version | awk '{print $2}')
7878
@@ -86,11 +86,11 @@ check_version() {
8686}
8787
8888download_and_install() {
89− print_message info "Downloading ${ORANGE}opencode ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..."
90− mkdir -p opencodetmp && cd opencodetmp
89+ print_message info "Downloading ${ORANGE}crush ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..."
90+ mkdir -p crushtmp && cd crushtmp
9191 curl -# -L $url | tar xz
92− mv opencode $INSTALL_DIR
93− cd .. && rm -rf opencodetmp
92+ mv crush $INSTALL_DIR
93+ cd .. && rm -rf crushtmp
9494}
9595
9696check_version
@@ -102,9 +102,9 @@ add_to_path() {
102102 local command=$2
103103
104104 if [[ -w $config_file ]]; then
105− echo -e "\n# opencode" >> "$config_file"
105+ echo -e "\n# crush" >> "$config_file"
106106 echo "$command" >> "$config_file"
107− print_message info "Successfully added ${ORANGE}opencode ${GREEN}to \$PATH in $config_file"
107+ print_message info "Successfully added ${ORANGE}crush ${GREEN}to \$PATH in $config_file"
108108 else
109109 print_message warning "Manually add the directory to $config_file (or similar):"
110110 print_message info " $command"
internal/config/config.go+5−5
@@ -97,9 +97,9 @@ type Config struct {
9797
9898// Application constants
9999const (
100− defaultDataDirectory = ".opencode"
100+ defaultDataDirectory = ".crush"
101101 defaultLogLevel = "info"
102− appName = "opencode"
102+ appName = "crush"
103103
104104 MaxTokensFallbackDefault = 4096
105105)
@@ -110,8 +110,8 @@ var defaultContextPaths = []string{
110110 ".cursor/rules/",
111111 "CLAUDE.md",
112112 "CLAUDE.local.md",
113− "opencode.md",
114− "opencode.local.md",
113+ "crush.md",
114+ "crush.local.md",
115115 "OpenCode.md",
116116 "OpenCode.local.md",
117117 "OPENCODE.md",
@@ -221,7 +221,7 @@ func configureViper() {
221221func setDefaults(debug bool) {
222222 viper.SetDefault("data.directory", defaultDataDirectory)
223223 viper.SetDefault("contextPaths", defaultContextPaths)
224− viper.SetDefault("tui.theme", "opencode")
224+ viper.SetDefault("tui.theme", "crush")
225225 viper.SetDefault("autoCompact", true)
226226
227227 // Set default shell from environment or fallback to /bin/bash
internal/db/connect.go+1−1
@@ -23,7 +23,7 @@ func Connect() (*sql.DB, error) {
2323 if err := os.MkdirAll(dataDir, 0o700); err != nil {
2424 return nil, fmt.Errorf("failed to create data directory: %w", err)
2525 }
26− dbPath := filepath.Join(dataDir, "opencode.db")
26+ dbPath := filepath.Join(dataDir, "crush.db")
2727 // Open the SQLite database
2828 db, err := sql.Open("sqlite3", dbPath)
2929 if err != nil {
internal/fileutil/fileutil.go+1−1
@@ -67,7 +67,7 @@ func SkipHidden(path string) bool {
6767 }
6868
6969 commonIgnoredDirs := map[string]bool{
70− ".opencode": true,
70+ ".crush": true,
7171 "node_modules": true,
7272 "vendor": true,
7373 "dist": true,
internal/fileutil/ls.go+1−1
@@ -64,7 +64,7 @@ var CommonIgnorePatterns = []string{
6464 ".fseventsd",
6565
6666 // OpenCode
67− ".opencode",
67+ ".crush",
6868}
6969
7070type DirectoryLister struct {
internal/llm/prompt/coder.go+2−2
@@ -33,7 +33,7 @@ You can:
3333- Apply patches, run commands, and manage user approvals based on policy.
3434- Work inside a sandboxed, git-backed workspace with rollback support.
3535- Log telemetry so sessions can be replayed or inspected later.
36−- More details on your functionality are available at "opencode --help"
36+- More details on your functionality are available at "crush --help"
3737
3838
3939You are an agent - please keep going until the user's query is completely resolved, before ending your turn and yielding back to the user. Only terminate your turn when you are sure that the problem is solved. If you are not sure about file content or codebase structure pertaining to the user's request, use your tools to read files and gather the relevant information: do NOT guess or make up an answer.
@@ -156,7 +156,7 @@ The user will primarily request you perform software engineering tasks. This inc
1561561. Use the available search tools to understand the codebase and the user's query.
1571572. Implement the solution using all tools available to you
1581583. Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.
159−4. VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (eg. npm run lint, npm run typecheck, ruff, etc.) if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to opencode.md so that you will know to run it next time.
159+4. VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (eg. npm run lint, npm run typecheck, ruff, etc.) if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to crush.md so that you will know to run it next time.
160160
161161NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.
162162
internal/llm/provider/provider.go+1−1
@@ -130,7 +130,7 @@ func NewProvider(providerName models.ModelProvider, opts ...ProviderClientOption
130130 clientOptions.openaiOptions = append(clientOptions.openaiOptions,
131131 WithOpenAIBaseURL("https://openrouter.ai/api/v1"),
132132 WithOpenAIExtraHeaders(map[string]string{
133− "HTTP-Referer": "opencode.ai",
133+ "HTTP-Referer": "crush.ai",
134134 "X-Title": "OpenCode",
135135 }),
136136 )
internal/llm/tools/bash.go+5−5
@@ -122,16 +122,16 @@ When the user asks you to create a new git commit, follow these steps carefully:
122122</commit_analysis>
123123
1241244. Create the commit with a message ending with:
125−🤖 Generated with opencode
126−Co-Authored-By: opencode <noreply@opencode.ai>
125+🤖 Generated with crush
126+Co-Authored-By: crush <noreply@crush.ai>
127127
128128- In order to ensure good formatting, ALWAYS pass the commit message via a HEREDOC, a la this example:
129129<example>
130130git commit -m "$(cat <<'EOF'
131131 Commit message here.
132132
133− 🤖 Generated with opencode
134− Co-Authored-By: opencode <noreply@opencode.ai>
133+ 🤖 Generated with crush
134+ Co-Authored-By: crush <noreply@crush.ai>
135135 EOF
136136 )"
137137</example>
@@ -193,7 +193,7 @@ gh pr create --title "the pr title" --body "$(cat <<'EOF'
193193## Test plan
194194[Checklist of TODOs for testing the pull request...]
195195
196−🤖 Generated with opencode
196+🤖 Generated with crush
197197EOF
198198)"
199199</example>
internal/llm/tools/fetch.go+1−1
@@ -152,7 +152,7 @@ func (t *fetchTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error
152152 return ToolResponse{}, fmt.Errorf("failed to create request: %w", err)
153153 }
154154
155− req.Header.Set("User-Agent", "opencode/1.0")
155+ req.Header.Set("User-Agent", "crush/1.0")
156156
157157 resp, err := client.Do(req)
158158 if err != nil {
internal/llm/tools/shell/shell.go+4−4
@@ -149,10 +149,10 @@ func (s *PersistentShell) execCommand(command string, timeout time.Duration, ctx
149149 }
150150
151151 tempDir := os.TempDir()
152− stdoutFile := filepath.Join(tempDir, fmt.Sprintf("opencode-stdout-%d", time.Now().UnixNano()))
153− stderrFile := filepath.Join(tempDir, fmt.Sprintf("opencode-stderr-%d", time.Now().UnixNano()))
154− statusFile := filepath.Join(tempDir, fmt.Sprintf("opencode-status-%d", time.Now().UnixNano()))
155− cwdFile := filepath.Join(tempDir, fmt.Sprintf("opencode-cwd-%d", time.Now().UnixNano()))
152+ stdoutFile := filepath.Join(tempDir, fmt.Sprintf("crush-stdout-%d", time.Now().UnixNano()))
153+ stderrFile := filepath.Join(tempDir, fmt.Sprintf("crush-stderr-%d", time.Now().UnixNano()))
154+ statusFile := filepath.Join(tempDir, fmt.Sprintf("crush-status-%d", time.Now().UnixNano()))
155+ cwdFile := filepath.Join(tempDir, fmt.Sprintf("crush-cwd-%d", time.Now().UnixNano()))
156156
157157 defer func() {
158158 os.Remove(stdoutFile)
internal/llm/tools/sourcegraph.go+1−1
@@ -218,7 +218,7 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
218218 }
219219
220220 req.Header.Set("Content-Type", "application/json")
221− req.Header.Set("User-Agent", "opencode/1.0")
221+ req.Header.Set("User-Agent", "crush/1.0")
222222
223223 resp, err := client.Do(req)
224224 if err != nil {
internal/logging/logger.go+1−1
@@ -54,7 +54,7 @@ func RecoverPanic(name string, cleanup func()) {
5454
5555 // Create a timestamped panic log file
5656 timestamp := time.Now().Format("20060102-150405")
57− filename := fmt.Sprintf("opencode-panic-%s-%s.log", name, timestamp)
57+ filename := fmt.Sprintf("crush-panic-%s-%s.log", name, timestamp)
5858
5959 file, err := os.Create(filename)
6060 if err != nil {
internal/tui/components/dialogs/commands/commands.go+1−1
@@ -233,7 +233,7 @@ func (c *commandDialogCmp) defaultCommands() []Command {
233233 2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
234234
235235 The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20 lines long.
236− If there's already a opencode.md, improve it.
236+ If there's already a crush.md, improve it.
237237 If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include them.`
238238 return tea.Batch(
239239 util.CmdHandler(chat.SendMsg{
internal/tui/components/dialogs/commands/loader.go+2−2
@@ -56,7 +56,7 @@ func buildCommandSources(cfg *config.Config) []commandSource {
5656 // Home directory
5757 if home, err := os.UserHomeDir(); err == nil {
5858 sources = append(sources, commandSource{
59− path: filepath.Join(home, ".opencode", "commands"),
59+ path: filepath.Join(home, ".crush", "commands"),
6060 prefix: UserCommandPrefix,
6161 })
6262 }
@@ -78,7 +78,7 @@ func getXDGCommandsDir() string {
7878 }
7979 }
8080 if xdgHome != "" {
81− return filepath.Join(xdgHome, "opencode", "commands")
81+ return filepath.Join(xdgHome, "crush", "commands")
8282 }
8383 return ""
8484}
opencode-schema.json+5−5
@@ -216,8 +216,8 @@
216216 ".cursor/rules/",
217217 "CLAUDE.md",
218218 "CLAUDE.local.md",
219− "opencode.md",
220− "opencode.local.md",
219+ "crush.md",
220+ "crush.local.md",
221221 "OpenCode.md",
222222 "OpenCode.local.md",
223223 "OPENCODE.md",
@@ -233,7 +233,7 @@
233233 "description": "Storage configuration",
234234 "properties": {
235235 "directory": {
236− "default": ".opencode",
236+ "default": ".crush",
237237 "description": "Directory where application data is stored",
238238 "type": "string"
239239 }
@@ -374,10 +374,10 @@
374374 "description": "Terminal User Interface configuration",
375375 "properties": {
376376 "theme": {
377− "default": "opencode",
377+ "default": "crush",
378378 "description": "TUI theme name",
379379 "enum": [
380− "opencode",
380+ "crush",
381381 "catppuccin",
382382 "dracula",
383383 "flexoki",