From 5baebf702d0cf3da94cd4167636755660a875bea Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Sat, 7 Jun 2025 21:09:10 +0200 Subject: [PATCH] chore: rename opencode -> crush --- README.md | 44 +++++++++---------- cmd/root.go | 14 +++--- cmd/schema/README.md | 6 +-- cmd/schema/main.go | 10 ++--- cspell.json | 2 +- install | 22 +++++----- internal/config/config.go | 10 ++--- internal/db/connect.go | 2 +- internal/fileutil/fileutil.go | 2 +- internal/fileutil/ls.go | 2 +- internal/llm/prompt/coder.go | 4 +- internal/llm/provider/provider.go | 2 +- internal/llm/tools/bash.go | 10 ++--- internal/llm/tools/fetch.go | 2 +- internal/llm/tools/shell/shell.go | 8 ++-- internal/llm/tools/sourcegraph.go | 2 +- internal/logging/logger.go | 2 +- .../components/dialogs/commands/commands.go | 2 +- .../tui/components/dialogs/commands/loader.go | 4 +- opencode-schema.json | 10 ++--- 20 files changed, 80 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index 39fec806a2d299dffefb039404aeae11ea37e55e..4b68dfbdb4f915dbde5c348720fa37072a3dcafd 100644 --- a/README.md +++ b/README.md @@ -43,17 +43,17 @@ curl -fsSL https://raw.githubusercontent.com/charmbracelet/crush/refs/heads/main ### Using Homebrew (macOS and Linux) ```bash -brew install opencode-ai/tap/opencode +brew install crush-ai/tap/crush ``` ### Using AUR (Arch Linux) ```bash # Using yay -yay -S opencode-ai-bin +yay -S crush-ai-bin # Using paru -paru -S opencode-ai-bin +paru -S crush-ai-bin ``` ### Using Go @@ -66,9 +66,9 @@ go install github.com/charmbracelet/crush@latest OpenCode looks for configuration in the following locations: -- `$HOME/.opencode.json` -- `$XDG_CONFIG_HOME/opencode/.opencode.json` -- `./.opencode.json` (local directory) +- `$HOME/.crush.json` +- `$XDG_CONFIG_HOME/crush/.crush.json` +- `./.crush.json` (local directory) ### Auto Compact Feature @@ -130,7 +130,7 @@ This is useful if you want to use a different shell than your default system she ```json { "data": { - "directory": ".opencode" + "directory": ".crush" }, "providers": { "openai": { @@ -248,13 +248,13 @@ OpenCode supports a variety of AI models from different providers: ```bash # Start OpenCode -opencode +crush # Start with debug logging -opencode -d +crush -d # Start with a specific working directory -opencode -c /path/to/project +crush -c /path/to/project ``` ## Non-interactive Prompt Mode @@ -263,13 +263,13 @@ You can run OpenCode in non-interactive mode by passing a prompt directly as a c ```bash # Run a single prompt and print the AI's response to the terminal -opencode -p "Explain the use of context in Go" +crush -p "Explain the use of context in Go" # Get response in JSON format -opencode -p "Explain the use of context in Go" -f json +crush -p "Explain the use of context in Go" -f json # Run without showing the spinner (useful for scripts) -opencode -p "Explain the use of context in Go" -q +crush -p "Explain the use of context in Go" -q ``` In 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 1. **User Commands** (prefixed with `user:`): ``` - $XDG_CONFIG_HOME/opencode/commands/ + $XDG_CONFIG_HOME/crush/commands/ ``` - (typically `~/.config/opencode/commands/` on Linux/macOS) + (typically `~/.config/crush/commands/` on Linux/macOS) or ``` - $HOME/.opencode/commands/ + $HOME/.crush/commands/ ``` 2. **Project Commands** (prefixed with `project:`): ``` - /.opencode/commands/ + /.crush/commands/ ``` Each `.md` file in these directories becomes a custom command. The file name (without extension) becomes the command ID. -For example, creating a file at `~/.config/opencode/commands/prime-context.md` with content: +For example, creating a file at `~/.config/crush/commands/prime-context.md` with content: ```markdown RUN git ls-files @@ -472,7 +472,7 @@ When you run a command with arguments, OpenCode will prompt you to enter values You can organize commands in subdirectories: ``` -~/.config/opencode/commands/git/commit.md +~/.config/crush/commands/git/commit.md ``` This 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 ` ```bash # Clone the repository git clone https://github.com/charmbracelet/crush.git -cd opencode +cd crush # Build -go build -o opencode +go build -o crush # Run -./opencode +./crush ``` ## Acknowledgments diff --git a/cmd/root.go b/cmd/root.go index 9a8748f5252773176b490b172fd8c14c26e7bc12..db9cc116f2db557e4affefc1453612fd5f2a9531 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,29 +21,29 @@ import ( ) var rootCmd = &cobra.Command{ - Use: "opencode", + Use: "crush", Short: "Terminal-based AI assistant for software development", Long: `OpenCode is a powerful terminal-based AI assistant that helps with software development tasks. It provides an interactive chat interface with AI capabilities, code analysis, and LSP integration to assist developers in writing, debugging, and understanding code directly from the terminal.`, Example: ` # Run in interactive mode - opencode + crush # Run with debug logging - opencode -d + crush -d # Run with debug logging in a specific directory - opencode -d -c /path/to/project + crush -d -c /path/to/project # Print version - opencode -v + crush -v # Run a single non-interactive prompt - opencode -p "Explain the use of context in Go" + crush -p "Explain the use of context in Go" # Run a single non-interactive prompt with JSON output format - opencode -p "Explain the use of context in Go" -f json + crush -p "Explain the use of context in Go" -f json `, RunE: func(cmd *cobra.Command, args []string) error { // If the help flag is set, show the help message diff --git a/cmd/schema/README.md b/cmd/schema/README.md index b67626635144a4e97b49cf6f5d86808e1a2b2fac..4876ccb4d4e8513b66a03534b015b9de77eb800d 100644 --- a/cmd/schema/README.md +++ b/cmd/schema/README.md @@ -5,7 +5,7 @@ This tool generates a JSON Schema for the OpenCode configuration file. The schem ## Usage ```bash -go run cmd/schema/main.go > opencode-schema.json +go run cmd/schema/main.go > crush-schema.json ``` This will generate a JSON Schema file that can be used to validate configuration files. @@ -24,7 +24,7 @@ The generated schema includes: You can use the generated schema in several ways: -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. +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. 2. **Validation Tools**: You can use tools like [jsonschema](https://github.com/Julian/jsonschema) to validate your configuration files against the schema. @@ -37,7 +37,7 @@ Here's an example configuration that conforms to the schema: ```json { "data": { - "directory": ".opencode" + "directory": ".crush" }, "debug": false, "providers": { diff --git a/cmd/schema/main.go b/cmd/schema/main.go index b638fb7a0d2b113304c4338779332bd6ad2d7bf9..4d2b9b8bffc93c3d653336baf5165320a90650bd 100644 --- a/cmd/schema/main.go +++ b/cmd/schema/main.go @@ -52,7 +52,7 @@ func generateSchema() map[string]any { "directory": map[string]any{ "type": "string", "description": "Directory where application data is stored", - "default": ".opencode", + "default": ".crush", }, }, "required": []string{"directory"}, @@ -89,8 +89,8 @@ func generateSchema() map[string]any { ".cursor/rules/", "CLAUDE.md", "CLAUDE.local.md", - "opencode.md", - "opencode.local.md", + "crush.md", + "crush.local.md", "OpenCode.md", "OpenCode.local.md", "OPENCODE.md", @@ -105,9 +105,9 @@ func generateSchema() map[string]any { "theme": map[string]any{ "type": "string", "description": "TUI theme name", - "default": "opencode", + "default": "crush", "enum": []string{ - "opencode", + "crush", "catppuccin", "dracula", "flexoki", diff --git a/cspell.json b/cspell.json index f59940e21add71cde463dbf18e50d40ff0c76594..afdb1e5275851972ef8d0cf2c8503fe9f2f26323 100644 --- a/cspell.json +++ b/cspell.json @@ -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"} \ No newline at end of file +{"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"} \ No newline at end of file diff --git a/install b/install index 8d394d34b930e9d9afe8c359c5a0ae52cfa00e76..975bfacd7df000156267e2948cc956af4c991565 100755 --- a/install +++ b/install @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -euo pipefail -APP=opencode +APP=crush RED='\033[0;31m' GREEN='\033[0;32m' @@ -36,7 +36,7 @@ case "$filename" in ;; esac -INSTALL_DIR=$HOME/.opencode/bin +INSTALL_DIR=$HOME/.crush/bin mkdir -p "$INSTALL_DIR" if [ -z "$requested_version" ]; then @@ -67,12 +67,12 @@ print_message() { } check_version() { - if command -v opencode >/dev/null 2>&1; then - opencode_path=$(which opencode) + if command -v crush >/dev/null 2>&1; then + crush_path=$(which crush) ## TODO: check if version is installed - # installed_version=$(opencode version) + # installed_version=$(crush version) installed_version="0.0.1" installed_version=$(echo $installed_version | awk '{print $2}') @@ -86,11 +86,11 @@ check_version() { } download_and_install() { - print_message info "Downloading ${ORANGE}opencode ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..." - mkdir -p opencodetmp && cd opencodetmp + print_message info "Downloading ${ORANGE}crush ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..." + mkdir -p crushtmp && cd crushtmp curl -# -L $url | tar xz - mv opencode $INSTALL_DIR - cd .. && rm -rf opencodetmp + mv crush $INSTALL_DIR + cd .. && rm -rf crushtmp } check_version @@ -102,9 +102,9 @@ add_to_path() { local command=$2 if [[ -w $config_file ]]; then - echo -e "\n# opencode" >> "$config_file" + echo -e "\n# crush" >> "$config_file" echo "$command" >> "$config_file" - print_message info "Successfully added ${ORANGE}opencode ${GREEN}to \$PATH in $config_file" + print_message info "Successfully added ${ORANGE}crush ${GREEN}to \$PATH in $config_file" else print_message warning "Manually add the directory to $config_file (or similar):" print_message info " $command" diff --git a/internal/config/config.go b/internal/config/config.go index 5ed55552d9d4f07c4d4e00f8d7980880d05e8a34..07e1c95fab98f84496d572f54a82406947b0589a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -97,9 +97,9 @@ type Config struct { // Application constants const ( - defaultDataDirectory = ".opencode" + defaultDataDirectory = ".crush" defaultLogLevel = "info" - appName = "opencode" + appName = "crush" MaxTokensFallbackDefault = 4096 ) @@ -110,8 +110,8 @@ var defaultContextPaths = []string{ ".cursor/rules/", "CLAUDE.md", "CLAUDE.local.md", - "opencode.md", - "opencode.local.md", + "crush.md", + "crush.local.md", "OpenCode.md", "OpenCode.local.md", "OPENCODE.md", @@ -221,7 +221,7 @@ func configureViper() { func setDefaults(debug bool) { viper.SetDefault("data.directory", defaultDataDirectory) viper.SetDefault("contextPaths", defaultContextPaths) - viper.SetDefault("tui.theme", "opencode") + viper.SetDefault("tui.theme", "crush") viper.SetDefault("autoCompact", true) // Set default shell from environment or fallback to /bin/bash diff --git a/internal/db/connect.go b/internal/db/connect.go index 3881dd34bdc16a9a893d24377eafcd1f59e7aace..ed48ddcba8fea094c815b009dcaa5ce1cc354d0c 100644 --- a/internal/db/connect.go +++ b/internal/db/connect.go @@ -23,7 +23,7 @@ func Connect() (*sql.DB, error) { if err := os.MkdirAll(dataDir, 0o700); err != nil { return nil, fmt.Errorf("failed to create data directory: %w", err) } - dbPath := filepath.Join(dataDir, "opencode.db") + dbPath := filepath.Join(dataDir, "crush.db") // Open the SQLite database db, err := sql.Open("sqlite3", dbPath) if err != nil { diff --git a/internal/fileutil/fileutil.go b/internal/fileutil/fileutil.go index 94013b7f3e27abb9e4240d62e72176d1f8576067..b9619b8ada2cf3b9df29b30cc51238bf829ebd8e 100644 --- a/internal/fileutil/fileutil.go +++ b/internal/fileutil/fileutil.go @@ -67,7 +67,7 @@ func SkipHidden(path string) bool { } commonIgnoredDirs := map[string]bool{ - ".opencode": true, + ".crush": true, "node_modules": true, "vendor": true, "dist": true, diff --git a/internal/fileutil/ls.go b/internal/fileutil/ls.go index 9ea0dfa670388f46ff339f77f03a9dd60897d2b8..9a271da25f49b48c965115ae7979c690e88bf8c1 100644 --- a/internal/fileutil/ls.go +++ b/internal/fileutil/ls.go @@ -64,7 +64,7 @@ var CommonIgnorePatterns = []string{ ".fseventsd", // OpenCode - ".opencode", + ".crush", } type DirectoryLister struct { diff --git a/internal/llm/prompt/coder.go b/internal/llm/prompt/coder.go index 085dc9bec55b2b1def04082fed66b5859c676fce..dcf3c7370f062375ee8299de71930b5f1a80b3eb 100644 --- a/internal/llm/prompt/coder.go +++ b/internal/llm/prompt/coder.go @@ -33,7 +33,7 @@ You can: - Apply patches, run commands, and manage user approvals based on policy. - Work inside a sandboxed, git-backed workspace with rollback support. - Log telemetry so sessions can be replayed or inspected later. -- More details on your functionality are available at "opencode --help" +- More details on your functionality are available at "crush --help" You 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 1. Use the available search tools to understand the codebase and the user's query. 2. Implement the solution using all tools available to you 3. 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. -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. +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. NEVER 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. diff --git a/internal/llm/provider/provider.go b/internal/llm/provider/provider.go index 558eec31059ecb068897fe09397813bbaafe6afd..dae3bc10e6dea0ddd6b6757f34c0bd247b10e33e 100644 --- a/internal/llm/provider/provider.go +++ b/internal/llm/provider/provider.go @@ -130,7 +130,7 @@ func NewProvider(providerName models.ModelProvider, opts ...ProviderClientOption clientOptions.openaiOptions = append(clientOptions.openaiOptions, WithOpenAIBaseURL("https://openrouter.ai/api/v1"), WithOpenAIExtraHeaders(map[string]string{ - "HTTP-Referer": "opencode.ai", + "HTTP-Referer": "crush.ai", "X-Title": "OpenCode", }), ) diff --git a/internal/llm/tools/bash.go b/internal/llm/tools/bash.go index 33e703cca4d559ea32d97786c191dcae49855c43..d2c467fe45dccebde8aa3ac130a488dfef9c5000 100644 --- a/internal/llm/tools/bash.go +++ b/internal/llm/tools/bash.go @@ -122,16 +122,16 @@ When the user asks you to create a new git commit, follow these steps carefully: 4. Create the commit with a message ending with: -🤖 Generated with opencode -Co-Authored-By: opencode +🤖 Generated with crush +Co-Authored-By: crush - In order to ensure good formatting, ALWAYS pass the commit message via a HEREDOC, a la this example: git commit -m "$(cat <<'EOF' Commit message here. - 🤖 Generated with opencode - Co-Authored-By: opencode + 🤖 Generated with crush + Co-Authored-By: crush EOF )" @@ -193,7 +193,7 @@ gh pr create --title "the pr title" --body "$(cat <<'EOF' ## Test plan [Checklist of TODOs for testing the pull request...] -🤖 Generated with opencode +🤖 Generated with crush EOF )" diff --git a/internal/llm/tools/fetch.go b/internal/llm/tools/fetch.go index 105733dc680ef40efb57a2ecb735af1e6b1463ea..780f22a43bae7c9ec1e077c2d5878d3aeb0284ec 100644 --- a/internal/llm/tools/fetch.go +++ b/internal/llm/tools/fetch.go @@ -152,7 +152,7 @@ func (t *fetchTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error return ToolResponse{}, fmt.Errorf("failed to create request: %w", err) } - req.Header.Set("User-Agent", "opencode/1.0") + req.Header.Set("User-Agent", "crush/1.0") resp, err := client.Do(req) if err != nil { diff --git a/internal/llm/tools/shell/shell.go b/internal/llm/tools/shell/shell.go index 0f0f88afced34a53fef34cfda83aec637ca02f5b..fffe8fcfe73894f30790c6a21be402332af21c9c 100644 --- a/internal/llm/tools/shell/shell.go +++ b/internal/llm/tools/shell/shell.go @@ -149,10 +149,10 @@ func (s *PersistentShell) execCommand(command string, timeout time.Duration, ctx } tempDir := os.TempDir() - stdoutFile := filepath.Join(tempDir, fmt.Sprintf("opencode-stdout-%d", time.Now().UnixNano())) - stderrFile := filepath.Join(tempDir, fmt.Sprintf("opencode-stderr-%d", time.Now().UnixNano())) - statusFile := filepath.Join(tempDir, fmt.Sprintf("opencode-status-%d", time.Now().UnixNano())) - cwdFile := filepath.Join(tempDir, fmt.Sprintf("opencode-cwd-%d", time.Now().UnixNano())) + stdoutFile := filepath.Join(tempDir, fmt.Sprintf("crush-stdout-%d", time.Now().UnixNano())) + stderrFile := filepath.Join(tempDir, fmt.Sprintf("crush-stderr-%d", time.Now().UnixNano())) + statusFile := filepath.Join(tempDir, fmt.Sprintf("crush-status-%d", time.Now().UnixNano())) + cwdFile := filepath.Join(tempDir, fmt.Sprintf("crush-cwd-%d", time.Now().UnixNano())) defer func() { os.Remove(stdoutFile) diff --git a/internal/llm/tools/sourcegraph.go b/internal/llm/tools/sourcegraph.go index 0d38c975fbe202a8cd16f580586795bf2213fabb..f62e6a961bed962088e0e40670a4276f16174187 100644 --- a/internal/llm/tools/sourcegraph.go +++ b/internal/llm/tools/sourcegraph.go @@ -218,7 +218,7 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse, } req.Header.Set("Content-Type", "application/json") - req.Header.Set("User-Agent", "opencode/1.0") + req.Header.Set("User-Agent", "crush/1.0") resp, err := client.Do(req) if err != nil { diff --git a/internal/logging/logger.go b/internal/logging/logger.go index 7ae2e7b87ab7f3f71811c793118c79e2a72a3bbf..9c2cfb50f33d27d52b9acb3009859f3509484253 100644 --- a/internal/logging/logger.go +++ b/internal/logging/logger.go @@ -54,7 +54,7 @@ func RecoverPanic(name string, cleanup func()) { // Create a timestamped panic log file timestamp := time.Now().Format("20060102-150405") - filename := fmt.Sprintf("opencode-panic-%s-%s.log", name, timestamp) + filename := fmt.Sprintf("crush-panic-%s-%s.log", name, timestamp) file, err := os.Create(filename) if err != nil { diff --git a/internal/tui/components/dialogs/commands/commands.go b/internal/tui/components/dialogs/commands/commands.go index 718b49599a3267151e459653fd28861db0acf24f..59b92d1ad52500cedacc9c421288207177b91cd7 100644 --- a/internal/tui/components/dialogs/commands/commands.go +++ b/internal/tui/components/dialogs/commands/commands.go @@ -233,7 +233,7 @@ func (c *commandDialogCmp) defaultCommands() []Command { 2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc. 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. - If there's already a opencode.md, improve it. + If there's already a crush.md, improve it. If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include them.` return tea.Batch( util.CmdHandler(chat.SendMsg{ diff --git a/internal/tui/components/dialogs/commands/loader.go b/internal/tui/components/dialogs/commands/loader.go index 447d7c6412c191934563f7351630d6832424846b..9f70afa3cd60342028b6d3fd00e017221c179686 100644 --- a/internal/tui/components/dialogs/commands/loader.go +++ b/internal/tui/components/dialogs/commands/loader.go @@ -56,7 +56,7 @@ func buildCommandSources(cfg *config.Config) []commandSource { // Home directory if home, err := os.UserHomeDir(); err == nil { sources = append(sources, commandSource{ - path: filepath.Join(home, ".opencode", "commands"), + path: filepath.Join(home, ".crush", "commands"), prefix: UserCommandPrefix, }) } @@ -78,7 +78,7 @@ func getXDGCommandsDir() string { } } if xdgHome != "" { - return filepath.Join(xdgHome, "opencode", "commands") + return filepath.Join(xdgHome, "crush", "commands") } return "" } diff --git a/opencode-schema.json b/opencode-schema.json index dc139fda374964b1254d5df12c42751c84d29e7a..0e60c0330b5da10cee836385067fb0bfcafe9bcc 100644 --- a/opencode-schema.json +++ b/opencode-schema.json @@ -216,8 +216,8 @@ ".cursor/rules/", "CLAUDE.md", "CLAUDE.local.md", - "opencode.md", - "opencode.local.md", + "crush.md", + "crush.local.md", "OpenCode.md", "OpenCode.local.md", "OPENCODE.md", @@ -233,7 +233,7 @@ "description": "Storage configuration", "properties": { "directory": { - "default": ".opencode", + "default": ".crush", "description": "Directory where application data is stored", "type": "string" } @@ -374,10 +374,10 @@ "description": "Terminal User Interface configuration", "properties": { "theme": { - "default": "opencode", + "default": "crush", "description": "TUI theme name", "enum": [ - "opencode", + "crush", "catppuccin", "dracula", "flexoki",