Catwalk v3, hooks!
A big one! Crush now runs on Catwalk v3, hooks can see every part of a run, and editors that host Crush get a whole new set of tools to feel right at home.
Small overview of Catwalk v3:
Crush now speaks Catwalk v3. Provider type describes the API format a provider uses, not who made it:
completions: OpenAI-compatible APIsresponses: OpenAI, or anything routed through itmessages: Anthropic-compatible APIs
Your config is migrated automatically when it loads, so openai, openai-compat and anthropic keep working. No edits needed.
The provider add and model add flags follow along:
crush provider add deepseek \
--type completions \
--base-url "https://api.deepseek.com/v1" \
--api-key "$DEEPSEEK_API_KEY"
crush model add deepseek/deepseek-chat --thinking toggleable --max-attachments 5--can-reasonis now--thinking always|never|toggleable--max-attachments Nis new- Reasoning levels show friendly names in the picker, like "X-High"
Hooks, everywhere 🪝
Hooks are no longer just about tools. They can now follow the whole run: sessions, turns, permissions and more!
Hooks are now checked against the list of known events, so a typo gets caught early. The docs cover each event and how it lines up with Claude Code.
Client/server mode
If you build something that runs Crush inside it, this release is for you:
- Host themes: the host app can theme the TUI over the server API, so Crush matches your applications.
- Host context: the host can tell Crush what's in view, like open files, and those files appear in completions.
- Append to the next prompt: clients can add text the agent reads with the next prompt, without starting a run or cluttering the chat.
- Shared viewing: clients can see which session other clients are looking at.
- Piped permissions: set
CRUSH_PERMISSIONS_PIPED=1and the host answers permission prompts, so you aren't asked twice. http://addresses work as an alias fortcp://when starting the server.
Steadier server
SIGHUPnow reloads the config instead of stopping the server.- Closing the terminal or stopping Crush through a service manager now shuts down gracefully, so work in progress is saved instead of left looking stuck.
That's all for now!
Charm XX 💫
Thoughts? Questions? We love hearing from you. Feel free to reach out on X, Discord, Slack, The Fediverse, Bluesky.
Changelog
New!
- 9dac45b: feat(config): declare the hook event list and validate hooks against it (@taciturnaxolotl)
- bdc53ce: feat(hooks): add PostToolUse and PostToolUseFailure (@taciturnaxolotl)
- 48c0224: feat(hooks): add session, turn, permission and compaction lifecycle hooks (@taciturnaxolotl)
- 27cb41b: feat(permission): tell subscribers when a prompt is cancelled (@taciturnaxolotl)
- a0f462f: feat(server): host context (#4148) (@andrinoff)
- 94592ce: feat(server): let client append to next prompt (#4176) (@andrinoff)
- aae2ee2: feat(server): reload config on SIGHUP instead of stopping (@taciturnaxolotl)
- 52dd976: feat(server): tell clients which session other clients view (#4178) (@andrinoff)
- a2c8a95: feat: Catwalk v3 (#3829) (@andrinoff)
- 3349824: feat: allow a host application theme the TUI over server API (#4127) (@andrinoff)
Fixed
- 451bedc: fix(config): keep tests from rewriting the real global config (@taciturnaxolotl)
- 0e989d2: fix(server): preserve work in progress when Crush is told to quit (@taciturnaxolotl)
- 21dd748: fix(tools): stop tool failures from ending the agent turn (#4143) (@andreynering)
- eded979: fix(ui): drop the dot between git branch and path in header (@taciturnaxolotl)
- 685274b: fix(ui): give the thinking spinner label its own color (@taciturnaxolotl)
- 3629f66: fix(ui): keep forked child processes from writing over the TUI (@taciturnaxolotl)
- a945ccf: fix(ui): stop the first prompt in a new session from duplicating itself (@taciturnaxolotl)
- 3538c72: fix(ui): stop the yolo banner from inverting its meaning when truncated (@taciturnaxolotl)
- ebf0e55: fix: add a flag to not show permissions (#4153) (@andrinoff)
Docs
- 6c3ce0c: docs(hooks): document the lifecycle events and Claude Code compatibility (@taciturnaxolotl)
- 57f5901: docs(tools): stop background jobs from being waited on immediately (@taciturnaxolotl)
Other stuff
- 82c0199: chore: auto-update files (@charmcli)
- a94ff94: chore: auto-update files (@charmcli)
- 6366afc: chore: auto-update files (@charmcli)
- 82b035a: chore: bump catwalk (@andrinoff)
- 070e189: chore: regenerate golden files (@taciturnaxolotl)
- 3e7d94e: fix(llama.cpp): double /v1 in model fetching (#4137) (@moul)
- 40f5782: refactor(hooks): run every event through one Event and one Runner (@taciturnaxolotl)
- 81e41ae: server: support http:// as a tcp:// alias (@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.99.0/checksums.txt'
wget 'https://github.com/charmbracelet/crush/releases/download/v0.99.0/checksums.txt.sigstore.json'Then, verify it using cosign:
cosign verify-blob \
--certificate-identity-regexp '^https://github.com/charmbracelet/crush/\.github/workflows/(release|nightly)\.yml@' \
--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.