### Install Crush with Go Source: https://github.com/charmbracelet/crush/blob/main/README.md Install the latest version of Crush using Go's install command. ```bash go install github.com/charmbracelet/crush@latest ``` -------------------------------- ### Install Crush with Winget (Windows) Source: https://github.com/charmbracelet/crush/blob/main/README.md Install Crush on Windows using Winget. ```bash # Winget winget install charmbracelet.crush ``` -------------------------------- ### Install Crush with NPM Source: https://github.com/charmbracelet/crush/blob/main/README.md Install Crush globally using NPM. ```bash # NPM npm install -g @charmland/crush ``` -------------------------------- ### Add Crush Scoop Bucket and Install (Windows) Source: https://github.com/charmbracelet/crush/blob/main/README.md Add the Charm Scoop bucket and install Crush on Windows. ```bash # Scoop scoop bucket add charm https://github.com/charmbracelet/scoop-bucket.git scoop install crush ``` -------------------------------- ### Install Crush with Nix Source: https://github.com/charmbracelet/crush/blob/main/README.md Run Crush using Nix. ```bash # Nix nix run github:numtide/nix-ai-tools#crush ``` -------------------------------- ### Full MCP Configuration Example Source: https://github.com/charmbracelet/crush/blob/main/README.md Comprehensive configuration for Model Context Protocol (MCP) servers, including stdio, http, and sse transports with various options. ```json { "$schema": "https://charm.land/crush.json", "mcp": { "filesystem": { "type": "stdio", "command": "node", "args": ["/path/to/mcp-server.js"], "timeout": 120, "disabled": false, "disabled_tools": ["some-tool-name"], "env": { "NODE_ENV": "production" } }, "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/", "timeout": 120, "disabled": false, "disabled_tools": ["create_issue", "create_pull_request"], "headers": { "Authorization": "Bearer $GH_PAT" } }, "streaming-service": { "type": "sse", "url": "https://example.com/mcp/sse", "timeout": 120, "disabled": false, "headers": { "API-Key": "$(echo $API_KEY)" } } } } ``` -------------------------------- ### Add NUR Channel and Install Crush in Nix Shell Source: https://github.com/charmbracelet/crush/blob/main/README.md Add the NUR channel and use nix-shell to get Crush. ```bash # Add the NUR channel. nix-channel --add https://github.com/nix-community/NUR/archive/main.tar.gz nur nix-channel --update # Get Crush in a Nix shell. nix-shell -p '(import { pkgs = import {}; }).repos.charmbracelet.crush' ``` -------------------------------- ### Install Skills on Unix-like Systems Source: https://github.com/charmbracelet/crush/blob/main/README.md Set up a directory for Crush skills and clone the anthropics/skills repository into it. Ensure the directory structure is correctly organized for Crush to discover skills. ```bash # Unix mkdir -p ~/.config/crush/skills cd ~/.config/crush/skills git clone https://github.com/anthropics/skills.git _temp mv _temp/skills/* . && rm -rf _temp ``` -------------------------------- ### Install Crush on Debian/Ubuntu Source: https://github.com/charmbracelet/crush/blob/main/README.md Add the Charm APT repository and install Crush on Debian or Ubuntu systems. ```bash sudo mkdir -p /etc/apt/keyrings curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list sudo apt update && sudo apt install crush ``` -------------------------------- ### Install Crush with Homebrew Source: https://github.com/charmbracelet/crush/blob/main/README.md Use Homebrew to install Crush on macOS or Linux. ```bash # Homebrew brew install charmbracelet/tap/crush ``` -------------------------------- ### Install Crush with FreeBSD pkg Source: https://github.com/charmbracelet/crush/blob/main/README.md Install Crush on FreeBSD using the pkg package manager. ```bash # FreeBSD pkg install crush ``` -------------------------------- ### Install Crush on Fedora/RHEL Source: https://github.com/charmbracelet/crush/blob/main/README.md Configure the Charm YUM repository and install Crush on Fedora or RHEL systems. ```bash echo '[charm] name=Charm baseurl=https://repo.charm.sh/yum/ enabled=1 gpgcheck=1 gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo sudo yum install crush ``` -------------------------------- ### Global Hook Configuration Examples Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md For global hooks in ~/.config/crush/crush.json, use absolute paths or inline commands for 'command'. ```jsonc // Global ~/.config/crush/crush.json { "hooks": { "PreToolUse": [ { "command": "/home/you/.config/crush/hooks/no-haskell.sh" // or use an inline command: // "command": "echo '{\"decision\":\"allow\"}'" } ] } } ``` -------------------------------- ### Install Skills on Windows (PowerShell) Source: https://github.com/charmbracelet/crush/blob/main/README.md Set up a directory for Crush skills using PowerShell and clone the anthropics/skills repository. This ensures skills are available for Crush on Windows systems. ```powershell # Windows (PowerShell) mkdir -Force "$env:LOCALAPPDATA\crush\skills" cd "$env:LOCALAPPDATA\crush\skills" git clone https://github.com/anthropics/skills.git _temp mv _temp/skills/* . ; rm -r -force _temp ``` -------------------------------- ### Install Crush with AUR (Arch Linux) Source: https://github.com/charmbracelet/crush/blob/main/README.md Install Crush on Arch Linux using the AUR helper 'yay'. ```bash # Arch Linux (btw) yay -S crush-bin ``` -------------------------------- ### Hook Configuration Example Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Defines the configuration for a hook, including an optional display name, a regex to match against the tool name, the shell command to execute, and an optional timeout. ```json { // string. Optional. Friendly display name shown in the TUI. Falls back to // command when omitted. "name": "no-rm-rf", // string. Optional. Regex tested against the tool name. Omit to match all. "matcher": "^bash$", // string. Required. Shell command to run. "command": "./hooks/my-hook.sh", // number. Optional. Seconds before the hook is killed. Defaults to 30. "timeout": 10, } ``` -------------------------------- ### Configure llama.cpp Local Provider Source: https://github.com/charmbracelet/crush/blob/main/README.md Configure Crush to connect to a local llama.cpp server. This setup allows Crush to interact with models served by llama.cpp. ```json { "providers": { "llamacpp": { "name": "llama.cpp", "base_url": "http://localhost:2222", "type": "llamacpp" } } } ``` -------------------------------- ### NixOS/Home Manager Configuration for Crush via NUR Source: https://github.com/charmbracelet/crush/blob/main/README.md Example Nix flake configuration to enable Crush using NUR modules for NixOS and Home Manager. ```nix { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nur.url = "github:nix-community/NUR"; }; outputs = { self, nixpkgs, nur, ... }: { nixosConfigurations.your-hostname = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ nur.modules.nixos.default nur.repos.charmbracelet.modules.crush { programs.crush = { enable = true; settings = { providers = { openai = { id = "openai"; name = "OpenAI"; base_url = "https://api.openai.com/v1"; type = "openai"; api_key = "sk-fake123456789abcdef..."; models = [ { id = "gpt-4"; name = "GPT-4"; } ]; }; }; lsp = { go = { command = "gopls"; enabled = true; }; nix = { command = "nil"; enabled = true; }; }; options = { context_paths = [ "/etc/nixos/configuration.nix" ]; tui = { compact_mode = true; }; debug = false; }; }; }; } ]; }; }; } ``` -------------------------------- ### Process a File with jq Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/jq/SKILL.md jq can directly process files specified as arguments after the filter. This example shows how to extract keys from a `package.json` file. ```bash jq '.dependencies | keys' package.json ``` -------------------------------- ### Configure Vertex AI Platform Models Source: https://github.com/charmbracelet/crush/blob/main/README.md This JSON configuration adds specific models to your Vertex AI provider setup in Crush. Ensure VERTEXAI_PROJECT and VERTEXAI_LOCATION environment variables are set. ```json { "$schema": "https://charm.land/crush.json", "providers": { "vertexai": { "models": [ { "id": "claude-sonnet-4@20250514", "name": "VertexAI Sonnet 4", "cost_per_1m_in": 3, "cost_per_1m_out": 15, "cost_per_1m_in_cached": 3.75, "cost_per_1m_out_cached": 0.3, "context_window": 200000, "default_max_tokens": 50000, "can_reason": true, "supports_attachments": true } ] } } } ``` -------------------------------- ### JSON Input Example for Crush Hooks Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md This JSON structure represents the full context provided to a hook via standard input. It includes event details, session information, working directory, tool name, and the tool's raw input. ```json { "event": "PreToolUse", // Hook event name "session_id": "313909e", // Current session ID "cwd": "/home/user/project", // Working directory "tool_name": "bash", // The tool being called "tool_input": { "command": "rm -rf /" } // The tool's input } ``` -------------------------------- ### Build Project with Go Source: https://github.com/charmbracelet/crush/blob/main/AGENTS.md Use 'go build' to compile the project or 'go run' to compile and execute. ```bash go build . ``` ```bash go run . ``` -------------------------------- ### Run Project Tests Source: https://github.com/charmbracelet/crush/blob/main/AGENTS.md Execute all tests using 'task test' or 'go test ./...'. For a single test, specify the package and test function. ```bash task test ``` ```bash go test ./... ``` ```bash go test ./internal/llm/prompt -run TestGetContextFromPaths ``` -------------------------------- ### Block All MCP Tools Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md A simple inline command hook to block all tools whose names start with 'mcp_'. It outputs an error message and exits with code 2. ```json { "matcher": "^mcp_", "command": "echo 'MCP tools are disabled' >&2; exit 2" } ``` -------------------------------- ### Modernize and Develop Project Source: https://github.com/charmbracelet/crush/blob/main/AGENTS.md Run 'task modernize' to apply code simplifications. Use 'task dev' to run the project with profiling enabled. ```bash task modernize ``` ```bash task dev ``` -------------------------------- ### Block rm -rf in Bash (JavaScript) Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md An example of implementing the 'block rm -rf' functionality using Node.js. This hook targets the 'bash' tool and checks the command input. ```js let input = ""; process.stdin.on("data", (chunk) => (input += chunk)); process.stdin.on("end", () => { const { tool_input: toolInput } = JSON.parse(input); if (/rm\s+-[rf]{2}\s+\//.test(toolInput.command)) { process.stderr.write("Refusing to run rm -rf against root\n"); process.exit(2); } }); ``` -------------------------------- ### Customize Initialization File Name Source: https://github.com/charmbracelet/crush/blob/main/README.md Specify a custom name and location for the project context file generated during Crush initialization. This allows for flexible organization of project-specific context. ```json { "$schema": "https://charm.land/crush.json", "options": { "initialize_as": "AGENTS.md" } } ``` -------------------------------- ### Block rm -rf in Bash (Lua) Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md An example of implementing the 'block rm -rf' functionality using Lua. This hook targets the 'bash' tool and checks the command input. ```lua local input = io.read("*a") local tool_input = input:match('"command":"(.-)"') or "" if tool_input:match('rm%s+%-[rf][rf]%s+/') then io.stderr:write("Refusing to run rm -rf against root\n") os.exit(2) end ``` -------------------------------- ### General Crush Options Configuration Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Configure general Crush options, including skill paths, disabled tools/skills, TUI settings, and debugging flags. Note that certain skill paths are loaded by default. ```json { "options": { "skills_paths": ["./skills"], "disabled_tools": ["bash", "sourcegraph"], "disabled_skills": ["crush-config"], "tui": { "compact_mode": false, "diff_mode": "unified", "transparent": false }, "auto_lsp": true, "debug": false, "debug_lsp": false, "attribution": { "trailer_style": "assisted-by", "generated_with": true } } } ``` -------------------------------- ### Enable Mock Providers for Testing Source: https://github.com/charmbracelet/crush/blob/main/AGENTS.md Use mock providers to avoid API calls during testing. Ensure to reset providers and restore original mock settings after the test. ```go func TestYourFunction(t *testing.T) { // Enable mock providers for testing originalUseMock := config.UseMockProviders config.UseMockProviders = true defer func() { config.UseMockProviders = originalUseMock config.ResetProviders() }() // Reset providers to ensure fresh mock data config.ResetProviders() // Your test code here - providers will now return mock data providers := config.Providers() // ... test logic } ``` -------------------------------- ### Authenticate for Vertex AI Platform Source: https://github.com/charmbracelet/crush/blob/main/README.md Before configuring Vertex AI, authenticate your application using the Google Cloud SDK. This command sets up application-default credentials. ```bash gcloud auth application-default login ``` -------------------------------- ### LSP Server Configuration Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Configure Language Server Protocol (LSP) servers for different languages. The 'command' field is required, and 'env' can be used to set environment variables. Values are shell-expanded. ```json { "lsp": { "go": { "command": "gopls", "env": { "GOPATH": "$HOME/go" } }, "typescript": { "command": "typescript-language-server", "args": ["--stdio"] } } } ``` -------------------------------- ### Project-Level Hook Configuration Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Configure hooks in your project's crush.json. The 'command' is resolved relative to the current working directory. ```jsonc { "hooks": { "PreToolUse": [ { "name": "no-rm-rf", "matcher": "bash", "command": "./hooks/my-hot-hook.sh", "timeout": 10 } ] } } ``` -------------------------------- ### Allow Specific Tools for Execution Source: https://github.com/charmbracelet/crush/blob/main/README.md Configure a list of tools that Crush can execute without prompting for permission. Use with caution to avoid unintended executions. ```json { "$schema": "https://charm.land/crush.json", "permissions": { "allowed_tools": [ "view", "ls", "grep", "edit", "mcp_context7_get-library-doc" ] } } ``` -------------------------------- ### Configure Custom Anthropic-Compatible API Source: https://github.com/charmbracelet/crush/blob/main/README.md This JSON configuration is for setting up custom providers that are compatible with Anthropic's API. Ensure the ANTHROPIC_API_KEY environment variable is set. ```json { "$schema": "https://charm.land/crush.json", "providers": { "custom-anthropic": { "type": "anthropic", "base_url": "https://api.anthropic.com/v1", "api_key": "$ANTHROPIC_API_KEY", "extra_headers": { "anthropic-version": "2023-06-01" }, "models": [ { "id": "claude-sonnet-4-20250514", "name": "Claude Sonnet 4", "cost_per_1m_in": 3, "cost_per_1m_out": 15, "cost_per_1m_in_cached": 3.75, "cost_per_1m_out_cached": 0.3, "context_window": 200000, "default_max_tokens": 50000, "can_reason": true, "supports_attachments": true } ] } } } ``` -------------------------------- ### Lint and Format Code Source: https://github.com/charmbracelet/crush/blob/main/AGENTS.md Fix linting issues with 'task lint:fix' and format code with 'task fmt', which uses 'gofumpt'. ```bash task lint:fix ``` ```bash task fmt ``` ```bash gofumpt -w . ``` -------------------------------- ### MCP Server Configuration Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Configure Multi-Client Protocol (MCP) servers for different types (stdio, sse, http). 'type', 'command', 'args', 'url', and 'headers' are shell-expanded. Additional fields like 'env' and 'timeout' are available. ```json { "mcp": { "filesystem": { "type": "stdio", "command": "node", "args": ["/path/to/mcp-server.js"] }, "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/", "headers": { "Authorization": "Bearer $GH_PAT" } } } } ``` -------------------------------- ### Basic Crush Configuration Structure Source: https://github.com/charmbracelet/crush/blob/main/README.md This is the general structure for a Crush configuration file. It uses a JSON object to define various settings. ```json { "this-setting": { "this": "that" }, "that-setting": ["ceci", "cela"] } ``` -------------------------------- ### Configure Additional Skill Paths Source: https://github.com/charmbracelet/crush/blob/main/README.md Specify custom directories for Crush to load agent skills from, in addition to default locations. This allows for project-specific or custom skill organization. ```jsonc { "$schema": "https://charm.land/crush.json", "options": { "skills_paths": [ "~/.config/crush/skills", // Windows: "%LOCALAPPDATA%\crush\skills", "./project-skills", ], }, } ``` -------------------------------- ### Inject Context into File Writes Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Configure a hook to inject context into the model when it writes Go files. This hook reminds the user to run 'gofumpt' after edits. ```json { "hooks": { "PreToolUse": [ { "matcher": "^(edit|write|multiedit)$", "command": "./hooks/go-context.sh" } ] } } ``` -------------------------------- ### Configure Deepseek OpenAI-Compatible API Source: https://github.com/charmbracelet/crush/blob/main/README.md Use this configuration for Deepseek or other non-OpenAI providers with OpenAI-compatible APIs. Ensure the DEEPSEEK_API_KEY environment variable is set. ```json { "$schema": "https://charm.land/crush.json", "providers": { "deepseek": { "type": "openai-compat", "base_url": "https://api.deepseek.com/v1", "api_key": "$DEEPSEEK_API_KEY", "models": [ { "id": "deepseek-chat", "name": "Deepseek V3", "cost_per_1m_in": 0.27, "cost_per_1m_out": 1.1, "cost_per_1m_in_cached": 0.07, "cost_per_1m_out_cached": 1.1, "context_window": 64000, "default_max_tokens": 5000 } ] } } } ``` -------------------------------- ### Configure Crush Hooks Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-hooks/SKILL.md Define hooks in `crush.json` to intercept `PreToolUse` events. Specify a regex matcher for tool names, the shell command to execute, and an optional timeout. ```jsonc { "hooks": { "PreToolUse": [ { "matcher": "^bash$", // regex against tool name (optional; omit to match all) "command": "./hooks/my-hook.sh", // required: shell command to run "timeout": 10 // optional: seconds, default 30 } ] } } ``` -------------------------------- ### Configure Allowed Tools for Crush Skills Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Specify which tools are permitted for use by Crush skills. This JSON configuration restricts the execution of external commands. ```json { "permissions": { "allowed_tools": ["view", "ls", "grep", "edit"] } } ``` -------------------------------- ### Basic Crush Configuration Structure Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md This is the fundamental structure of a crush.json configuration file. The $schema property is optional but enables IDE autocompletion. ```json { "$schema": "https://charm.land/crush.json", "models": {}, "providers": {}, "mcp": {}, "lsp": {}, "hooks": {}, "options": {}, "permissions": {}, "tools": {} } ``` -------------------------------- ### Override Theme Colors in Styles Source: https://github.com/charmbracelet/crush/blob/main/AGENTS.md When a style genuinely needs a color that doesn't fit the token model, keep `quickStyle` on the closest semantic token and override only the differing colors in the theme function. ```go func CharmtonePantera() Styles { s := quickStyle(quickStyleOpts{ /* palette */ }) // Override only the colors that differ from the token defaults. s.Editor.PromptBangIconFocused = s.Editor.PromptBangIconFocused. Foreground(charmtone.Salt). Background(charmtone.Hazy) return s } ``` -------------------------------- ### Configure PreToolUse Hooks Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Define `PreToolUse` hooks in the `hooks` section of the configuration. Each hook requires a `command` and can optionally have a `matcher` regex and `timeout`. ```json { "hooks": { "PreToolUse": [ { "matcher": "^(edit|write|multiedit)$", "command": ".crush/hooks/protect-files.sh" }, { "matcher": "^bash$", "command": ".crush/hooks/no-haskell.sh" } ] } } ``` -------------------------------- ### Block Tool Call with Exit Code and Stderr Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Use a non-zero exit code (e.g., 2) and print a reason to stderr to block a tool call. This is suitable for simple denial messages. ```bash # Here, error code 2 blocks the tool, using stderr as the reason: if some_bad_condition; then echo "Blocked: reason here" >&2 exit 2 fi ``` -------------------------------- ### Required Environment Variable Configuration Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Demonstrates how to use shell expansion to ensure a required environment variable is set. If CODEBERG_TOKEN is not set, Crush will fail loudly at load time with the specified message. ```json { "api_key": "${CODEBERG_TOKEN:?set CODEBERG_TOKEN}" } ``` -------------------------------- ### Configure Model Selection Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Define model aliases for different tasks, specifying the model name, provider, and optional parameters like max tokens. Only 'model' and 'provider' are strictly required. ```json { "models": { "large": { "model": "claude-sonnet-4-20250514", "provider": "anthropic", "max_tokens": 16384 }, "small": { "model": "claude-haiku-4-20250514", "provider": "anthropic" } } } ``` -------------------------------- ### Customize Global Context Paths Source: https://github.com/charmbracelet/crush/blob/main/README.md Specify custom paths for global context files like CRUSH.md and AGENTS.md. Supports individual files and recursively loading .md files from directories. ```jsonc { "$schema": "https://charm.land/crush.json", "options": { "global_context_paths": [ "~/path/to/custom/context/file.md", "/full/path/to/folder/of/files/" // recursively load all .md files in folder ] } } ``` -------------------------------- ### View Crush Logs Source: https://github.com/charmbracelet/crush/blob/main/README.md Print the last 1000 lines of Crush logs. Use the --tail flag to specify a different number of lines. ```bash crush logs ``` ```bash crush logs --tail 500 ``` ```bash crush logs --follow ``` -------------------------------- ### LSP Configuration for Crush Source: https://github.com/charmbracelet/crush/blob/main/README.md Defines Language Server Protocol (LSP) configurations for Crush, specifying commands and environment variables for different languages. ```json { "$schema": "https://charm.land/crush.json", "lsp": { "go": { "command": "gopls", "env": { "GOTOOLCHAIN": "go1.24.5" } }, "typescript": { "command": "typescript-language-server", "args": ["--stdio"] }, "nix": { "command": "nil" } } } ``` -------------------------------- ### Configure PreToolUse Hook in crush.json Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Add this configuration to your project-level crush.json to intercept 'PreToolUse' events. It specifies a matcher for the 'bash' tool and the command to execute, './no-haskell.sh'. ```jsonc { // As expected, hooks go in a "hooks" object. "hooks": { // PreToolUse is an event that fires before a tool is used. "PreToolUse": [ { // What tool do we want to hook into? In this case, Bash, because it // runs the stuff we wanna block. "matcher": "^bash$", // The path to our actual hook script. "command": "./no-haskell.sh", }, ], }, } ``` -------------------------------- ### Construct JSON with Null Input Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/jq/SKILL.md Use the `-n` flag with `--arg` to construct JSON output when there is no input JSON to process. This is useful for creating configuration objects or simple JSON messages. ```bash jq -n --arg msg hello '{"message": $msg}' ``` -------------------------------- ### Bash Script for JSON Hook Output Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md A complete bash script demonstrating how to read input, process it, and generate the required JSON output for a Crush hook. ```bash #!/usr/bin/env bash # Example: rewrite a bash command using RTK read -r input original_cmd=$(echo "$input" | jq -r '.tool_input.command') rewritten=$(secret-scrubber rewrite "$original_cmd") cat <> ./tools.log" } ``` -------------------------------- ### Crush Hook Input - JSON Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-hooks/SKILL.md The input to a Crush hook is provided as JSON on stdin, containing details about the event, session, tool, and input. ```json { "event": "PreToolUse", "session_id": "313909e", "cwd": "/home/user/project", "tool_name": "bash", "tool_input": {"command": "rm -rf /"} } ``` -------------------------------- ### Configure Git Attribution Settings Source: https://github.com/charmbracelet/crush/blob/main/README.md Customize how Crush attributes Git commits and pull requests it creates. Control the trailer style and whether a 'generated with' line is included. ```json { "$schema": "https://charm.land/crush.json", "options": { "attribution": { "trailer_style": "co-authored-by", "generated_with": true } } } ``` -------------------------------- ### Bash Script to Inject Go Formatting Context Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md A bash script that checks if the file path ends with '.go'. If it does, it outputs context reminding the user about Go formatting; otherwise, it outputs empty JSON. ```bash #!/usr/bin/env bash # Remind the model about Go formatting when editing .go files. # Emit context only; stay silent on `decision` so the normal permission # prompt still runs for edits/writes. if [[ "$CRUSH_TOOL_INPUT_FILE_PATH" == *.go ]]; then echo '{"context": "Remember: run gofumpt after editing Go files."}' else echo '{}' fi ``` -------------------------------- ### Hook Configuration Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Configuration structure for each hook entry within a hooks. array. ```APIDOC ## Hook config Each entry under a `hooks.` array: ```jsonc { // string. Optional. Friendly display name shown in the TUI. Falls back to // command when omitted. "name": "no-rm-rf", // string. Optional. Regex tested against the tool name. Omit to match all. "matcher": "^bash$", // string. Required. Shell command to run. "command": "./hooks/my-hook.sh", // number. Optional. Seconds before the hook is killed. Defaults to 30. "timeout": 10, } ``` ``` -------------------------------- ### Configure Custom API Provider Source: https://github.com/charmbracelet/crush/blob/main/internal/skills/builtin/crush-config/SKILL.md Add a custom provider by specifying its type, base URL, API key, and model details. The 'type' field is mandatory and can be one of several predefined values or a local provider type. ```json { "providers": { "deepseek": { "type": "openai-compat", "base_url": "https://api.deepseek.com/v1", "api_key": "$DEEPSEEK_API_KEY", "models": [ { "id": "deepseek-chat", "name": "Deepseek V3", "context_window": 64000 } ] } } } ``` -------------------------------- ### JSON Output for Tool Call Control Source: https://github.com/charmbracelet/crush/blob/main/docs/hooks/README.md Provide structured JSON on stdout for more control, including allowing, denying, halting, adding context, or updating input. Exit code 0 indicates success. ```jsonc { "version": 1, // Output envelope version. Optional; defaults to 1. "decision": "allow", // "allow", "deny", or null. Omit for no opinion. "halt": false, // If true, halts the turn entirely. "reason": "LGTM", // Shown when denying or halting. "context": "Scrubbed secrets", // String or array of strings. Appended to what the model sees. "updated_input": { "command": "…" } // Shallow-merged into the tool's input before execution. } ```