- AI 应用
- 代码智能体
- 交互助手
- CLI
- MCP Clients
- 人工智能
【免费下载链接】crush
Glamourous agentic coding for all 💘
Crush(charmbracelet/crush)是一个 "Glamourous agentic coding" 命令行 AI 编程助手。它放弃了传统 JSON 配置文件,转而使用一套Crush 专属的 Bash 内建命令(provider、model、mcp、lsp、hook、permissions、option)来驱动配置,全局配置默认位于 Unix 系系统的~/.config/crush/crushrc与 Windows 的%USERPROFILE%\.config\crush\crushrc。这份指南以仓库中的 docs/config/README.md 为主体,结合 internal/shellconfig 的源码实现,完整讲解 crushrc 的定位、加载机制、命令参考、配置优先级与安全边界,读完你就能用一段 Bash 脚本完成"添加 Ollama 提供商、注册模型、自动放行工具、挂载 MCP 服务器"等全部日常配置,并理解底层是如何把 Bash 转成配置的。
为什么 Crush 用 Bash 而不是 JSON 做配置
文档开篇就给出了两个核心理由,这也是理解整个配置体系的关键:
- Crush 内置了一等公民的 Bash 解释器,条件判断、变量展开、函数、循环这些能力"免费"获得,无需自研一套配置语言;
- Crush 需要能自己配置自己:基于命令行的配置让用户和 Agent 使用同一套工具——你手敲的每一行配置命令,Agent 也能通过
bash工具执行,两者行为完全一致。
因此crushrc的工作方式与.bashrc完全一致:Crush 启动时执行它,脚本内的内建命令逐步"构建"出最终配置。JSON 配置(crush.json)仍然受支持但已被标记为deprecated,短期内不会移除,但新功能只会加到 Bash 配置上,详见后文 Legacy JSON。
一个最小可用的crushrc长这样:
# 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"既然是 Bash,你就能使用逻辑分支、source引入其他文件等一切 shell 能力:
# Change config based on the machine you're on. if [[ $HOSTNAME == "babysquid" ]]; then option skill-path "$HOME/squid-skills" fi # Load some extra config source "$XDG_CONFIG_HOME/squid-config.sh" # Get API keys from your password manager. provider add my-secret-provider \ --type openai-compat \ --base-url "https://api.example.com/v1" \ --api-key "$(op read my-secret-key)"版本兼容:用$CRUSH_VERSION做特性探测
配置 API 的稳定性是 Crush 非常重视的承诺。文档明确表示"不破坏配置 API 对我们来说非常重要",同时提供了针对特定版本做条件配置的手段:加载crushrc时,Crush 会把当前版本号以CRUSH_VERSION环境变量导出到脚本中。
if [[ $CRUSH_VERSION == "0.85.*" ]]; then option debug true fi在源码中可以看到这个变量的注入位置:internal/shellconfig/load.go 中的LoadShellConfig会把"CRUSH_VERSION="+version.Version追加进脚本环境;配套的配置技能文档 internal/skills/builtin/crush-config/SKILL.md 还补充了细节:本地开发构建时该值就是字面量devel,因此可以用[[ "$CRUSH_VERSION" != devel ]]判断是否为发布版本。
安全边界:crushrc 是受信任文件
与crush.json一样,crushrc是受信任文件:它以你的 shell 权限在 UI 出现之前运行。因此文档强调:谨慎保护它,不要下载未经审阅的随机配置,也不要在未读过配置的目录里启动 Crush。这一点在 internal/skills/builtin/crush-config/SKILL.md 的 Security note 中也有完全一致的表述——两种格式都是可信代码,crush.json中的$(...)也会在加载时执行。
配置在哪里:查找顺序与优先级
Crush 按以下位置查找配置,数字越小优先级越高:
| 优先级 | Unix-like | Windows |
|---|---|---|
| 1 | ./.crushrc | .\.crushrc |
| 2 | ./crushrc | .\crushrc |
| 3 | $XDG_CONFIG_HOME/crush/crushrc | %XDG_CONFIG_HOME%\crush\crushrc |
Legacy JSON 则在上述同一目录下使用.crush.json/crush.json。所有找到的配置全部合并:项目配置覆盖全局配置;同一目录下crushrc覆盖 JSON;如果某个目录同时存在两种格式,它们会合并且 Crush 会打印一条警告。
数据目录(Unix 系的~/.local/share/crush、Windows 的%LOCALAPPDATA%\crush)存放的是机器持有的 JSON 状态,Crush 不会从这些位置发现或执行crushrc。同时 Crush 也会在$XDG_DATA_HOME/crush(Windows 为%LOCALAPPDATA%\crush)存放应用状态数据,这些是运行时状态,不应手工编辑。
从源码层面看,查找逻辑在 internal/config/load.go 的lookupConfigs中实现:搜索从当前工作目录出发向上回溯,在 git 工作树根部停止(由projectBoundary/worktreeRoot决定),避免误拾取项目上层的无关配置文件。加载时若同一目录同时出现 JSON 与crushrc且顶层键有重叠,loadFromConfigPaths会通过slog.Warn输出冲突警告。crushrc 的执行会被 30 秒超时约束(loadTimeout常量),防止卡死的脚本阻塞整个配置存储的写锁。
命令参考:七个配置内建命令
下面各节读起来像 CLI help。实体类命令(provider、model、mcp、lsp、hook)用add创建或更新对象,用remove(别名rm)删除;布尔值接受true/false/1/0/yes/no,大小写不敏感(见 internal/shellconfig/options.go 中parseBool的实现)。
Available Commands: provider Manage model providers model Manage models and model selection mcp Manage MCP servers lsp Manage language servers hook Manage hooks permissions Configure tool permissions option Configure general Crush behavior这七个命令正是 internal/shellconfig/register.go 中注册的全部内建命令。值得注意的实现细节是:这些内建命令通过 shell 上下文中的ConfigBuilder开关生效——configBuilderFromCtx返回 nil(即普通bash工具执行场景)时,命令会直接静默返回(no-op)。这正是 docs/config/FUTURE.md 中"实时配置"规划所依赖的机制:未来把实时 sink 挂到 bash 工具上下文,这些命令就能在会话中即时生效。
provider:管理模型提供商
Usage: provider [command] Available Commands: add Add or update a provider remove Remove a provider and its custom models rm Alias for removeprovider add
添加提供商,或更新同一 ID 的现有提供商(重复调用同一<id>会合并更新)。
Usage: provider add <id> [flags] Flags: --name string display name --type string provider type (openai, openai-compat, anthropic, ollama, …) --api-key string API key --base-url string API base URL --disable bool disable without removing --flat-rate bool use flat-rate billing --discover-models bool auto-discover and merge provider models --system-prompt-prefix string text prepended to the system prompt --extra-header key value add an HTTP header (repeatable) --extra-body JSON merge a JSON object into request bodies --provider-options JSON merge a provider-specific JSON objectprovider add deepseek \ --type openai-compat \ --base-url "https://api.deepseek.com/v1" \ --api-key "${DEEPSEEK_API_KEY:?set DEEPSEEK_API_KEY}"${VAR:?message}是 Bash 的强制展开语法:变量未设置时脚本立即报错退出——这正是文档推荐把它用在 API key 上的原因。在源码 internal/shellconfig/provider.go 中可以看到providerAddFlags表格与上述 flags 一一对应,JSON 字段映射关系清晰(如--api-key→api_key、--extra-header→extra_headers)。
环境变量门控的 Header 是安全的:解析结果为空字符串的 header(未设置的$VAR、输出为空的$(...)、或字面量"")会被从出站请求中丢弃。这使得如下写法完全安全:
provider add openai \ --extra-header OpenAI-Organization "$OPENAI_ORG_ID"若OPENAI_ORG_ID未设置,该 header 只是不被发送而已。这个"header 空值即丢弃"的契约在 internal/config/load.go 的configureProviders中有完整实现:resolver.ResolveValue失败会中止加载并给出清晰报错,而解析为空则直接delete。
provider remove
删除提供商及其注册的所有自定义模型。
Usage: provider remove <id> provider rm <id>model:管理模型与大小模型槽位
模型引用使用与crush models输出一致的<provider>/<id>形式。large是主编码模型,small用于摘要等轻量任务。
Usage: model [command] Available Commands: add Register a custom model on an existing provider remove Remove a custom model rm Alias for remove large Set or print the large model small Set or print the small modelmodel add
在已存在的提供商上注册自定义模型。
Usage: model add <provider>/<id> [flags] Flags: --name string display name --context-window int context window in tokens --default-max-tokens int default maximum output tokens --can-reason bool model supports reasoning --supports-images bool model accepts image input --price-input float input price per 1M tokens --price-output float output price per 1M tokens --price-cache-create float cache-creation price per 1M tokens --price-cache-hit float cache-hit price per 1M tokens --reasoning-effort string low, medium, or highmodel remove
Usage: model remove <provider>/<id> model rm <provider>/<id>model large/model small
设置大/小模型槽位;不带模型参数时打印当前选择(可在$(model large)中复用)。
Usage: model large [<provider>/<id>] [flags] model small [<provider>/<id>] [flags] Flags: --think enable thinking mode --reasoning-effort string low, medium, or high --max-tokens int maximum output tokens --temperature float sampling temperature --top-p float top-p sampling (0–1) --top-k int top-k sampling --frequency-penalty float frequency penalty --presence-penalty float presence penalty --provider-options JSON merge a provider-specific JSON objectmodel large openai/gpt-4o --think echo "coding with: $(model large)" # prints: openai/gpt-4o这些采样参数最终在 internal/config/load.go 的resolveSelectedModels中被逐项应用到SelectedModel:若用户配置的模型 ID 在提供商目录中不存在,会回退到默认模型并标记LargeFallback/SmallFallback,同时把纠正结果持久化到首选模型字段。
mcp:管理 Model Context Protocol 服务器
Usage: mcp [command] Available Commands: add Add or update an MCP server remove Remove an MCP server rm Alias for removemcp add
添加 MCP 服务器,或更新同名服务器。
Usage: mcp add <name> [flags] Flags: --type string stdio, sse, or http (default "stdio") --command string executable for stdio servers --args string command argument (repeatable) --env key value environment variable (repeatable) --url string URL for HTTP/SSE servers --header key value HTTP header (repeatable) --timeout int startup timeout in seconds --disabled bool disable without removing --disabled-tools string deny a server tool (repeatable) --enabled-tools string allow only these server tools (repeatable) --oauth bool enable OAuth 2.1 flow (HTTP only) --oauth-client-id string pre-registered OAuth client ID --oauth-client-secret string pre-registered OAuth client secret --oauth-callback-port int fixed localhost port for the OAuth callbackmcp add github --type http \ --url "https://api.githubcopilot.com/mcp/" \ --header Authorization "Bearer $GH_PAT"与 provider 一致,header 解析为空字符串时会被从出站请求中丢弃。--enabled-tools/--disabled-tools提供了工具级的白名单/黑名单能力,--oauth系列 flag 则支持 HTTP 类型的 OAuth 2.1 授权流程。
mcp remove
Usage: mcp remove <name> mcp rm <name>lsp:管理语言服务器
Usage: lsp [command] Available Commands: add Add or update a language server remove Remove a language server rm Alias for removelsp add
添加语言服务器,或更新同名服务器。--command为必填。
Usage: lsp add <name> --command <command> [flags] Flags: --args string command argument (repeatable) --env key value environment variable (repeatable) --filetypes string file type to attach to (repeatable) --root-markers string root marker file (repeatable) --timeout int startup timeout in seconds --disabled bool disable without removing --init-options JSON initialization options --options JSON server settingslsp add go --command gopls --env GOPATH "$HOME/go"配置完成后,internal/config/load.go 的applyLSPDefaults会用内置的 powernap 语言服务器目录为未显式指定的字段(filetypes、root-markers、init-options 等)填充默认值。
lsp remove
Usage: lsp remove <name> lsp rm <name>hook:管理钩子
钩子的能力和运行方式详见 docs/hooks/ 目录。事件名大小写不敏感,也接受 snake_case 变体(如PreToolUse、pre_tool_use均可),归一化逻辑位于 internal/config/load.go 的normalizeHookEvent;所有钩子在加载完成后会经过ValidateHooks校验(命令必填、matcher 正则必须可编译),保证配置错误在启动时暴露而不是等到首次工具调用。
Usage: hook [command] Available Commands: add Add a hook to an event remove Remove a named hook, or clear an event rm Alias for removehook add
添加一个在指定钩子事件触发时运行的 shell 命令。
Usage: hook add <event> --command <command> [flags] Flags: --command string shell command to run (required) --name string name used for later removal --matcher string regex tested against the tool name --timeout int timeout in seconds (default 30)hook add PreToolUse --matcher "^bash$" \ --command "./hooks/no-haskell.sh" --name no-haskell注意:只有命名钩子才能被单独移除,所以打算日后删除的钩子一定要给--name。
hook remove
不带--name时移除该事件的全部钩子。
Usage: hook remove <event> [--name <name>] hook rm <event> [--name <name>] Flags: --name string remove hooks with this namepermissions:配置工具权限
allow让工具跳过审批提示;deny则把工具从 Agent 视野中彻底隐藏(Agent 根本看不到、也无法调用)。源码 internal/shellconfig/permissions.go 显示:allow写入permissions.allowed_tools,deny写入options.disabled_tools——deny是allow的逆操作,且deny 优先:工具同时出现在两个列表时,仍会通过disabled_tools从 Agent 的有效工具集中移除。重复添加同一工具是幂等的 no-op。
Usage: permissions [command] Available Commands: allow Allow tools without prompting deny Hide tools from the agentpermissions allow
Usage: permissions allow <tool> [<tool> ...]permissions deny
Usage: permissions deny <tool> [<tool> ...]permissions allow view ls grep edit permissions deny bashoption:配置通用行为
option配置 Crush 的通用行为、路径、署名与终端 UI。布尔值可省略,缺省为true;源码 internal/shellconfig/options.go 的optionSpecs表是 option key 处理的唯一事实来源,它还揭示了两个值得一提的细节:
- 反向存储:若干字段在配置里是反着存的(如
disable_metrics),但对用户以正向暴露。option metrics false实际写入disable_metrics = true,inverted: true的标记在handleOption中做了取反转换。同理auto-summarize、provider-auto-update、default-providers都是正向暴露、反向存储。 - 列表语义:列表型 key 每次调用追加一个值(key 是单数形式),
option reset <key>则把列表清空。
Usage: option <key> [value] option [command] Available Commands: reset Clear every value from a list option ui Configure terminal UI behavior Boolean Keys: debug enable debug logging debug-lsp enable LSP debug logging auto-lsp automatically configure language servers progress show progress indicators metrics send anonymous usage metrics auto-summarize automatically summarize long conversations provider-auto-update update the provider catalog automatically default-providers include built-in providers attribution-generated-with add the Generated with Crush line String Keys: >option progress false option skill-path ./skills option attribution-trailer-style assisted-byattribution-trailer-style只接受none/co-authored-by/assisted-by三值之一,handleOption中做了严格校验。
option reset
清空某个列表选项此前累积的全部值;reset 之后新加的值会被保留。
Usage: option reset <key> Available Keys: context-path clear project context paths global-context-path clear global context paths skill-path clear additional skill directories disable-skill clear disabled skill namesoption ui
配置终端 UI 呈现与补全列表上限。
Usage: option ui <key> <value> Available Keys: compact bool use the compact chat layout diff unified|split choose unified or side-by-side diffs transparent bool use the terminal background mouse bool enable terminal mouse capture for clicks, selection, and scrolling in the TUI (default true); disable to let the terminal emulator or tmux handle text selection and copy/paste scrollbar string control chat scrollbar visibility: default, always, or never exit-banner default|compact|none control the post-session banner: default shows the Crush logo, compact shows only the resume hint, none hides it entirely completions-max-depth int maximum directory depth shown by completions completions-max-items int maximum items returned to completionsoption ui compact true option ui diff unified option ui transparent true option ui mouse false option ui scrollbar always option ui exit-banner compact option ui completions-max-depth 4 option ui completions-max-items 200[!IMPORTANT] 以下技能路径默认加载,无需用
skill-path手动添加:.agents/skills、.crush/skills、.claude/skills、.cursor/skills。这在源码 internal/config/load.go 的projectSkillSubdirs中有印证,且配置技能文档 internal/skills/builtin/crush-config/SKILL.md 也明确列出。
[!NOTE] 命令面板里的 "Disable Background Color" 与 "Disable Mouse" 开关总是写入全局配置。如果某个项目配置同时也设置了
transparent或mouse,由于项目设置优先级更高(见 配置在哪里),下次启动时项目设置会胜出,导致开关看起来像"静默回退"了。
组合配置:source 与覆盖语义
因为 crushrc 本质是 Bash,共享基础配置就是一个source:
# Unix-like: ~/.config/crush/crushrc # Windows: %USERPROFILE%\.config\crush\crushrc source ~/team/crush-base.sh # sets up providers, a few skills # …but on this machine, drop a skill path the base added and add my own. option reset skill-path option skill-path ~/my/skillsremove、rm、option reset都作用于脚本中更早设置、或通过source引入的内容。后写的行生效,和 shell 完全一致。这一语义在源码中由 internal/shellconfig/builder.go 保证:ConfigBuilder让内建命令按执行顺序直接就地变更嵌套 map,因此追加、覆盖、删除、重置这些命令式操作精确反映脚本意图;脚本执行完后 builder 序列化为单个 JSON 对象,再由配置加载器与其它配置文件合并。
Legacy JSON:旧版 JSON 配置
crush.json是最初的配置格式,现已弃用。Crush 计划在可预见的未来继续支持它,但新配置选项只添加到 Bash 配置中。
{ "$schema": "https://charm.land/crush.json", "providers": { "anthropic": { "api_key": "$ANTHROPIC_API_KEY" }, }, "models": { "large": { "provider": "anthropic", "model": "claude-sonnet-4-20250514" }, }, "permissions": { "allowed_tools": ["view", "ls", "grep"] }, }完整字段参考见 schema.json(文档原链接为../../schema.json,即仓库根目录的 schema.json)。
两者在 shell 展开上有一个关键区别:JSON 中只有被选中的字符串字段(API key、URL、MCP/LSP 命令与参数、header)在加载时做 shell 展开;而 crushrc 不存在这样的清单——一切都是 Bash。更细的映射关系(provider add↔providers.*、permissions deny↔options.disabled_tools、option metrics false↔options.disable_metrics等)可查阅 internal/skills/builtin/crush-config/SKILL.md 中的对照表。
最后再次强调:两种格式都是受信任代码——它们在 UI 出现之前以你的 shell 权限运行。不要在未审阅配置的目录中启动 Crush。如果你正从旧 JSON 格式迁移,也可以直接用自然语言告诉 Crush(通过内置的 config 技能)帮你转换配置。
进阶阅读
- docs/hooks/:钩子事件的完整能力与运行时行为(stdin 载荷、环境变量、决策聚合)。
- docs/config/FUTURE.md:配置的规划方向——包括"bash 工具实时改配置"(复用现有内建命令与会话级临时覆盖,持久化明确为非目标)、"机器状态与用户配置分离"(版本化
state.json+ 类型化StateStore)、以及"权限级硬拒绝"的取舍分析。 - internal/shellconfig:七个内建命令的注册与实现(register.go、builder.go、provider.go、permissions.go、options.go 等)。
- internal/config/load.go:配置查找、合并、crushrc 执行、provider/模型解析与 LSP 默认值填充的完整实现。
- internal/skills/builtin/crush-config/SKILL.md:内置配置技能的完整说明,含 crushrc ↔ crush.json 映射表与 JSON shell 展开范围。
- schema.json:Legacy JSON 配置的完整 JSON Schema。
- AI 应用
- 代码智能体
- 交互助手
- CLI
- MCP Clients
- 人工智能
【免费下载链接】crush
Glamourous agentic coding for all 💘
相关推荐
Crush高级配置技巧:自定义Provider、LSP和MCP服务器
Crush高级配置技巧:自定义Provider、LSP和MCP服务器 Crush是一款强大的AI编程助手,专为终端环境设计。通过深度自定义Provider配置、
AI 应用代码智能体交互助手CLIMCP Clients人工智能OneUptime Runbook 配置与安全指南:Bash/JavaScript 执行模型、超时、权限与生产加固
OneUptime Runbook 配置与安全指南:Bash/JavaScript 执行模型、超时、权限与生产加固 导读 本指南聚焦 OneUptime 开源可
可观测性后端运维前端云原生微服务AI AgentApple MCP权限管理完全指南:如何正确配置macOS应用访问权限
Apple MCP权限管理完全指南:如何正确配置macOS应用访问权限 Apple MCP是一个强大的模型上下文协议工具集,让AI助手能够无缝访问和控制macO
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考