.crushrc is here!
Hey! Hope everybody had a great week. We were pretty productive at Charm and we're releasing some cool stuff today.
Bash configuration! (.crushrc)
Yep, .crushrc has come! You existing JSON config still works, but we just started migrating to something a lot more flexible!
An example on why this is cool: if you manage Crush config in a dotfiles repo, you can still have machine-specific overrides by using source to call a separate file that will be in your .gitignore. I'm sure there are many other use cases.
To read the full documentation on this, read this document.
See a snipped so you have an idea on how it looks:
# Add Ollama.
provider add ollama --type ollama --base-url "http://localhost:11434/v1"
# Register a model on Ollama.
model add ollama/llama3.3 --name "Llama 3.3" --context-window 128000
# Auto-approve some tools.
permissions allow view edit
# Add an MCP server
mcp add github \
--type http \
--url "https://api.githubcopilot.com/mcp/" \
--header Authorization "Bearer $GITHUB_TOKEN"
# Load some extra config
source "$XDG_CONFIG_HOME/squid-config.sh"
# Change config based on the machine you're on.
if [[ $HOSTNAME == "babysquid" ]]; then
option skill-path "$HOME/squid-skills"
fiWant to give feedback? Join the #crush channel on Discord.
Better AWS Bedrock SSO support
@jan-xyz did a great job bringing this one to life!
When using AWS Bedrock via SSO, tokens expire with time and need to be refreshed. Crush now has a proper configuration and UX for authenticating, and it will appear whenever tokens need to be refreshed.
To read more about it, see #2886.
More reliable Agent Fetch
@sven2718 contributed with better retries in searches when they don't work in the first try. Searches will be more reliable now, specially when doing many in a short period of time.
Fix for Fable 5
@sven2718 also contributed with a fix for Fable 5. When Anthropic decides to reject your prompt for security reasons, we'll now a proper error message in Crush. Before, Crush would just stop without giving context on why.
Crush now compiles on IlluminOS
Never heard of IllumiOS? Neither none of us at Charm, but @timotheosh adjusted the code to ensure it compiles there now!
Go compiles to many environments, and it's always fun to see Crush working on more operating systems! By the way, do you know you can use Crush on Android? 🤖
Enhanced MCP OAuth
In the last release, we shipped support for OAuth authentication for MCPs.
@BrunoKrugel did a few fixes to make more MCPs that require OAuth work as expected.
Agentic fixes
Quite a few fixes were made to Crush as an agent as well. Some of these were made on Fantasy and brought to Crush.
New Hyper models
Not less important, we keep bringing updates to Hyper, which is more stable than ever and has Minimax M3 and Qwen3.7-Flash avalable now.
A lot happened this week! We hope you enjoy, and Keep Crushing ™️!
Charm
Changelog
New!
- 9e3ed61: feat(bedrock): retry the turn automatically after AWS SSO re-auth (@jan-xyz)
- 7810d03: feat(config): apply top-level env vars on startup (@jan-xyz)
- 155072b: feat(noninteractive): make the spinner text use terminal default (@taciturnaxolotl)
- 1c07454: feat(oauth): give the browser redirect a real landing page (@taciturnaxolotl)
- c741463: feat: add "option reset" to wipe shell config list options (@meowgorithm)
- 987ba71: feat: add crush.sh discovery and loading (@meowgorithm)
- 528d837: feat: add permissions deny to hide tools from the agent (@meowgorithm)
- a5156e6: feat: add provider-model builtin for defining provider models (@meowgorithm)
- 3f54c0e: feat: add shell config builtins and ConfigBuilder infrastructure (@meowgorithm)
- c2b8f16: feat: add structured logging to shell config builtins (@meowgorithm)
- 9d31a1a: feat: add verb-first hook add/remove shell config commands (@meowgorithm)
- eea3bf7: feat: add verb-first lsp add/remove shell config commands (@meowgorithm)
- 9a3cdbf: feat: add verb-first mcp add/remove shell config commands (@meowgorithm)
- 52e041c: feat: clarify model pricing flags in crushrc (@meowgorithm)
- c6fb635: feat: configure attribution from crushrc (@meowgorithm)
- e99b8d6: feat: expose CRUSH_VERSION to shell config scripts (@meowgorithm)
- 0b58461: feat: expose remaining advanced config through crushrc (@meowgorithm)
- 8bf07da: feat: make permissions use verb-first allow subcommand (@meowgorithm)
- 650bf3c: feat: rename shell config to crushrc with local .crushrc override (@meowgorithm)
- 479da0f: feat: verb-first provider and model shell config commands (@meowgorithm)
Fixed
- 5e1cd7e: (fix: fable) surface model refusals in the TUI instead of silently stopping work (#3453) (@sven2718)
- 63dc1f0: fix(auth): stop parallel sessions from invalidating each other's login (@taciturnaxolotl)
- 2161989: fix(config): capture rollback snapshot before configureProviders (@taciturnaxolotl)
- 20e4dbc: fix(config): only warn when JSON and crushrc keys actually conflict (@taciturnaxolotl)
- 4dd4442: fix(config): retry transient Windows rename failures in atomicWriteFi… (#3469) (@joestump-agent)
- c7a5999: fix(config): track all discovered config paths for staleness (@taciturnaxolotl)
- ecdc6ed: fix(config): validate crushrc JSON output, skip empty config paths (@taciturnaxolotl)
- b679ba1: fix(edit): auto-correct whitespace mismatches in edit tool (@taciturnaxolotl)
- 677046d: fix(illumos): support building and running crush" (#3422) (@timotheosh)
- 560986c: fix(mcp): MCP server loading in server-client mode (@meowgorithm)
- 2ca5a8c: fix(mcp): normalize oauth metadata redirects (#3415) (@BrunoKrugel)
- e68041a: fix(mcp): pin go-sdk to main for protocol version header fix (#3421) (@taciturnaxolotl)
- c3fd60e: fix(mcp): remove orphaned tokens from oauths MCP (#3418) (@BrunoKrugel)
- 3a71bdf: fix(noninteractive): don't block non interactive mode on session title (@taciturnaxolotl)
- 954deae: fix(server): deliver permission and question events reliably to clients (@taciturnaxolotl)
- 359c13f: fix(shellconfig): assert section/childMap don't overwrite non-map values (@taciturnaxolotl)
- a45ab25: fix(shellconfig): bound crushrc execution with context and timeout (@taciturnaxolotl)
- f14e773: fix(shellconfig): dedup model add, document optionSpecs, pin deny target (@taciturnaxolotl)
- de67123: fix(tools): surface DuckDuckGo rate limiting instead of empty results (@sven2718)
- 80ce583: fix(ui): prevent double spinner on session reload after kill (#3457) (@taciturnaxolotl)
- b0c8c24: fix: accept mixed-case booleans in shell config (@meowgorithm)
- f13f8eb: fix: discover global crush.sh, not just crush.json (@meowgorithm)
- 601f7f7: fix: make crushrc source test pass on Windows (@meowgorithm)
- 7d8e93f: fix: never execute crushrc from machine data directories (@meowgorithm)
- ad70935: fix: resolve short session IDs in local 'crush run --session' (#3460) (@taciturnaxolotl)
- 884391f: fix: stop long thinking blocks from re-rendering the entire document every frame (#3454) (@taciturnaxolotl)
Docs
- 6fc7800: docs(config): add notes on future state migration, update readme/docs (@meowgorithm)
- d8cae42: docs(config): add windows paths, copyedits (@meowgorithm)
- 77444e4: docs(config): make documentation more human (@meowgorithm)
- 0813dcb: docs(crushrc): note that empty headers are dropped from requests (@meowgorithm)
- da35cd7: docs(readme): improve flow of configuration section a bit (@meowgorithm)
- 874c0af: docs(readme): update readme per bash-based config (@meowgorithm)
- f02ffbc: docs(ui): capture dialog rendering and chat perf rules (@taciturnaxolotl)
- 6f9b90c: docs: add config guide and future-work notes (@meowgorithm)
- 6421a2b: docs: default crush-config skill to the crush.sh format (@meowgorithm)
- 810168b: docs: document aws_auth_refresh and top-level env config (@taciturnaxolotl)
- 5d8af19: docs: finish crushrc examples and option help (@meowgorithm)
- 3c736be: docs: fix typos, grammar, and document deny-wins precedence (@taciturnaxolotl)
- f8c83fb: docs: fix version typo and clarify config trust wording (@meowgorithm)
- 5e735ec: docs: lead README configuration with the crush.sh format (@meowgorithm)
- e3dee0b: docs: note the deferred visible-but-always-denied tool state (@meowgorithm)
- 7b8f59f: docs: present crushrc commands as CLI-style help (@meowgorithm)
- b55a092: docs: update AGENTS.md with Bash config format (@meowgorithm)
- 812dc09: docs: use a local Ollama example in the config quick-start (@meowgorithm)
Other stuff
- 5b88f46: bench(config): add crushrc load benchmark (@taciturnaxolotl)
- 0e7db4a: chore(crushrc): drop deadcode (@meowgorithm)
- 7aef231: chore(crushrc): log conflicting keys when json and crushrc compete (@meowgorithm)
- 38f5d98: chore: auto-update files (@charmcli)
- d15f793: chore: auto-update files (@charmcli)
- 100c8bd: chore: auto-update files (@charmcli)
- aa57f56: chore: auto-update files (@charmcli)
- abceac2: chore: auto-update files (@charmcli)
- f4ff2ea: chore: bump fantasy to v0.39.0 (#3470) (@taciturnaxolotl)
- b83944c: chore: bump mcp sdk to 1.7.0 (#3447) (@taciturnaxolotl)
- 618a118: chore: format (@taciturnaxolotl)
- def12cc: chore: gufumpt (@andreynering)
- 6785e86: chore: merge main into crushrc (@meowgorithm)
- 15d2e1a: chore: regen golden files (@taciturnaxolotl)
- 35d82d0: chore: regenerate swagger docs (@taciturnaxolotl)
- 92d6998: refactor(shell): unify jq into the builtin registry (@taciturnaxolotl)
- 5d082a1: refactor(shellconfig): collapse option type system into one table (@taciturnaxolotl)
- 7303e15: refactor(shellconfig): replace copy-pasted flag loops with declarative engine (@taciturnaxolotl)
- 2a89bca: refactor(shellconfig): unify flagInt/flagInt64, make boolTrue a flagKind, checked assertions (@taciturnaxolotl)
- 6a6b215: refactor: build shell config imperatively instead of via JSON fragments (@meowgorithm)
- d8e0e73: refactor: make list option keys singular (@meowgorithm)
- 84f5b9c: refactor: make permissions deny the only tool-blocking command (@meowgorithm)
- 3e176af: refactor: rename provider/model unset to remove (alias rm) (@meowgorithm)
- 380c219: refactor: simplify shell config option booleans (@meowgorithm)
- 6c043eb: refactor: unify notification config under a single notifications key (@meowgorithm)
- 196dcf6: refactor: use positional provider ID for provider-model, rename options to option (@meowgorithm)
Verifying the artifacts
First, download the checksums.txt file and the checksums.txt.sigstore.json file files, for example, with wget:
wget 'https://github.com/charmbracelet/crush/releases/download/v0.88.0/checksums.txt'
wget 'https://github.com/charmbracelet/crush/releases/download/v0.88.0/checksums.txt.sigstore.json'Then, verify it using cosign:
cosign verify-blob \
--certificate-identity 'https://github.com/charmbracelet/meta/.github/workflows/goreleaser.yml@refs/heads/main' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle 'checksums.txt.sigstore.json' \
./checksums.txtIf the output is Verified OK, you can safely use it to verify the checksums of other artifacts you downloaded from the release using sha256sum:
sha256sum --ignore-missing -c checksums.txtDone! You artifacts are now verified!
Thoughts? Questions? We love hearing from you. Feel free to reach out on X, Discord, Slack, The Fediverse, Bluesky.