Doramagic 项目包 · 项目说明书
crush 项目
生成时间:2026-05-31 04:01:54 UTC
项目概览
Crush 是由 Charm 开发的终端编程助手,能够将你的工具、代码和工作流无缝接入你选择的 LLM 模型。它支持多模型切换、内置多种开发工具、Hooks 机制、LSP 语言服务器集成以及 MCP(Model Context Protocol)协议扩展。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
简介
Crush 是由 Charm 开发的终端编程助手,能够将你的工具、代码和工作流无缝接入你选择的 LLM 模型。它支持多模型切换、内置多种开发工具、Hooks 机制、LSP 语言服务器集成以及 MCP(Model Context Protocol)协议扩展。
资料来源:README.md:1-8
核心功能
多模型支持
Crush 支持从广泛的 LLM 中选择使用,也可以通过 OpenAI 或 Anthropic 兼容 API 添加自定义提供商。
| 功能类别 | 支持类型 |
|---|---|
| 云端 API | OpenAI、Anthropic、DeepSeek、Google Gemini 等 |
| 自托管 | 通过 OpenAI-compatible 或 Anthropic-compatible 接口 |
| 订阅服务 | Synthetic、GLM Coding Plan、Kimi Code、MiniMax Coding Plan |
资料来源:README.md:89-130
工具系统
Crush 提供丰富的内置工具集,包括:
- Bash 工具:执行命令行操作
- Glob 工具:文件模式匹配
- Grep 工具:代码搜索
- View 工具:文件查看
- Edit 工具:文件编辑
- Search 工具:网络搜索
- Web Fetch 工具:网页内容获取
- Task 工具:任务分解执行
资料来源:README.md:32-45
LSP 集成
Crush 可使用 Language Server Protocol (LSP) 来获取额外的上下文信息,辅助决策。支持手动配置 LSP:
{
"lsp": {
"go": {
"command": "gopls",
"env": { "GOTOOLCHAIN": "go1.24.5" }
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
}
}
}
资料来源:README.md:180-195
MCP 支持
Crush 支持通过三种传输类型连接 MCP 服务器:
| 传输类型 | 用途 |
|---|---|
stdio | 命令行 MCP 服务器 |
http | HTTP 端点 |
sse | Server-Sent Events |
MCP 配置支持 shell 风格的环境变量展开($VAR、${VAR:-default}、$(command))。
资料来源:README.md:197-215
Hooks 机制
Hooks 使用内置 shell 解释器执行,默认使用系统 shell。这改善了跨平台支持。
资料来源:v0.67.0 发布说明
系统架构
客户端-服务端架构
Crush 采用客户端-服务端架构设计,可通过环境变量 CRUSH_CLIENT_SERVER=1 启用实验性功能。
graph TD
A[CLI Client] -->|HTTP/WebSocket| B[Backend Server]
B --> C[Workspace Manager]
C --> D[Agent Processing]
C --> E[LSP Manager]
C --> F[MCP Integration]
B --> G[Database]
D --> H[Tool Executor]
H --> I[Permission System]资料来源:internal/backend/backend_test.go:10-25 资料来源:internal/server/events.go:1-50
工作空间管理
每个客户端连接到一个工作空间(Workspace),工作空间通过路径索引管理:
- 绝对路径直接解析
- 相对路径基于当前目录
- 不存在的路径会创建新工作空间
type Workspace struct {
ID string
Path string
resolvedPath string
clients map[string]*clientState
shutdownFn func()
}
资料来源:internal/backend/backend_test.go:13-20
事件系统
Crush 使用发布-订阅模式处理内部事件,主要事件类型包括:
type LSPEvent struct {
Type LSPEventType
Name string
State lsp.ServerState
Error error
DiagnosticCount int
}
| 事件类型 | 说明 |
|---|---|
LSPEventStateChanged | LSP 服务器状态变更 |
LSPEventDiagnosticsChanged | 诊断信息变更 |
pubsub.Event[mcp.Event] | MCP 相关事件 |
pubsub.Event[permission.PermissionRequest] | 权限请求 |
资料来源:internal/app/lsp_events.go:16-30 资料来源:internal/server/events.go:25-55
配置系统
配置文件优先级
Crush 配置文件按以下优先级加载:
.crush.json(项目本地)crush.json(项目本地)$HOME/.config/crush/crush.json(全局)
配置文件使用 JSON 格式存储。
资料来源:README.md:139-155
环境变量覆盖
可通过以下环境变量覆盖默认配置路径:
| 环境变量 | 说明 |
|---|---|
CRUSH_GLOBAL_CONFIG | 全局配置文件路径 |
CRUSH_GLOBAL_DATA | 全局数据目录路径 |
CRUSH_CLIENT_SERVER | 启用客户端-服务端模式 |
资料来源:README.md:156-165
API 密钥配置
Crush 支持多种提供商的 API 密钥配置:
| 环境变量 | 提供商 |
|---|---|
ANTHROPIC_API_KEY | Anthropic |
OPENAI_API_KEY | OpenAI |
DEEPSEEK_API_KEY | DeepSeek |
OPENROUTER_API_KEY | OpenRouter |
VERTEXAI_* | Google Cloud VertexAI |
AWS_* | Amazon Bedrock |
资料来源:README.md:220-260
客户端 API
配置操作
客户端提供完整的配置管理接口:
// 设置紧凑模式
func (c *Client) SetCompactMode(ctx context.Context, id string, scope config.Scope, enabled bool) error
// 设置提供商 API 密钥
func (c *Client) SetProviderAPIKey(ctx context.Context, id string, scope config.Scope, providerID string, apiKey any) error
// 导入 Copilot Token
func (c *Client) ImportCopilot(ctx context.Context, id string) (*oauth.Token, bool, error)
// 刷新 OAuth Token
func (c *Client) RefreshOAuthToken(ctx context.Context, id string, scope config.Scope, providerID string) error
资料来源:internal/client/config.go:180-280
MCP 操作
客户端支持与 MCP 服务器交互:
// 读取 MCP 资源
func (c *Client) GetMCPResource(ctx context.Context, id, clientID, serverID, uri string) ([]MCPResourceContents, error)
// 获取 MCP Prompt
func (c *Client) GetMCPPrompt(ctx context.Context, id, clientID, promptID string, args map[string]string) (string, error)
资料来源:internal/client/config.go:60-120
Agent 操作
// 列出消息
func (c *Client) ListMessages(ctx context.Context, id string, sessionID string) ([]proto.Message, error)
// 汇总会话
func (c *Client) SummarizeSession(ctx context.Context, id, sessionID string) error
// 初始化 Agent 处理
func (c *Client) InitiateAgentProcessing(ctx context.Context, id string) error
资料来源:internal/client/proto.go:80-120
生命周期管理
应用关闭
Crush 提供两种关闭机制:
App.Shutdown:生产环境完整关闭路径,包含数据库释放、LSP 关闭、MCP 关闭App.ShutdownForTest:测试用关闭,仅执行清理函数
func (app *App) ShutdownForTest() {
for _, cleanup := range app.cleanupFuncs {
if cleanup != nil {
_ = cleanup(context.Background())
}
}
app.cleanupFuncs = nil
}
资料来源:internal/app/testing.go:1-15
工作空间持有机制
工作空间使用持有(Hold)机制防止意外关闭:
- 注册客户端时获取持有
- 客户端连接时增加引用计数
- 最后一个持有释放时触发工作空间关闭
func TestHoldExpiry_TearsDown(t *testing.T) {
b, srvShutdowns := newTestBackend(t)
ws, wsShutdowns := insertTestWorkspace(t, b, "/tmp/a")
cid := newClientID(t)
b.registerClient(ws, cid)
// 持有过期时触发关闭
}
资料来源:internal/backend/backend_test.go:80-95
社区相关问题
已知问题与功能请求
| Issue | 说明 | 状态 |
|---|---|---|
| #2935 | 多权限配置文件(Yolo/Safe/Custom)运行时切换 | 功能请求 |
| #928 | 移除 bash 命令安全限制 | 功能请求 |
| #2898 | 全局 LSP 配置不生效 | Bug 报告 |
| #2903 | 数据库持续损坏 | Bug 报告 |
| #2928 | OpenRouter 模型授权失败 | Bug 报告 |
最新版本动态
v0.74.1 修复内容:
- 修复
bash工具在运行交互式命令(如git rebase -i)时挂起的问题 - 修复 OpenCode + Qwen 3.7 的兼容性
- 客户端-服务端架构持续改进
技术栈
| 组件 | 技术 |
|---|---|
| 语言 | Go |
| 协议 | HTTP, WebSocket, SSE |
| 配置 | JSON |
| 扩展协议 | MCP (Model Context Protocol) |
| 语言服务 | LSP (Language Server Protocol) |
| 授权 | OAuth, API Key |
相关资源
- 官方文档:https://charm.land/crush
- 社区 Slack:https://charm.land/slack
- Discord:https://charm.land/discord
- 模型列表:https://github.com/charmbracelet/catwalk
资料来源:README.md:1-8
安装与部署
Crush 是一个终端编程助手,支持在多种操作系统上运行。本文档详细介绍 Crush 的各种安装方式和部署配置选项,帮助用户快速上手并根据自身环境进行定制化部署。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Crush 是一个终端编程助手,支持在多种操作系统上运行。本文档详细介绍 Crush 的各种安装方式和部署配置选项,帮助用户快速上手并根据自身环境进行定制化部署。
Crush 采用 Go 语言开发,提供了跨平台支持,覆盖 macOS、Linux、Windows(包括 PowerShell 和 WSL)、Android、FreeBSD、OpenBSD 和 NetBSD 等主流操作系统。资料来源:README.md:1-15
系统要求
运行环境要求
| 组件 | 最低要求 | 推荐配置 |
|---|---|---|
| 操作系统 | macOS 10.15+ / Linux (glibc 2.31+) / Windows 10+ | 最新稳定版 |
| 内存 | 4GB | 8GB+ |
| 磁盘空间 | 200MB | 500MB+ |
| 网络 | 需要访问 LLM API | 稳定高速网络 |
外部依赖
部分功能需要安装外部工具:
- Shell 工具:bash、zsh、PowerShell
- Git:版本控制功能必需
- LSP 服务器:根据编程语言需求(如 gopls、typescript-language-server)
资料来源:README.md:45-52
安装方式
通过包管理器安装
#### macOS (Homebrew)
brew install charmbracelet/tap/crush
#### NPM
npm install -g @charmland/crush
资料来源:README.md:59-65
#### Linux 包管理器
| 发行版 | 安装命令 |
|---|---|
| Arch Linux | yay -S crush-bin |
| FreeBSD | pkg install crush |
| Nix | nix run github:numtide/nix-ai-tools#crush |
#### Windows
| 包管理器 | 安装命令 |
|---|---|
| Winget | winget install charmbracelet.crush |
| Scoop | scoop bucket add charm https://github.com/charmbracelet/scoop-bucket.git && scoop install crush |
资料来源:README.md:66-80
Nix/NixOS 安装
#### 通过 NUR 安装
Crush 通过官方 Charm NUR 提供 Nix 支持,是 Nix 中获取最新版本的最优方式。
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nur.url = "github:nix-community/NUR";
# 导入 nur.repos.charmbracelet.crush
};
}
#### Nix Shell 快速试用
# 添加 NUR channel
nix-channel --add https://github.com/nix-community/NUR/archive/main.tar.gz nur
nix-channel --update
# 在 Nix shell 中运行 Crush
nix-shell -p '(import <nur> { pkgs = import <nixpkgs> {}; }).repos.charmbracelet.crush'
#### NixOS / Home Manager 模块
Crush 提供 NixOS 和 Home Manager 模块,可直接通过 NUR 导入到 flake 配置中:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nur.url = "github:nix-community/NUR";
};
outputs = { self, nixpkgs, nur }: {
# 支持自动检测 home-manager 或 nixos 上下文
homeModules.example = import (nur + "/repos/charmbracelet/modules/crush") { pkgs = nixpkgs.legacyPackages.x86_64-linux; };
};
}
资料来源:flake.nix:1-25
从源码编译安装
#### 环境准备
- 安装 Go 1.21+
- 克隆仓库
git clone https://github.com/charmbracelet/crush.git
cd crush
#### 编译
# 编译可执行文件
go build -o crush ./cmd/crush
# 或使用 Taskfile(需要安装 Task)
task build
#### Taskfile 构建任务
| 任务 | 说明 |
|---|---|
task build | 编译 Crush 可执行文件 |
task test | 运行测试套件 |
task lint | 运行代码检查 |
task release | 创建发布版本 |
# 查看所有可用任务
task --list
资料来源:Taskfile.yaml:1-50
配置管理
配置文件位置
Crush 支持多级配置文件,按以下优先级加载:
graph TD
A[配置文件加载顺序] --> B[.crush.json]
B --> C[crush.json]
C --> D[$HOME/.config/crush/crush.json]
E[临时数据位置] --> F[Unix: $HOME/.local/share/crush/crush.json]
E --> G[Windows: %LOCALAPPDATA%\crush\crush.json]配置文件优先级(高 → 低):
.crush.json(项目本地)crush.json(项目根目录)$HOME/.config/crush/crush.json(全局)
资料来源:README.md:30-50
环境变量配置覆盖
可通过环境变量覆盖默认配置路径:
| 环境变量 | 用途 |
|---|---|
CRUSH_GLOBAL_CONFIG | 全局配置文件路径 |
CRUSH_GLOBAL_DATA | 全局数据目录路径 |
CRUSH_SKILLS_DIR | 自定义技能目录 |
CRUSH_CLIENT_SERVER | 启用客户端-服务器架构(实验性) |
资料来源:README.md:48-52
基本配置示例
{
"$schema": "https://charm.land/crush.json",
"options": {
"disabled_skills": ["crush-config"]
},
"lsp": {
"go": {
"command": "gopls",
"env": {
"GOTOOLCHAIN": "go1.24.5"
}
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
}
}
}
LSP 配置
Crush 支持 Language Server Protocol,可为不同编程语言配置 LSP 服务器:
{
"lsp": {
"<语言>": {
"command": "<命令>",
"args": ["参数列表"],
"env": {"环境变量": "值"},
"root_markers": ["标记文件"],
"filetypes": ["文件类型"]
}
}
}
常见 LSP 配置示例:
| 语言 | 命令 | 参数 |
|---|---|---|
| Go | gopls | - |
| TypeScript | typescript-language-server | --stdio |
| Nix | nil | - |
注意:全局 LSP 配置需确保配置文件位于正确路径(~/.config/crush/crush.json),部分用户报告过全局 LSP 配置不生效的问题。资料来源:README.md:54-68
MCP 服务器配置
Crush 支持 Model Context Protocol (MCP),支持三种传输类型:
| 传输类型 | 说明 |
|---|---|
stdio | 命令行服务器 |
http | HTTP 端点 |
sse | Server-Sent Events |
{
"mcp": {
"servers": {
"example": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/workspace"]
}
}
}
}
环境变量扩展支持:
$VAR- 基本变量替换${VAR:-default}- 带默认值的变量$(command)- 命令替换- 文件引用如
"$(cat /path/to/secret/token)"
资料来源:README.md:70-90
技能(Skills)配置
#### 技能搜索路径
Crush 按以下顺序搜索技能目录:
graph LR
A[技能搜索路径] --> B[全局目录]
A --> C[项目目录]
B --> B1[$CRUSH_SKILLS_DIR]
B --> B2[$XDG_CONFIG_HOME/agents/skills]
B --> B3[$XDG_CONFIG_HOME/crush/skills]
B --> B4[~/.agents/skills]
B --> B5[~/.claude/skills]
C --> C1[.agents/skills]
C --> C2[.crush/skills]
C --> C3[.claude/skills]
C --> C4[.cursor/skills]#### 自定义技能路径
{
"options": {
"skills_paths": [
"~/.config/crush/skills",
"./project-skills"
]
}
}
资料来源:README.md:105-135
权限模式配置
Crush 提供三种权限模式控制工具调用行为:
| 模式 | 说明 | 配置项 |
|---|---|---|
| Yolo | 完全自动批准所有工具调用 | permissions.yolo: true |
| Safe | 每次工具调用前询问确认 | permissions.yolo: false(默认) |
| Custom | 自定义权限规则 | 使用 permissions.rules |
社区反馈:当前版本权限模式一旦设置将应用于整个会话,无法在运行时切换。资料来源:社区讨论 #2935
提交信息配置
{
"git": {
"trailer_style": "assisted-by",
"generated_with": true
}
}
| 配置项 | 可选值 | 说明 |
|---|---|---|
trailer_style | assisted-by(默认)、co-authored-by、none | 提交信息归属风格 |
generated_with | true(默认)、false | 是否添加 "💘 Generated with Crush" |
资料来源:README.md:145-165
环境变量
API 密钥配置
Crush 支持多种 LLM 提供商,通过环境变量配置 API 密钥:
| 环境变量 | 支持的提供商 |
|---|---|
ANTHROPIC_API_KEY | Anthropic |
OPENAI_API_KEY | OpenAI |
VERCEL_API_KEY | Vercel AI Gateway |
GEMINI_API_KEY | Google Gemini |
SYNTHETIC_API_KEY | Synthetic |
ZAI_API_KEY | Z.ai |
MINIMAX_API_KEY | MiniMax |
HF_TOKEN | Hugging Face Inference |
CEREBRAS_API_KEY | Cerebras |
OPENROUTER_API_KEY | OpenRouter |
OPENCODE_API_KEY | OpenCode Zen & Go |
GROQ_API_KEY | Groq |
IONET_API_KEY | io.net |
ALIBABA_SINGAPORE_API_KEY | Alibaba (Singapore) |
AVIAN_API_KEY | Avian |
AWS / Azure 配置
| 环境变量 | 用途 |
|---|---|
AWS_ACCESS_KEY_ID | Amazon Bedrock (Claude) |
AWS_SECRET_ACCESS_KEY | Amazon Bedrock (Claude) |
AWS_REGION | Amazon Bedrock (Claude) |
AWS_PROFILE | Amazon Bedrock (自定义 Profile) |
AWS_BEARER_TOKEN_BEDROCK | Amazon Bedrock |
AZURE_OPENAI_API_ENDPOINT | Azure OpenAI |
AZURE_OPENAI_API_KEY | Azure OpenAI |
AZURE_OPENAI_API_VERSION | Azure OpenAI |
VERTEXAI_PROJECT | Google Cloud VertexAI |
VERTEXAI_LOCATION | Google Cloud VertexAI |
资料来源:README.md:170-195
客户端-服务器模式
架构概述
Crush 支持实验性的客户端-服务器架构,将前端界面与后端服务分离:
graph TD
A[Crush 客户端] <--> B[Crush 服务器]
B --> C[数据库]
B --> D[LSP 服务]
B --> E[MCP 服务]
B --> F[LLM API]启用方式
export CRUSH_CLIENT_SERVER=1
crush
工作空间管理
服务器模式下支持多工作空间管理:
| 功能 | 说明 |
|---|---|
| 多工作空间 | 每个项目独立的上下文 |
| 会话持久化 | 跨会话保持对话历史 |
| 并行连接 | 支持多个客户端同时连接 |
桌面通知
Crush 支持桌面通知,当工具调用需要权限或代理完成时会发送通知:
{
"options": {
"disable_notifications": false // 默认值
}
}
通知发送条件:
- 工具调用需要权限确认
- 代理完成当前回合
注意:macOS 平台的通知目前缺少图标(平台限制)。
资料来源:README.md:138-155
订阅服务
除 API 密钥方式外,Crush 也支持订阅制服务:
| 服务 | 说明 |
|---|---|
| Synthetic | 订阅计费 |
| GLM Coding Plan | 智谱 AI 代码计划 |
| Kimi Code | 月之暗面代码助手 |
| MiniMax Coding Plan | MiniMax 代码计划 |
资料来源:README.md:197-205
验证安装
基本验证
# 检查版本
crush --version
# 检查配置
crush doctor
配置测试
# 测试 API 连接
crush config test
# 测试 LSP 连接
crush lsp check
常见问题排查
| 问题 | 解决方案 |
|---|---|
| 数据库损坏 | 清除 ~/.local/share/crush/crush.json 并重启 |
| OpenRouter 连接失败 | 确认 OPENROUTER_API_KEY 正确设置 |
| LSP 配置不生效 | 检查配置文件路径和权限 |
| Bash 工具挂起 | 避免运行交互式命令(如 git rebase -i) |
社区反馈:部分用户报告数据库在 VM 环境中定期损坏,可能是文件系统问题导致。资料来源:社区讨论 #2903
更新升级
自动更新检查
Crush 启动时会自动检查更新,提示用户有新版本可用。
手动更新
# 使用包管理器
brew upgrade crush # macOS
npm update -g @charmland/crush # NPM
# 或重新安装
brew reinstall charmbracelet/tap/crush
版本信息
当前稳定版本:v0.74.1
最新版本信息请参阅 GitHub Releases。
资料来源:README.md:210-220
卸载
| 平台 | 卸载命令 |
|---|---|
| Homebrew (macOS) | brew uninstall crush |
| NPM | npm uninstall -g @charmland/crush |
| Winget (Windows) | winget uninstall charmbracelet.crush |
| Scoop (Windows) | scoop uninstall crush |
卸载后建议清理配置文件:
# 配置文件
rm -rf ~/.config/crush
# 数据文件
rm -rf ~/.local/share/crush
# Windows
rd /s /q %LOCALAPPDATA%\crush资料来源:README.md:45-52
快速入门
Crush 是一款终端内的智能编程助手,它将你的工具、代码和工作流与大型语言模型(LLM)无缝集成。无论你是处理日常开发任务还是复杂的多步骤项目,Crush 都能提供强大的辅助能力。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
安装 Crush
系统要求
Crush 支持 macOS、Linux 和 Windows 系统。推荐使用最新版本的操作系统以获得最佳体验。
安装方式
#### macOS
brew install charm-cli/tap/crush
#### Linux
curl -fsSL https://get.crush.sh | bash
#### Windows
使用 winget 安装:
winget install Charm.Crush
验证安装
安装完成后,在终端中运行以下命令验证安装:
crush --version
资料来源:README.md:1-20
首次启动与登录
默认启动
直接运行 crush 命令即可启动程序:
crush
首次启动时,Crush 会引导你完成初始配置流程,包括选择默认语言模型和配置 API 密钥。
配置 API 密钥
Crush 支持多种模型提供商,你需要配置相应的 API 密钥才能使用对应的模型。
#### 环境变量方式
| 提供商 | 环境变量 | 说明 |
|---|---|---|
| Anthropic | ANTHROPIC_API_KEY | 用于 Claude 系列模型 |
| OpenAI | OPENAI_API_KEY | 用于 GPT 系列模型 |
| Google Gemini | GEMINI_API_KEY | 用于 Gemini 模型 |
| OpenRouter | OPENROUTER_API_KEY | 用于访问多种模型 |
| DeepSeek | DEEPSEEK_API_KEY | 用于 DeepSeek 模型 |
资料来源:README.md:1-100
#### 配置文件方式
你也可以在 crush.json 中直接配置 API 密钥:
{
"$schema": "https://charm.land/crush.json",
"providers": {
"deepseek": {
"type": "openai-compat",
"base_url": "https://api.deepseek.com/v1",
"api_key": "$DEEPSEEK_API_KEY"
}
}
}
资料来源:README.md:100-150
基本配置
配置文件位置
Crush 按以下优先级查找配置文件:
| 优先级 | 位置 | 说明 |
|---|---|---|
| 1 | .crush.json | 项目本地配置 |
| 2 | crush.json | 项目本地配置 |
| 3 | ~/.config/crush/crush.json | 用户全局配置 |
配置结构
Crush 的配置文件采用 JSON 格式,主要包含以下部分:
{
"$schema": "https://charm.land/crush.json",
"providers": {},
"lsp": {},
"mcp": {},
"options": {}
}
资料来源:README.md:150-200
核心功能入门
1. 对话交互
启动 Crush 后,你可以直接通过自然语言与它交流。Crush 能够理解你的编程需求并执行相应的操作。
示例对话:
你:帮我创建一个新的 Go 项目
Crush:好的,我将为你创建一个标准的 Go 项目结构...
2. 文件操作
Crush 提供了多种文件操作工具:
| 工具名称 | 功能 | 常用场景 |
|---|---|---|
view | 查看文件内容 | 代码审查、快速定位 |
write | 写入或创建文件 | 生成代码、修改配置 |
read | 读取文件 | 获取文件内容进行处理 |
edit | 编辑文件 | 修改代码、行级调整 |
glob | 文件搜索 | 查找项目中的文件 |
3. Bash 命令执行
Crush 可以执行 bash 命令来完成各种任务:
# 运行 git 命令
crush> git status
# 运行构建命令
crush> go build ./...
# 搜索文件内容
crush> grep -r "function" .
[!NOTE]
某些敏感命令(如curl、wget、ssh、sudo)可能受到安全限制。社区中有用户反馈希望移除这些限制以获得不受限制的终端访问能力。相关讨论可参考 GitHub Issue #928。
4. LSP 集成
Crush 支持 Language Server Protocol (LSP),可以为编程决策提供更丰富的上下文信息。
#### 配置示例
{
"lsp": {
"go": {
"command": "gopls",
"env": {
"GOTOOLCHAIN": "go1.24.5"
}
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
}
}
}
资料来源:README.md:200-250
#### LSP 事件类型
| 事件类型 | 说明 |
|---|---|
state_changed | LSP 服务器状态变更 |
diagnostics_changed | 诊断信息变更 |
资料来源:internal/app/lsp_events.go:1-50
5. MCP 服务器支持
Crush 支持 Model Context Protocol (MCP) 服务器,提供三种传输类型:
| 传输类型 | 说明 | 配置方式 |
|---|---|---|
stdio | 命令行服务器 | 命令行参数 |
http | HTTP 端点 | URL 和 Headers |
sse | Server-Sent Events | URL 配置 |
#### 配置示例
{
"mcp": {
"my-server": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"]
}
}
}
#### Shell 变量展开
MCP 配置支持 Shell 风格的变量展开:
| 语法 | 说明 |
|---|---|
$VAR | 展开环境变量 |
${VAR:-default} | 展开带默认值的变量 |
$(command) | 执行命令并展开结果 |
资料来源:README.md:250-300
工作流程图
基本交互流程
graph TD
A[用户启动 Crush] --> B[加载配置文件]
B --> C{检查 API 密钥}
C -->|有有效密钥| D[连接到 LLM]
C -->|无密钥| E[引导用户配置]
E --> C
D --> F[用户发送请求]
F --> G[解析请求意图]
G --> H[调用相应工具]
H --> I[执行操作]
I --> J[返回结果给用户]
J --> F工具调用流程
graph LR
A[用户请求] --> B[LLM 决策]
B --> C{需要权限?}
C -->|是| D[请求权限]
D --> E{用户批准?}
E -->|是| F[执行工具]
E -->|否| G[跳过/取消]
C -->|否| F
F --> H[返回结果]
G --> HAgent Skills
Crush 支持 Agent Skills 开放标准,可以通过可重用的技能包扩展功能。
技能搜索路径
| 优先级 | 路径 |
|---|---|
| 1 | $CRUSH_SKILLS_DIR |
| 2 | ~/.config/agents/skills/ |
| 3 | ~/.config/crush/skills/ |
| 4 | ~/.agents/skills/ |
| 5 | ~/.claude/skills/ |
项目本地技能路径
.agents/skills.crush/skills.claude/skills.cursor/skills
资料来源:README.md:300-350
权限与安全
权限模式
Crush 提供了两种权限模式:
| 模式 | 说明 | 配置项 |
|---|---|---|
| Yolo | 自动批准所有工具调用 | permissions.yolo: true |
| Safe | 执行前询问每个工具 | permissions.yolo: false |
[!TIP]
社区中有功能请求,希望支持在运行时切换权限配置文件(如 Yolo、Safe、Custom),而无需重启 Crush。相关讨论可参考 GitHub Issue #2935。
提交信息配置
{
"git": {
"trailer_style": "assisted-by",
"generated_with": true
}
}
支持的提交风格:
| 风格 | 说明 |
|---|---|
assisted-by | 添加 Assisted-by: Crush:[ModelID] |
co-authored-by | 添加 Co-Authored-By: Crush <[email protected]> |
none | 不添加任何标识 |
资料来源:README.md:50-100
常见问题与故障排除
数据库问题
[!WARNING]
有用户报告在虚拟机环境中运行 Crush 时遇到数据库损坏问题。若遇到 ERROR: failed to get session message 错误,可能需要检查文件系统完整性。相关讨论可参考 GitHub Issue #2903。
LSP 配置问题
[!NOTE]
全局 LSP 配置可能不生效。若 LSP 功能无法正常使用,可以尝试使用项目本地的 .crush.json 配置文件。相关讨论可参考 GitHub Issue #2898。
模型提供商问题
如果在使用 OpenRouter 等第三方模型时遇到认证错误,请确保:
- API 密钥已正确设置在环境变量中
- API 密钥具有访问所需模型的权限
- 配置文件中的模型名称拼写正确
相关讨论可参考 GitHub Issue #2928。
下一步
| 资源 | 说明 |
|---|---|
| 配置文件参考 | 完整的配置选项文档 |
| 工具参考 | 所有可用工具的详细说明 |
| LSP 集成 | LSP 配置高级指南 |
| MCP 集成 | MCP 服务器配置指南 |
| 技能开发 | 创建自定义 Agent Skills |
获取帮助
- GitHub Issues - 报告问题和建议功能
- Slack - 加入社区讨论
- Discord - 即时交流
- Mastodon - 关注更新动态
资料来源:README.md:1-20
系统架构
Crush 是一个基于终端的 AI 编程助手,采用客户端-服务器(Client-Server)架构设计。该架构允许终端界面与核心处理逻辑分离,支持多工作区管理和实时事件流传输。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
整体架构概览
Crush 的系统架构由以下几个核心模块组成:
graph TD
subgraph "客户端层 (Client)"
TUI[终端用户界面]
SDK[Client SDK]
end
subgraph "服务端层 (Server)"
HTTP[HTTP Server]
WS[WebSocket Handler]
API[REST API Controllers]
end
subgraph "业务逻辑层 (Backend)"
BE[Backend 核心]
WS_Manager[Workspace Manager]
Agent[Agent 处理]
end
subgraph "集成层 (Integrations)"
LSP[LSP 集成]
MCP[MCP 集成]
Permission[权限系统]
end
TUI <--> SDK
SDK <--> HTTP
SDK <--> WS
HTTP --> API
API --> BE
BE --> WS_Manager
BE --> Agent
BE --> LSP
BE --> MCP
BE --> Permission
LSP <--> LSP_Server[Language Server]
MCP <--> MCP_Server[MCP Server]核心组件
1. App 模块
App 模块是 Crush 应用程序的主入口,负责全局生命周期管理和清理函数注册。
| 组件 | 文件 | 职责 |
|---|---|---|
| App | internal/app/app.go | 全局应用状态管理 |
| testing | internal/app/testing.go | 测试环境支持 |
| lsp_events | internal/app/lsp_events.go | LSP 事件订阅与分发 |
关键特性:
- 清理函数注册:通过
cleanupFuncs切片管理资源释放回调 - 测试支持:
ShutdownForTest()方法提供测试专用的清理路径 - LSP 事件系统:基于
pubsub.Broker的发布订阅机制
// internal/app/testing.go:7-11
func (app *App) ShutdownForTest() {
for _, cleanup := range app.cleanupFuncs {
if cleanup != nil {
_ = cleanup(context.Background())
}
}
app.cleanupFuncs = nil
}
资料来源:internal/app/testing.go:7-11
2. Backend 模块
Backend 是 Crush 的核心业务逻辑层,负责工作区管理和客户端状态追踪。
| 组件 | 文件 | 职责 |
|---|---|---|
| backend.go | internal/backend/backend.go | 核心业务逻辑 |
| backend_test.go | internal/backend/backend_test.go | 单元测试 |
关键数据结构:
type Workspace struct {
ID string
Path string
resolvedPath string
clients map[string]*clientState
shutdownFn func()
}
资料来源:internal/backend/backend_test.go:22-29
工作区生命周期管理:
- 创建:通过
NewWorkspace创建独立工作区 - 注册客户端:使用
registerClient追踪活跃连接 - 持有机制:
releaseHold控制工作区何时被销毁
sequenceDiagram
participant C as Client
participant B as Backend
participant W as Workspace
C->>B: registerClient(ws, clientID)
C->>B: AttachClient(ws.ID, clientID)
C->>B: releaseHold(ws.ID, clientID)
alt 有活跃流
B->>W: 保持 Workspace
else 无活跃流
B->>W: 调用 shutdownFn
W->>B: 清理资源
end3. Server 模块
Server 模块实现 HTTP API 接口,支持 REST 和 SSE(Server-Sent Events)两种通信模式。
| 组件 | 文件 | 职责 |
|---|---|---|
| server.go | internal/server/server.go | HTTP 服务器启动与路由 |
| events.go | internal/server/events.go | 事件类型转换 |
| proto.go | internal/server/proto.go | API 控制器实现 |
事件类型转换链:
// internal/server/events.go:1-25
// 支持的事件类型:
// - LSPEvent: 语言服务器协议事件
// - MCPEvent: 模型上下文协议事件
// - PermissionRequest: 权限请求事件
// - PermissionNotification: 权限通知事件
主要 API 端点:
| 端点 | 方法 | 功能 |
|---|---|---|
/workspaces | GET | 列出所有工作区 |
/workspaces/:id | GET | 获取工作区详情 |
/workspaces/:id/config | GET/PUT | 配置管理 |
/workspaces/:id/agent/sessions/:sid/summarize | POST | 会话摘要 |
/workspaces/:id/agent/init | POST | 初始化 Agent |
/control | POST | 服务器控制命令 |
资料来源:internal/server/proto.go:1-20
4. Client 模块
Client 模块提供 SDK 供外部应用集成 Crush 功能。
| 组件 | 文件 | 职责 |
|---|---|---|
| client.go | internal/client/client.go | HTTP 客户端基类 |
| config.go | internal/client/config.go | 配置与 MCP 交互 |
| proto.go | internal/client/proto.go | 协议消息处理 |
MCP 资源访问:
// internal/client/config.go:1-20
type MCPResourceContents struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
URI string `json:"uri,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
API Key 管理:
Client 支持多种凭证类型的安全传输:
// internal/client/config.go - SetProviderAPIKey
// 支持的 API Key 类型:
// - Anthropic
// - OpenAI
// - Google Gemini
// - 其他自定义提供商
资料来源:internal/client/config.go:1-20
5. LSP 集成
LSP(Language Server Protocol)集成提供项目级代码上下文感知能力。
| 文件 | 职责 |
|---|---|
internal/app/lsp_events.go | LSP 事件定义与分发 |
LSP 事件类型:
const (
LSPEventStateChanged LSPEventType = "state_changed"
LSPEventDiagnosticsChanged LSPEventType = "diagnostics_changed"
)
LSP 状态管理:
// internal/app/lsp_events.go:28-35
type LSPClientInfo struct {
Name string
State lsp.ServerState
Error error
Client *lsp.Client
DiagnosticCount int
ConnectedAt time.Time
}
使用 csync.NewMap 实现线程安全的并发访问:
var lspStates = csync.NewMap[string, LSPClientInfo]()
var lspBroker = pubsub.NewBroker[LSPEvent]()
资料来源:internal/app/lsp_events.go:1-35
客户端-服务器通信架构
实验性架构
Crush 正在推进客户端-服务器架构的重构,可通过环境变量 CRUSH_CLIENT_SERVER=1 启用实验性功能。
资料来源:社区讨论 - v0.68.0
事件流处理
graph LR
subgraph "服务端"
E[Event Source]
T[Type Conversion]
W[Wire Format]
end
subgraph "传输层"
S[JSON over HTTP/SSE]
end
subgraph "客户端"
P[Parse]
R[Application]
end
E --> T
T --> W
W --> S
S --> P
P --> R事件序列化示例:
// internal/server/events.go - skillsEventToProto
func skillsEventToProto(e skills.Event) proto.SkillsEvent {
out := proto.SkillsEvent{States: make([]proto.SkillState, len(e.States))}
for i, s := range e.States {
entry := proto.SkillState{
Name: s.Name,
Path: s.Path,
State: proto.SkillDiscoveryState(s.State),
}
if s.Err != nil {
entry.Error = s.Err.Error()
}
out.States[i] = entry
}
return out
}
工作区管理
Workspace 结构
type Workspace struct {
ID string // 唯一标识符 (UUID)
Path string // 用户指定路径
resolvedPath string // 解析后的绝对路径
clients map[string]*clientState // 活跃客户端映射
shutdownFn func() // 清理回调
}
资料来源:internal/backend/backend_test.go:22-29
路径解析与符号链接
Backend 模块实现了智能路径解析:
- 解析符号链接到真实路径
- 对不存在的路径自动创建
- 支持工作区路径索引映射
// internal/backend/backend_test.go - 测试用例
func TestResolveWorkspaceKey_AbsoluteAndSymlink(t *testing.T) {
tmp := t.TempDir()
real, err := filepath.EvalSymlinks(tmp)
got, err := resolveWorkspaceKey(tmp)
require.Equal(t, real, got)
}
资料来源:internal/backend/backend_test.go:37-46
权限系统
Crush 实现细粒度的权限控制机制,支持运行时权限请求和审批流程。
| 事件类型 | 说明 |
|---|---|
| PermissionRequest | 工具调用前的权限请求 |
| PermissionNotification | 权限状态变更通知 |
权限请求结构:
// internal/server/events.go
type PermissionRequest struct {
ID string
SessionID string
ToolCallID string
ToolName string
Description string
Action string
Path string
Params map[string]any
}
配置系统
配置优先级
.crush.json(项目本地)crush.json(项目根目录)$HOME/.config/crush/crush.json(用户全局)
环境变量覆盖
| 变量 | 说明 |
|---|---|
CRUSH_GLOBAL_CONFIG | 覆盖配置文件路径 |
CRUSH_GLOBAL_DATA | 覆盖数据目录路径 |
CRUSH_CLIENT_SERVER | 启用实验性客户端-服务器模式 |
常见问题与社区反馈
架构相关问题
| Issue | 问题 | 状态 |
|---|---|---|
| #2935 | 多权限模式切换(Yolo/Safe/Custom) | 功能请求 |
| #928 | Bash 命令安全限制 | 用户反馈 |
| #2898 | 全局 LSP 配置不生效 | 问题报告 |
| #2903 | 数据库损坏问题 | 问题报告 |
稳定性改进
v0.68.0 版本对客户端-服务器架构进行了大量修复,显著提升了稳定性。
资料来源:社区讨论 - v0.68.0
扩展机制
LSP 支持
配置示例:
{
"lsp": {
"go": {
"command": "gopls",
"env": { "GOTOOLCHAIN": "go1.24.5" }
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
}
}
}
MCP 支持
支持三种传输类型:
stdio:命令行服务器http:HTTP 端点sse:Server-Sent Events
总结
Crush 的系统架构采用分层设计:
- App 层:应用生命周期管理
- Backend 层:核心业务逻辑与工作区管理
- Server 层:HTTP API 与事件分发
- Client 层:SDK 与外部集成
- 集成层:LSP、MCP、权限系统
该架构支持实验性的客户端-服务器模式,允许更灵活的前端实现和更好的资源隔离。
数据流与数据库
Crush 的数据流与数据库系统承担着整个应用的状态管理、事件分发和持久化存储的核心职责。该系统采用模块化架构,将客户端与服务器分离,通过事件驱动的方式实现各组件间的解耦通信。数据库层负责存储会话、消息历史和配置信息,而事件系统则负责在运行时协调 LSP、MCP、权限等子系统的状态变化。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Crush 的数据流与数据库系统承担着整个应用的状态管理、事件分发和持久化存储的核心职责。该系统采用模块化架构,将客户端与服务器分离,通过事件驱动的方式实现各组件间的解耦通信。数据库层负责存储会话、消息历史和配置信息,而事件系统则负责在运行时协调 LSP、MCP、权限等子系统的状态变化。
核心架构
Crush 采用客户端-服务器架构,数据在各组件间通过统一的事件总线流转。客户端负责用户交互和 API 调用,服务器端处理实际的业务逻辑和数据库操作。
graph TD
Client[客户端] -->|HTTP/WebSocket| Server[服务器]
Server -->|事件分发| EventBus[事件总线]
EventBus -->|LSP事件| LSPSub[LSP子系统]
EventBus -->|MCP事件| MCPSub[MCP子系统]
EventBus -->|权限事件| PermSub[权限子系统]
Server -->|持久化| DB[数据库]
Session[会话管理] --> DB
Workspace[工作空间] --> Session事件系统
事件类型与转换
事件系统是 Crush 数据流的核心枢纽。系统定义了多种事件类型,每种事件在客户端与服务器之间通过 Protocol Buffer 进行序列化传输。
// 资料来源:internal/app/lsp_events.go:11-14
const (
LSPEventStateChanged LSPEventType = "state_changed"
LSPEventDiagnosticsChanged LSPEventType = "diagnostics_changed"
)
事件类型映射表
| 事件类型 | 来源文件 | 说明 |
|---|---|---|
LSPEvent | lsp_events.go | 语言服务器状态变化 |
MCPEvent | events.go | MCP 服务器事件 |
PermissionRequest | events.go | 工具调用权限请求 |
PermissionNotification | events.go | 权限通知 |
SkillsEvent | events.go | 技能状态变化 |
Proto 转换机制
事件在跨网络传输前需要转换为 Protocol Buffer 格式。转换逻辑集中在 internal/server/events.go 中:
// 资料来源:internal/server/events.go
func skillsEventToProto(e skills.Event) proto.SkillsEvent {
if len(e.States) == 0 {
return proto.SkillsEvent{}
}
out := proto.SkillsEvent{States: make([]proto.SkillState, len(e.States))}
for i, s := range e.States {
entry := proto.SkillState{
Name: s.Name,
Path: s.Path,
State: proto.SkillDiscoveryState(s.State),
}
if s.Err != nil {
entry.Error = s.Err.Error()
}
out.States[i] = entry
}
return out
}
事件消息转换
消息内容的转换同样遵循统一的 proto 格式:
// 资料来源:internal/server/events.go
func messagesToProto(msgs []message.Message) []proto.Message {
out := make([]proto.Message, len(msgs))
for i, m := range msgs {
out[i] = messageToProto(m)
}
return out
}
会话管理
会话生命周期
会话是 Crush 数据持久化的核心单位。每个工作空间可以包含多个会话,会话存储消息历史、工具调用记录和上下文状态。
graph LR
Create[创建会话] --> Active[活跃状态]
Active -->|上下文满| Summarize[摘要压缩]
Active -->|用户退出| Close[关闭会话]
Active -->|Token刷新| Refresh[刷新认证]
Summarize --> Active客户端注册与注销
// 资料来源:internal/backend/backend_test.go:21-32
func insertTestWorkspace(t *testing.T, b *Backend, key string) (*Workspace, *atomic.Int32) {
var shutdowns atomic.Int32
ws := &Workspace{
ID: uuid.New().String(),
Path: key,
resolvedPath: key,
clients: make(map[string]*clientState),
shutdownFn: func() { shutdowns.Add(1) },
}
b.mu.Lock()
b.workspaces.Set(ws.ID, ws)
b.pathIndex[key] = ws.ID
b.mu.Unlock()
return ws, &shutdowns
}
Hold 机制
为防止最后一个客户端断开时工作空间被意外销毁,Crush 实现了引用计数机制(Hold)。
// 资料来源:internal/backend/backend_test.go:60-75
func TestHoldExpiry_TearsDown(t *testing.T) {
b, srvShutdowns := newTestBackend(t)
ws, wsShutdowns := insertTestWorkspace(t, b, "/tmp/a")
cid := newClientID(t)
b.registerClient(ws, cid)
require.Eventually(t, func() bool {
return wsShutdowns.Load() == 1 && srvShutdowns.Load() == 1
}, 1*time.Second, 5*time.Millisecond)
}
客户端 API
消息列表获取
// 资料来源:internal/client/proto.go
func (c *Client) ListMessages(ctx context.Context, id string, sessionID string) ([]proto.Message, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/sessions/%s/messages", id, sessionID), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get messages: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get messages: status code %d", rsp.StatusCode)
}
var msgs []proto.Message
// ...
}
会话摘要
// 资料来源:internal/client/proto.go
func (c *Client) SummarizeSession(ctx context.Context, id string, sessionID string) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s/summarize", id, sessionID), nil, nil, nil)
if err != nil {
return fmt.Errorf("failed to summarize session: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to summarize session: status code %d", rsp.StatusCode)
}
return nil
}
OAuth 令牌刷新
// 资料来源:internal/client/config.go
func (c *Client) RefreshOAuthToken(ctx context.Context, id string, scope config.Scope, providerID string) error {
// 实现刷新逻辑
}
LSP 事件处理
事件订阅机制
// 资料来源:internal/app/lsp_events.go:40-41
var (
lspStates = csync.NewMap[string, LSPClientInfo]()
lspBroker = pubsub.NewBroker[LSPEvent]()
)
状态查询接口
// 资料来源:internal/app/lsp_events.go:53-58
func GetLSPStates() map[string]LSPClientInfo {
return lspStates.Copy()
}
func GetLSPState(name string) (LSPClientInfo, bool) {
return lspStates.Get(name)
}
MCP 资源与提示
资源获取
// 资料来源:internal/client/config.go
func (c *Client) GetMCPResource(ctx context.Context, id, clientID, serverID, uri string) ([]MCPResourceContents, error) {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/mcp/read-resource", id), nil, jsonBody(struct {
ClientID string `json:"client_id"`
URI string `json:"uri"`
}{Name: name, URI: uri}), http.Header{"Content-Type": []string{"application/json"}})
// ...
}
提示获取
// 资料来源:internal/client/config.go
func (c *Client) GetMCPPrompt(ctx context.Context, id, clientID, promptID string, args map[string]string) (string, error) {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/mcp/get-prompt", id), nil, jsonBody(struct {
ClientID string `json:"client_id"`
PromptID string `json:"prompt_id"`
Args map[string]string `json:"args"`
}{ClientID: clientID, PromptID: promptID, Args: args}), http.Header{"Content-Type": []string{"application/json"}})
// ...
}
权限事件
权限相关事件通过专用的 Payload 类型分发:
// 资料来源:internal/server/events.go
case pubsub.Event[permission.PermissionRequest]:
return envelope(pubsub.PayloadTypePermissionRequest, pubsub.Event[proto.PermissionRequest]{
Type: e.Type,
Payload: proto.PermissionRequest{
ID: e.Payload.ID,
SessionID: e.Payload.SessionID,
ToolCallID: e.Payload.ToolCallID,
ToolName: e.Payload.ToolName,
Description: e.Payload.Description,
Action: e.Payload.Action,
Path: e.Payload.Path,
Params: e.Payload.Params,
},
})
清理与关闭
清理函数注册
应用在启动时注册多个清理函数,确保资源正确释放:
// 资料来源:internal/app/testing.go
func (app *App) ShutdownForTest() {
for _, cleanup := range app.cleanupFuncs {
if cleanup != nil {
_ = cleanup(context.Background())
}
}
app.cleanupFuncs = nil
}
清理流程覆盖:
- 数据库连接释放
- LSP 服务器关闭
- MCP 连接断开
已知问题
社区反馈表明数据库损坏是用户遇到的常见问题之一:
用户在 VM 环境中运行 Crush 时,数据库每隔一到两小时就会损坏,出现 "failed to get session message" 错误。
相关社区议题:数据库损坏问题 #2903
配置与持久化路径
Crush 的配置和数据存储位置可通过环境变量覆盖:
| 环境变量 | 说明 |
|---|---|
CRUSH_GLOBAL_CONFIG | 覆盖全局配置文件路径 |
CRUSH_GLOBAL_DATA | 覆盖全局数据目录路径 |
graph TD
Config[配置文件] --> Priority{配置优先级}
Priority -->|1| Local1[.crush.json]
Priority -->|2| Local2[crush.json]
Priority -->|3| Global[~/.config/crush/crush.json]
Data[数据存储] --> Platform{平台}
Platform -->|Unix| UnixPath[$HOME/.local/share/crush/]
Platform -->|Windows| WinPath[%LOCALAPPDATA%\crush\]测试覆盖
事件系统的测试确保数据在序列化和反序列化过程中不丢失:
// 资料来源:internal/server/events_test.go
func TestSkillsEventToProto_RoundTrip(t *testing.T) {
src := pubsub.Event[skills.Event]{
Type: pubsub.UpdatedEvent,
Payload: skills.Event{
States: []*skills.SkillState{
{Name: "ok", Path: "/p/ok", State: skills.StateNormal},
{Name: "broken", Path: "/p/broken", State: skills.StateError, Err: errors.New("bad frontmatter")},
},
},
}
env := wrapEvent(src)
// 验证往返转换正确性
}
总结
Crush 的数据流与数据库系统通过事件驱动的架构实现了组件间的高效解耦。Protocol Buffer 格式确保了跨网络通信的类型安全,Hold 机制防止了工作空间的意外销毁,而清理函数则保证了资源的正确释放。开发者若需扩展新的事件类型,应遵循 events.go 中定义的转换模式,并在 proto.go 中添加对应的消息类型。
来源:https://github.com/charmbracelet/crush / 项目说明书
Agent 系统
Crush 的 Agent 系统是整个应用的核心组件,负责协调 AI 模型与工作区之间的交互。该系统处理 Agent 消息、会话管理、事件分发等核心功能,支持多客户端同时连接和工作区隔离。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Crush 的 Agent 系统是整个应用的核心组件,负责协调 AI 模型与工作区之间的交互。该系统处理 Agent 消息、会话管理、事件分发等核心功能,支持多客户端同时连接和工作区隔离。
Agent 系统采用客户端-服务器架构,通过 HTTP API 和 Server-Sent Events (SSE) 实现与前端的通信。
架构概览
graph TD
A[Client] -->|HTTP/WebSocket| B[Server Controller]
B --> C[Backend]
C --> D[Agent]
C --> E[Workspace Manager]
C --> F[Event Broker]
F -->|SSE Events| A
D -->|Tool Calls| G[Permission System]
G -->|Approved| H[Tool Executor]
H -->|Results| D
D -->|Messages| I[LLM Provider]
I -->|Responses| D核心组件
Server Controller
internal/server/proto.go 中的 Controller 负责处理 Agent 相关的 HTTP 请求。主要端点包括:
| 端点 | 方法 | 功能 |
|---|---|---|
/workspaces/{id}/agent | POST | 发送 Agent 消息 |
/workspaces/{id}/agent/init | POST | 初始化 Agent 处理 |
/workspaces/{id}/agent/sessions | GET | 列出所有会话 |
/workspaces/{id}/agent/sessions/{sessionID}/summarize | POST | 汇总会话 |
#### 消息处理流程
// handlePostWorkspaceAgent 处理 Agent 消息
// 资料来源:internal/server/proto.go:XX
func (c *controllerV1) handlePostWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
var msg proto.AgentMessage
if err := json.NewDecoder(r.Body).Decode(&msg); err != nil {
c.server.logError(r, "Failed to decode request", "error", err)
jsonError(w, http.StatusBadRequest, "failed to decode request")
return
}
// 使用 WithoutCancel 分离请求生命周期
ctx := context.WithoutCancel(r.Context())
if err := c.backend.SendMessage(ctx, id, msg); err != nil {
c.handleError(w, r, err)
return
}
w.WriteHeader(http.StatusOK)
}
关键设计点:
- 使用
context.WithoutCancel()分离运行生命周期,避免客户端断连导致正在进行的操作被取消 - 只有显式的取消端点才能终止运行
事件系统
事件类型
internal/server/events.go 定义了 Agent 系统支持的事件类型:
case pubsub.Event[proto.AgentEvent]:
return envelope(pubsub.PayloadTypeAgentEvent, pubsub.Event[proto.AgentEvent]{
Type: e.Type,
Payload: proto.AgentEvent{
SessionID: e.Payload.SessionID,
SessionTitle: e.Payload.SessionTitle,
Type: proto.AgentEventType(e.Payload.Type),
},
})
Agent 事件类型
| 事件类型 | 说明 |
|---|---|
AgentEventTypeResponse | Agent 响应事件 |
AgentEventTypeError | Agent 错误事件 |
AgentEventTypeComplete | Agent 完成事件 |
事件封装机制
所有事件通过统一的 envelope 函数进行 JSON 序列化:
// envelope marshals the inner event and wraps it in a pubsub.Payload
// 资料来源:internal/server/events.go:XX
func envelope(payloadType pubsub.PayloadType, inner any) *pubsub.Payload {
raw, err := json.Marshal(inner)
if err != nil {
slog.Error("Failed to marshal event payload", "error", err)
return nil
}
return &pubsub.Payload{
Type: payloadType,
Payload: raw,
}
}
客户端 API
Agent 操作
internal/client/proto.go 提供了完整的 Agent 客户端接口:
#### 发送消息
// SendMessage sends a message to the agent
// 资料来源:internal/client/proto.go:XX
func (c *Client) SendMessage(ctx context.Context, id string, msg proto.AgentMessage) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent", id), nil, jsonBody(msg), http.Header{"Content-Type": []string{"application/json"}})
if err != nil {
return fmt.Errorf("failed to send message: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to send message: status code %d", rsp.StatusCode)
}
return nil
}
#### 初始化 Agent 处理
// InitiateAgentProcessing triggers agent initialization on the server
// 资料来源:internal/client/proto.go:XX
func (c *Client) InitiateAgentProcessing(ctx context.Context, id string) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/init", id), nil, nil, nil)
if err != nil {
return fmt.Errorf("failed to initiate session agent processing: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to initiate session agent processing: status code %d", rsp.StatusCode)
}
return nil
}
#### 会话汇总
// Summarize generates a summary of the conversation
// 资料来源:internal/client/proto.go:XX
func (c *Client) Summarize(ctx context.Context, id, sessionID string) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s/summarize", id, sessionID), nil, nil, nil)
if err != nil {
return fmt.Errorf("failed to summarize session: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to summarize session: status code %d", rsp.StatusCode)
}
return nil
}
配置管理
Agent 配置 API
internal/client/config.go 提供了 Agent 配置相关的 API:
#### 设置默认模型
// SetDefaultAgentModel sets the default agent model
// 资料来源:internal/client/config.go:XX
func (c *Client) SetDefaultAgentModel(ctx context.Context, id string, modelID, providerID string) error {
_, err := c.patch(ctx, fmt.Sprintf("/workspaces/%s/agent/default-model", id),
url.Values{"model_id": []string{modelID}, "provider_id": []string{providerID}}, nil, nil)
if err != nil {
return fmt.Errorf("failed to set default agent model: %w", err)
}
return nil
}
#### 设置默认小型模型
// SetDefaultSmallModel sets the default small model for quick operations
// 资料来源:internal/client/config.go:XX
func (c *Client) SetDefaultSmallModel(ctx context.Context, id, modelID, providerID string) error {
_, err := c.patch(ctx, fmt.Sprintf("/workspaces/%s/agent/default-small-model", id),
url.Values{"model_id": []string{modelID}, "provider_id": []string{providerID}}, nil, nil)
if err != nil {
return fmt.Errorf("failed to set default small model: %w", err)
}
return nil
}
#### 获取默认模型
// GetDefaultSmallModel returns the default small model for the workspace
// 资料来源:internal/client/config.go:XX
func (c *Client) GetDefaultSmallModel(ctx context.Context, id, providerID string) (*config.SelectedModel, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/agent/default-small-model", id), url.Values{"provider_id": []string{providerID}}, nil)
if err != nil {
return nil, fmt.Errorf("failed to get default small model: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get default small model: status code %d", rsp.StatusCode)
}
var model config.SelectedModel
if err := json.NewDecoder(rsp.Body).Decode(&model); err != nil {
return nil, fmt.Errorf("failed to decode default small model: %w", err)
}
return &model, nil
}
事件订阅与分发
LSP 事件集成
虽然 LSP 系统是独立的,但 Agent 系统通过事件总线与其交互:
// LSPEvent represents an event in the LSP system
// 资料来源:internal/app/lsp_events.go:XX
type LSPEvent struct {
Type LSPEventType
Name string
State lsp.ServerState
Error error
DiagnosticCount int
}
事件订阅机制:
// SubscribeLSPEvents returns a channel for LSP events
// 资料来源:internal/app/lsp_events.go:XX
func SubscribeLSPEvents(ctx context.Context) <-chan pubsub.Event[LSPEvent] {
return lspBroker.Subscribe(ctx)
}
消息协议
Agent 消息结构
Agent 消息通过 proto.AgentMessage 类型传输,包含:
| 字段 | 类型 | 说明 |
|---|---|---|
| SessionID | string | 会话标识符 |
| Type | AgentMessageType | 消息类型 |
| Content | string | 消息内容 |
| Metadata | map | 元数据 |
事件有效载荷类型
| 类型 | 说明 | 资料来源 |
|---|---|---|
PayloadTypeAgentEvent | Agent 事件 | internal/server/events.go |
PayloadTypeRunComplete | 运行完成 | internal/server/events.go |
PayloadTypePermissionRequest | 权限请求 | internal/server/events.go |
PayloadTypePermissionNotification | 权限通知 | internal/server/events.go |
工作流程
sequenceDiagram
participant C as Client
participant S as Server
participant B as Backend
participant A as Agent
participant E as Event Broker
C->>S: POST /agent (AgentMessage)
S->>B: SendMessage(ctx, msg)
B->>A: Process Message
A->>A: LLM Inference
A->>A: Tool Execution
A-->>E: AgentEvent
E-->>C: SSE Stream
A-->>B: Response
B-->>S: Result
S-->>C: HTTP 200 OK测试覆盖
事件系统具有完整的测试覆盖:
// TestSkillsEventToProto_RoundTrip verifies that a pubsub.Event[skills.Event]
// can be wrapped, marshaled, and unmarshaled back through the SSE
// envelope without losing state values or error messages
// 资料来源:internal/server/events_test.go:XX
func TestSkillsEventToProto_RoundTrip(t *testing.T) {
t.Parallel()
// 测试事件序列化与反序列化
}
配置选项
Agent 系统支持通过 crush.json 进行配置:
{
"agent": {
"default_model": "claude-sonnet-4-20250514",
"default_small_model": "claude-haiku-4-20250514"
}
}
相关社区讨论
- #990: 支持 Agent Client Protocol 以与 IDE 集成
- #431: 子代理功能请求 - 支持配置子代理及其各自模型
- #372: Claude Code SDK 支持请求
扩展阅读
来源:https://github.com/charmbracelet/crush / 项目说明书
工具系统
Crush 的工具系统是 Agent 与外部环境交互的核心模块,负责执行文件操作、Shell 命令、代码编辑等任务。该系统支持多种工具类型,并通过权限控制机制确保操作安全性。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
系统架构
Crush 采用客户端-服务端架构,工具系统在服务端执行,操作结果通过事件机制通知客户端。
graph TD
A[Agent] -->|工具调用请求| B[服务端工具调度器]
B -->|权限检查| C[权限系统]
C -->|批准/拒绝| D{权限决策}
D -->|批准| E[工具执行器]
D -->|拒绝| F[返回权限拒绝]
E --> G[bash工具]
E --> H[文件编辑工具]
E --> I[写入工具]
E --> J[grep工具]
G -->|事件| K[事件总线]
H --> K
I --> K
J --> K
K -->|SSE推送| L[客户端]权限系统
权限系统是工具安全执行的核心,负责在工具执行前进行授权检查。
权限请求类型
权限系统定义了两种主要的事件类型,用于跟踪工具调用状态:
| 事件类型 | 说明 |
|---|---|
PermissionRequest | 工具执行前的授权请求 |
PermissionNotification | 工具执行完成的通知 |
权限请求数据结构
权限请求包含以下关键字段,用于识别和控制工具操作:
type PermissionRequest struct {
ID string // 唯一请求标识符
SessionID string // 会话标识符
ToolCallID string // 工具调用标识符
ToolName string // 工具名称
Description string // 操作描述
Action string // 请求的操作类型
Path string // 目标路径(如适用)
Params map[string]any // 操作参数
}
资料来源:internal/server/events.go:24-35
权限事件序列化
权限事件通过 protobuf 定义进行序列化,支持在客户端-服务端之间传输:
return envelope(pubsub.PayloadTypePermissionRequest, pubsub.Event[proto.PermissionRequest]{
Type: e.Type,
Payload: proto.PermissionRequest{
ID: e.Payload.ID,
SessionID: e.Payload.SessionID,
ToolCallID: e.Payload.ToolCallID,
ToolName: e.Payload.ToolName,
Description: e.Payload.Description,
Action: e.Payload.Action,
Path: e.Payload.Path,
Params: e.Payload.Params,
},
})
资料来源:internal/server/events.go:34-47
内置工具类型
Bash 工具
Bash 工具允许 Agent 执行 Shell 命令,是与系统交互的主要方式。
社区关注点: 用户反馈当前对 bash 命令存在安全限制,阻止了 curl、wget、ssh、sudo 等命令的执行,这影响了开发测试工作流。
参考:Issue #928 - Remove bash command security limits for unrestricted terminal access
已知问题: 在 v0.74.1 版本中修复了交互式命令(如 git rebase -i)导致的 bash 工具挂起问题。
文件编辑工具
支持对文件内容进行编辑操作,包括行级修改和内容替换。
文件写入工具
提供完整的文件写入能力,用于创建新文件或覆盖现有文件内容。
Grep 工具
实现代码搜索功能,支持在项目中查找指定模式的内容。
Safe 模式工具
提供额外的安全检查层,在执行敏感操作前进行额外验证。
工具配置
权限模式配置
在 crush.json 中通过 permissions.yolo 开关控制权限模式:
{
"$schema": "https://charm.land/crush.json",
"permissions": {
"yolo": false
}
}
| 模式 | 说明 |
|---|---|
yolo: true | 启用全自动化批准,所有工具调用无需确认 |
yolo: false | 启用安全模式,每项操作需用户确认 |
社区需求: Issue #2935 请求支持在运行时动态切换权限配置文件(Yolo、Safe、Custom),而无需重启会话。
参考:Issue #2935 - Feature: Multiple permission profiles/modes switchable at runtime
MCP 工具集成
Crush 支持通过 Model Context Protocol (MCP) 扩展工具集。MCP 服务器通过三种传输类型连接:
| 传输类型 | 说明 |
|---|---|
stdio | 命令行服务器模式 |
http | HTTP 端点模式 |
sse | Server-Sent Events 模式 |
MCP 工具调用通过客户端 API 执行:
// 获取 MCP 资源
func (c *Client) GetMCPResource(ctx context.Context, id, clientID, resourceID string) ([]MCPResourceContents, error)
// 获取 MCP 提示
func (c *Client) GetMCPPrompt(ctx context.Context, id, clientID, promptID string, args map[string]string) (string, error)
资料来源:internal/client/config.go:85-110
事件驱动通信
工具执行状态通过发布-订阅模式在系统内传播,客户端通过 SSE 连接接收实时更新。
sequenceDiagram
participant A as Agent
participant E as 事件总线
participant S as SSE服务端
participant C as 客户端
A->>E: 发布工具事件
E->>S: 事件推送
S->>C: SSE Stream
C-->>A: 用户反馈工具计数事件
MCP 工具事件携带工具计数信息:
case pubsub.Event[mcp.Event]:
return envelope(pubsub.PayloadTypeMCPEvent, pubsub.Event[proto.MCPEvent]{
Type: e.Type,
Payload: proto.MCPEvent{
Type: mcpEventTypeToProto(e.Payload.Type),
Name: e.Payload.Name,
State: proto.MCPState(e.Payload.State),
Error: e.Payload.Error,
ToolCount: e.Payload.Counts.Tools,
},
})
资料来源:internal/server/events.go:21-33
API 密钥管理
工具系统中的外部服务调用需要相应的 API 密钥支持:
| 环境变量 | 提供商 |
|---|---|
OPENAI_API_KEY | OpenAI |
ANTHROPIC_API_KEY | Anthropic |
OPENROUTER_API_KEY | OpenRouter |
OPENCODE_API_KEY | OpenCode |
DEEPSEEK_API_KEY | DeepSeek |
客户端提供设置提供商 API 密钥的方法:
func (c *Client) SetProviderAPIKey(ctx context.Context, id string, scope config.Scope, providerID string, apiKey any) error
资料来源:internal/client/config.go:145-170
错误处理与状态管理
工具执行可能遇到多种错误情况,系统通过事件机制传播错误状态:
type LSPEvent struct {
Type LSPEventType
Name string
State lsp.ServerState
Error error
DiagnosticCount int
}
资料来源:internal/app/lsp_events.go:24-30
最佳实践
- 安全优先:在公共或共享环境中使用
yolo: false模式,防止未经授权的操作 - 渐进式配置:从安全模式开始,逐步添加可信工具到白名单
- 会话隔离:每个工作区维护独立的权限上下文
- 错误监控:通过事件订阅机制实时监控工具执行状态
技能系统
Crush 的技能系统(Skills System)是一个扩展代理能力的框架,基于 Agent Skills 开放标准实现。技能系统允许用户通过可复用的技能包来扩展 Crush 的功能,这些技能包以包含 SKILL.md 说明文件的文件夹形式存在,Crush 可以按需发现和激活这些技能。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Crush 的技能系统(Skills System)是一个扩展代理能力的框架,基于 Agent Skills 开放标准实现。技能系统允许用户通过可复用的技能包来扩展 Crush 的功能,这些技能包以包含 SKILL.md 说明文件的文件夹形式存在,Crush 可以按需发现和激活这些技能。
技能系统的核心设计目标是:
- 模块化扩展:通过独立技能包扩展代理能力
- 按需激活:技能在需要时被发现和加载,而非全部预加载
- 多路径支持:支持全局技能路径和项目本地路径
- 跨平台兼容:支持 Unix、Windows 等多平台文件系统布局
技能发现机制
技能搜索路径
Crush 在多个位置搜索技能包,按照优先级和作用域分类。
#### 全局技能路径
| 环境变量/路径 | 描述 |
|---|---|
$CRUSH_SKILLS_DIR | 用户指定的技能目录 |
$XDG_CONFIG_HOME/agents/skills | Agent Skills 标准目录 |
$XDG_CONFIG_HOME/crush/skills | Crush 专用技能目录 |
~/.agents/skills/ | Claude 兼容路径 |
~/.claude/skills/ | Claude 兼容路径 |
Windows: %LOCALAPPDATA%\agents\skills\ | Windows 全局路径 |
Windows: %LOCALAPPDATA%\crush\skills\ | Windows Crush 专用 |
配置来源:README.md
#### 项目本地技能路径
| 相对路径 | 描述 |
|---|---|
.agents/skills | 标准 agent 技能目录 |
.crush/skills | Crush 项目目录 |
.claude/skills | Claude 兼容目录 |
.cursor/skills | Cursor IDE 兼容目录 |
项目本地技能路径支持项目级别的技能共享,无需全局安装。
#### 自定义技能路径
可通过配置文件指定额外的技能搜索路径:
{
"$schema": "https://charm.land/crush.json",
"options": {
"skills_paths": [
"~/.config/crush/skills",
"./project-skills"
]
}
}
技能包结构
技能包是一个文件夹,包含至少一个 SKILL.md 文件:
skill-name/
└── SKILL.md # 必需:技能说明文件
SKILL.md 文件包含技能的指令说明,Crush 会读取并使用这些内容来理解和执行技能任务。
技能状态管理
状态数据结构
技能状态通过 skills.Event 和 skills.SkillState 类型管理:
type SkillState struct {
Name string // 技能名称
Path string // 技能路径
State SkillDiscoveryState // 发现状态
Err error // 错误信息(如果有)
}
技能发现状态
| 状态值 | 描述 |
|---|---|
StateNormal | 技能正常加载 |
StateError | 技能加载失败,包含错误信息 |
配置来源:internal/server/events.go:71-72
事件通知机制
技能系统通过事件发布订阅机制通知状态变更:
type SkillsEvent struct {
States []SkillState // 所有技能的状态列表
}
当技能发现过程完成或发生变化时,系统发布 SkillsEvent,客户端可以订阅这些事件以更新 UI。
配置来源:internal/server/events.go:64-76
技能事件序列化
技能事件在客户端-服务器通信中需要进行序列化。以下函数负责将内部事件转换为协议缓冲区格式:
func skillsEventToProto(e skills.Event) proto.SkillsEvent {
if len(e.States) == 0 {
return proto.SkillsEvent{}
}
out := proto.SkillsEvent{States: make([]proto.SkillState, len(e.States))}
for i, s := range e.States {
entry := proto.SkillState{
Name: s.Name,
Path: s.Path,
State: proto.SkillDiscoveryState(s.State),
}
if s.Err != nil {
entry.Error = s.Err.Error()
}
out.States[i] = entry
}
return out
}
配置来源:internal/server/events.go:95-111
往返序列化测试
技能事件支持完整的往返序列化:
func TestSkillsEventToProto_RoundTrip(t *testing.T) {
src := pubsub.Event[skills.Event]{
Type: pubsub.UpdatedEvent,
Payload: skills.Event{
States: []*skills.SkillState{
{Name: "ok", Path: "/p/ok", State: skills.StateNormal},
{Name: "broken", Path: "/p/broken", State: skills.StateError, Err: errors.New("bad frontmatter")},
},
},
}
// 测试事件包装、序列化、反序列化过程
}
配置来源:internal/server/events_test.go:89-106
内置技能
Crush 附带了一些内置技能:
| 技能名称 | 功能描述 |
|---|---|
crush-config | 配置 Crush 本身 |
禁用内置技能
可以通过配置禁用内置技能:
{
"$schema": "https://charm.land/crush.json",
"options": {
"disabled_skills": ["crush-config"]
}
}
配置来源:README.md
技能管理器架构
graph TD
A[技能管理器] --> B[技能目录 Catalog]
A --> C[技能发现器 Discoverer]
A --> D[技能加载器 Loader]
A --> E[事件发布器 Broker]
B --> F[全局路径]
B --> G[项目路径]
B --> H[自定义路径]
E --> I[Server-Sent Events]
E --> J[WebSocket]
C --> K[文件系统扫描]
C --> L[SKILL.md 解析]配置选项汇总
| 配置项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
skills_paths | []string | [] | 额外的技能搜索路径 |
disabled_skills | []string | [] | 禁用的内置技能列表 |
常见问题
技能路径环境变量
可以通过设置 CRUSH_SKILLS_DIR 环境变量指定额外的技能目录:
export CRUSH_SKILLS_DIR=/path/to/my/skills
Windows 路径兼容性
Windows 平台使用 %LOCALAPPDATA% 变量,配置文件示例:
{
"options": {
"skills_paths": [
"%LOCALAPPDATA%\\crush\\skills"
]
}
}
配置来源:README.md
技能加载失败处理
当技能 SKILL.md 文件格式错误或路径不可访问时,该技能会标记为 StateError 状态,错误信息通过 Err 字段传递。单个技能加载失败不会影响其他技能。
来源:https://github.com/charmbracelet/crush / 项目说明书
配置系统
Crush 的配置系统负责管理应用程序的全局设置、用户偏好、模型提供者和运行时选项。该系统采用分层配置架构,支持本地项目和全局配置的优先级覆盖,同时提供灵活的环境变量扩展机制。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
配置架构概述
Crush 的配置系统采用三层架构设计,各层之间按优先级从高到低覆盖,形成统一配置视图。
配置层级
| 层级 | 配置文件位置 | 优先级 | 作用域 |
|---|---|---|---|
| 本地项目配置 | .crush.json | 最高 | 当前项目目录 |
| 工作目录配置 | crush.json | 中 | 执行命令的工作目录 |
| 全局用户配置 | ~/.config/crush/crush.json | 最低 | 当前用户所有项目 |
配置加载时会按上述顺序搜索配置文件,相同键值在高优先级配置中出现时将覆盖低优先级配置。资料来源:README.md
数据存储位置
除了 JSON 配置文件外,Crush 还使用以下数据存储路径:
| 操作系统 | 用户数据目录 | 全局配置覆盖变量 |
|---|---|---|
| Unix/Linux | $HOME/.local/share/crush/crush.json | CRUSH_GLOBAL_DATA |
| Windows | %LOCALAPPDATA%\crush\crush.json | CRUSH_GLOBAL_DATA |
| Unix/Linux | $HOME/.config/crush/crush.json | CRUSH_GLOBAL_CONFIG |
| Windows | %APPDATA%\crush\crush.json | CRUSH_GLOBAL_CONFIG |
环境变量 CRUSH_GLOBAL_CONFIG 和 CRUSH_GLOBAL_DATA 可分别覆盖全局配置和用户数据存储路径。资料来源:README.md
配置加载流程
配置加载由 internal/config/load.go 模块处理,采用懒加载和缓存机制确保性能。
加载流程图
graph TD
A[启动 Crush] --> B{检查缓存}
B -->|缓存未命中| C[查找配置文件]
C --> D[搜索 .crush.json]
C --> E[搜索 crush.json]
C --> F[搜索 ~/.config/crush/crush.json]
D --> G{找到配置文件?}
E --> G
F --> G
G -->|是| H[合并配置层级]
G -->|否| I[使用空配置]
H --> J[展开环境变量]
J --> K[缓存配置对象]
I --> K
K --> L[返回 Config 结构]配置加载器会递归合并各层级的配置对象,使用 JSON Schema 验证配置格式。资料来源:internal/config/load.go
配置结构
核心配置项
Crush 的配置文件采用 JSON 格式,支持以下顶层配置块:
{
"$schema": "https://charm.land/crush.json",
"providers": {},
"lsp": {},
"mcp": {},
"options": {},
"permissions": {},
"hooks": {}
}
| 配置块 | 类型 | 说明 |
|---|---|---|
providers | object | AI 模型提供者配置 |
lsp | object | 语言服务器协议配置 |
mcp | object | Model Context Protocol 配置 |
options | object | 全局运行选项 |
permissions | object | 权限控制配置 |
hooks | object | 钩子脚本配置 |
资料来源:schema.json
提供者配置
提供者(Provider)是 Crush 与各种 AI 模型服务交互的核心组件。
内置提供者支持
Crush 支持以下内置 AI 模型提供者,通过相应的环境变量配置 API 密钥:
| 环境变量 | 提供者 |
|---|---|
ANTHROPIC_API_KEY | Anthropic (Claude) |
OPENAI_API_KEY | OpenAI |
DEEPSEEK_API_KEY | Deepseek |
OPENROUTER_API_KEY | OpenRouter |
GOOGLE_API_KEY / GEMINI_API_KEY | Google Gemini |
VERTEXAI_PROJECT / VERTEXAI_LOCATION | Google VertexAI |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY | Amazon Bedrock (Claude) |
AZURE_OPENAI_API_ENDPOINT | Azure OpenAI |
GROQ_API_KEY | Groq |
HF_TOKEN | Hugging Face Inference |
CEREBRAS_API_KEY | Cerebras |
OPENCODE_API_KEY | OpenCode Zen & Go |
HYPER_API_KEY | Hyper (Charm) |
资料来源:README.md
自定义提供者
Crush 支持通过配置文件定义自定义提供者,分为 OpenAI 兼容和 Anthropic 兼容两种类型:
#### OpenAI 兼容 API
{
"providers": {
"deepseek": {
"type": "openai-compat",
"base_url": "https://api.deepseek.com/v1",
"api_key": "$DEEPSEEK_API_KEY"
}
}
}
注意:选择正确的类型非常重要。使用openai类型用于通过 OpenAI 代理或路由的请求,使用openai-compat类型用于非 OpenAI 但提供 OpenAI 兼容 API 的提供商。资料来源:README.md
#### Anthropic 兼容 API
{
"providers": {
"custom-anthropic": {
"type": "anthropic-compat",
"base_url": "https://your-custom-endpoint.com/v1",
"api_key": "$CUSTOM_ANTHROPIC_KEY"
}
}
}
LSP 配置
语言服务器协议(LSP)配置使 Crush 能够获取额外的上下文信息来辅助决策。
LSP 配置示例
{
"lsp": {
"go": {
"command": "gopls",
"env": {
"GOTOOLCHAIN": "go1.24.5"
}
},
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"]
},
"nix": {
"command": "nil"
}
}
}
每个 LSP 服务器配置包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
command | string | LSP 服务器可执行命令 |
args | array | 命令行参数 |
env | object | 环境变量 |
root_markers | array | 工作目录标记文件 |
filetypes | array | 支持的文件类型 |
已知问题:社区反馈全局 LSP 配置有时不生效,需要确保配置文件位于正确路径 ~/.config/crush/crush.json。资料来源:README.md
MCP 配置
Model Context Protocol (MCP) 配置支持三种传输类型:
| 传输类型 | 说明 | 使用场景 |
|---|---|---|
stdio | 标准输入输出 | 命令行 MCP 服务器 |
http | HTTP 请求 | REST API 端点 |
sse | Server-Sent Events | 实时事件流 |
Shell 变量扩展
MCP 配置支持完整的 Shell 风格变量扩展:
{
"mcp": {
"github": {
"command": "uvx",
"args": ["mcp-github", "--token", "$GITHUB_TOKEN"]
}
}
}
支持的扩展语法包括:
$VAR- 基本变量引用${VAR:-default}- 带默认值的变量$(command)- 命令替换- 嵌套引用和转义
变量扩展通过 Crush 内置的 Shell 解释器执行,确保在 Windows 和 Unix 系统上行为一致。资料来源:README.md
选项配置
options 配置块控制 Crush 的运行时行为。
可用选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
compact | boolean | false | 紧凑模式,减少输出 |
no_env_expansion | boolean | false | 禁用环境变量扩展 |
no_output | boolean | false | 禁用所有输出 |
verbose | boolean | false | 详细输出模式 |
hooks_path | string | - | 自定义钩子脚本路径 |
skills_paths | array | - | 技能目录路径列表 |
disabled_skills | array | - | 禁用的技能列表 |
trailer_style | string | "assisted-by" | 提交消息归属风格 |
generated_with | boolean | true | 添加生成标记 |
提交消息归属风格
| 值 | 效果 |
|---|---|
assisted-by | 添加 Assisted-by: Crush:[ModelID] |
co-authored-by | 添加 Co-Authored-By: Crush <[email protected]> |
none | 不添加归属信息 |
资料来源:README.md
权限配置
权限系统控制工具调用的安全策略。
当前限制
当前版本仅支持全局 permissions.yolo 开关,无法在运行时动态切换权限模式。社区有计划实现多权限配置文件(Yolo、Safe、Custom)在运行时切换的功能。资料来源:社区 Issue #2935
权限配置示例
{
"permissions": {
"yolo": true
}
}
当 yolo 设置为 true 时,所有工具调用将被自动批准,无需用户确认。
技能配置
Crush 支持 Agent Skills 开放标准,通过技能包扩展代理能力。
技能搜索路径
系统按以下顺序搜索技能目录:
| 优先级 | 路径(Unix) | 路径(Windows) |
|---|---|---|
| 1 | $CRUSH_SKILLS_DIR | $CRUSH_SKILLS_DIR |
| 2 | $XDG_CONFIG_HOME/agents/skills | %LOCALAPPDATA%\agents\skills |
| 3 | $XDG_CONFIG_HOME/crush/skills | %LOCALAPPDATA%\crush\skills |
| 4 | ~/.agents/skills | %USERPROFILE%\.agents\skills |
| 5 | ~/.claude/skills | %USERPROFILE%\.claude\skills |
| 6 | 自定义 skills_paths | 自定义 skills_paths |
项目本地技能路径:
.agents/skills.crush/skills.claude/skills.cursor/skills
自定义技能路径配置
{
"options": {
"skills_paths": [
"~/.config/crush/skills",
"./project-skills"
]
}
}
配置验证
Crush 配置文件遵循 JSON Schema 规范,位于项目根目录的 schema.json。
Schema 验证
使用 $schema 字段声明配置文件的规范版本:
{
"$schema": "https://charm.land/crush.json",
"options": {
"disabled_skills": ["crush-config"]
}
}
IDE 可利用 schema 提供自动补全和配置验证功能。资料来源:schema.json
客户端-服务端配置同步
当启用实验性的客户端-服务端架构(CRUSH_CLIENT_SERVER=1)时,配置通过 HTTP API 同步。
客户端配置 API
| 方法 | 端点 | 功能 |
|---|---|---|
| GET | /config | 获取全局服务器配置 |
| POST | /workspaces/{id}/config/preferred-model | 设置首选模型 |
| POST | /workspaces/{id}/config/compact | 设置紧凑模式 |
| POST | /workspaces/{id}/config/provider-api-key | 设置提供者 API 密钥 |
API 密钥类型处理
客户端使用显式类型标记 API 密钥,确保跨 Socket 传输时正确解码:
switch v := apiKey.(type) {
case string:
kind = proto.APIKeyKindApiKey
case *oauth2.Token:
kind = proto.APIKeyKindOAuthToken
}
资料来源:internal/client/config.go
配置示例
完整配置示例
{
"$schema": "https://charm.land/crush.json",
"providers": {
"deepseek": {
"type": "openai-compat",
"base_url": "https://api.deepseek.com/v1",
"api_key": "$DEEPSEEK_API_KEY"
},
"custom": {
"type": "anthropic-compat",
"base_url": "https://api.custom.com/v1",
"api_key": "$CUSTOM_API_KEY"
}
},
"lsp": {
"go": {
"command": "gopls",
"env": {
"GOTOOLCHAIN": "auto"
}
}
},
"options": {
"skills_paths": [
"~/.config/crush/skills"
],
"trailer_style": "assisted-by",
"generated_with": true
},
"permissions": {
"yolo": false
}
}
最佳实践
- 使用 Schema:在配置文件中声明
$schema以获得 IDE 自动补全支持 - 环境变量:敏感信息(如 API 密钥)应使用环境变量引用
- 项目级配置:项目特定配置放在
.crush.json,避免污染全局配置 - 权限策略:生产环境建议关闭
yolo模式,使用安全权限策略 - LSP 配置:为常用编程语言配置 LSP 以提升上下文理解能力
资料来源:schema.json
LSP 与 MCP 集成
Crush 通过集成 LSP (Language Server Protocol) 和 MCP (Model Context Protocol) 两大协议,实现了强大的代码上下文理解和工具扩展能力。LSP 为 Crush 提供代码诊断、符号解析等语言服务功能,而 MCP 则允许通过外部服务器扩展工具、资源和提示词能力。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Crush 通过集成 LSP (Language Server Protocol) 和 MCP (Model Context Protocol) 两大协议,实现了强大的代码上下文理解和工具扩展能力。LSP 为 Crush 提供代码诊断、符号解析等语言服务功能,而 MCP 则允许通过外部服务器扩展工具、资源和提示词能力。
这两套系统共享统一的事件发布订阅机制,能够在服务端和客户端之间高效传递状态变化信息。 资料来源:internal/app/lsp_events.go:1-20
架构设计
整体架构图
graph TB
subgraph "客户端层"
CLI[CLI 客户端]
WEB[Web 客户端]
end
subgraph "服务端层"
SERVER[HTTP Server]
BACKEND[Backend]
end
subgraph "集成层"
LSP_MGR[LSP Manager]
MCP[MCP 运行时]
end
subgraph "协议层"
LSP[LSP Clients]
STDIO[stdio 传输]
HTTP[HTTP 传输]
SSE[SSE 传输]
end
CLI --> SERVER
WEB --> SERVER
SERVER --> BACKEND
BACKEND --> LSP_MGR
BACKEND --> MCP
LSP_MGR --> LSP
MCP --> STDIO
MCP --> HTTP
MCP --> SSE核心组件
| 组件 | 位置 | 职责 |
|---|---|---|
| LSPManager | internal/lsp/manager.go | 管理多个 LSP 客户端生命周期 |
| LSPClient | internal/lsp/client.go | 与单个语言服务器通信 |
| MCPRuntime | internal/agent/tools/mcp/ | 管理 MCP 服务器连接 |
| LSPBroker | internal/app/lsp_events.go | 分发 LSP 事件 |
| MCPTool | internal/agent/tools/mcp/tools.go | MCP 工具调用封装 |
LSP 集成
功能特性
LSP 集成使 Crush 能够获取语言的诊断信息、代码结构等上下文,帮助 AI 模型做出更准确的决策。主要功能包括:
- 多语言支持:可同时管理多个 LSP 客户端
- 实时诊断:接收并展示代码诊断信息
- 状态追踪:监控 LSP 服务器连接状态
- 热配置:支持在工作空间中动态启动/停止 LSP 服务器
事件系统
LSP 事件通过 pubsub.Broker 进行分发,支持两种事件类型:
| 事件类型 | 说明 |
|---|---|
state_changed | LSP 服务器状态变更(连接/断开/错误) |
diagnostics_changed | 诊断信息更新 |
// internal/app/lsp_events.go:14-19
type LSPEvent struct {
Type LSPEventType
Name string
State lsp.ServerState
Error error
DiagnosticCount int
}
客户端状态管理
每个 LSP 客户端维护以下状态信息:
// internal/app/lsp_events.go:23-31
type LSPClientInfo struct {
Name string
State lsp.ServerState
Error error
Client *lsp.Client
DiagnosticCount int
ConnectedAt time.Time
}
状态通过 csync.NewMapstring, LSPClientInfo 线程安全存储在内存中。 资料来源:internal/app/lsp_events.go:35-36
工作空间 LSP 操作
服务端暴露了完整的 LSP 管理 API:
// internal/backend/events.go:120-135
func (b *Backend) GetLSPDiagnostics(workspaceID, lspName string) (any, error)
func (b *Backend) LSPStart(ctx context.Context, workspaceID, path string) error
func (b *Backend) LSPStopAll(ctx context.Context, workspaceID string) error
配置方式
在 crush.json 中配置 LSP 服务器:
{
"$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"
},
"deno": {
"command": "deno",
"args": ["lsp"],
"root_markers": ["deno.lock", "deno.json"],
"filetypes": ["js", "ts", "jsx", "tsx", "json"]
}
}
}
注意:LSP 配置目前仅在项目级别生效,不支持全局配置。这与 Issue #2898 中用户反馈的问题一致。
MCP 集成
协议概述
MCP (Model Context Protocol) 是一种用于扩展 AI 代理能力的标准协议。Crush 支持 MCP 服务器的三种传输类型:
| 传输类型 | 说明 | 典型用途 |
|---|---|---|
stdio | 标准输入输出 | 命令行 MCP 服务器 |
http | HTTP REST | Web API 服务器 |
sse | Server-Sent Events | 实时事件推送 |
配置结构
{
"mcp": {
"servers": {
"my-server": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"]
}
}
}
}
Shell 值展开
MCP 配置支持 bash 风格的变量展开:
$VAR:简单变量引用${VAR:-default}:带默认值的变量$(command):命令替换- 引号嵌套
{
"mcp": {
"servers": {
"github": {
"transport": "http",
"url": "https://api.github.com/mcp",
"headers": {
"Authorization": "Bearer $GITHUB_TOKEN"
}
}
}
}
}
展开通过 Crush 内置 shell 执行,Windows 系统也能完美支持。
工具调用流程
sequenceDiagram
participant AI as AI 模型
participant MCP as MCP 运行时
participant Server as MCP 服务器
participant Tool as 工具实现
AI->>MCP: 调用工具 (tool_name, arguments)
MCP->>Server: 发送工具调用请求
Server->>Tool: 执行工具逻辑
Tool-->>Server: 返回结果
Server-->>MCP: 返回响应
MCP-->>AI: 返回工具结果资源访问
MCP 资源通过以下 API 获取:
// internal/client/config.go:45-70
func (c *Client) GetMCPResource(ctx context.Context, id, clientID, resourceID string) ([]MCPResourceContents, error)
返回的资源内容类型包括:
- 文本内容(带 URI)
- 二进制内容(带 MIME 类型和数据)
提示词检索
MCP 服务器可以提供预定义的提示词模板:
// internal/client/config.go:72-95
func (c *Client) GetMCPPrompt(ctx context.Context, id, clientID, promptID string, args map[string]string) (string, error)
事件转换
MCP 事件在服务端和客户端之间传输时需要转换为协议消息:
// internal/server/events.go:45-58
case pubsub.Event[mcp.Event]:
return envelope(pubsub.PayloadTypeMCPEvent, pubsub.Event[proto.MCPEvent]{
Type: e.Type,
Payload: proto.MCPEvent{
Type: mcpEventTypeToProto(e.Payload.Type),
Name: e.Payload.Name,
State: proto.MCPState(e.Payload.State),
Error: e.Payload.Error,
ToolCount: e.Payload.Counts.Tools,
},
})
事件订阅机制
统一事件总线
Crush 使用 pubsub.Broker 作为统一事件分发中心,支持多订阅者模式:
// internal/app/app.go:80-100
func setupSubscriber[T any](
ctx context.Context,
wg *sync.WaitGroup,
name string,
subscriber func(context.Context) <-chan pubsub.Event[T],
broker *pubsub.Broker[tea.Msg],
)
订阅者列表
| 订阅者名称 | 事件源 | 用途 |
|---|---|---|
run | RunManager | 工具执行事件 |
completions | CompletionProvider | 自动补全事件 |
mcp | MCPSubscribeEvents | MCP 状态事件 |
lsp | SubscribeLSPEvents | LSP 状态事件 |
skills | Skills.SubscribeEvents | 技能发现事件 |
故障排除
LSP 相关问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 全局 LSP 配置不生效 | 当前仅支持项目级配置 | 在项目根目录创建 crush.json |
| LSP 服务器启动失败 | 命令路径或参数错误 | 检查 command 和 args 配置 |
| 诊断信息不更新 | 服务器连接断开 | 重启 LSP 服务器 |
MCP 相关问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| MCP 服务器无响应 | 传输类型配置错误 | 确认 transport 设置正确 |
| 变量展开失败 | 环境变量未设置 | 检查所需的 $VAR 环境变量 |
| 资源读取失败 | 服务器不支持资源 | 确认 MCP 服务器实现资源接口 |
调试方法
Error with Openai API: output new_sensitive (1027)
- 启用日志:设置 `R
Please check that you have set the OPENAI_API_KEY environment variable with a valid API key.
来源:https://github.com/charmbracelet/crush / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
Developers may fail before the first successful local run: Status line obscured by onboarding dialog
可能增加新用户试用和生产接入成本。
Developers may misconfigure credentials, environment, or host setup: Qwen 3.7 Max on OpenCode Go Unauthorized Error
Upgrade or migration may change expected behavior: v0.68.0
Pitfall Log / 踩坑日志
项目:charmbracelet/crush
摘要:发现 27 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:安装坑 - 失败模式:installation: Status line obscured by onboarding dialog。
1. 安装坑 · 失败模式:installation: Status line obscured by onboarding dialog
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this installation risk before relying on the project: Status line obscured by onboarding dialog
- 对用户的影响:Developers may fail before the first successful local run: Status line obscured by onboarding dialog
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: Status line obscured by onboarding dialog. Context: Observed when using macos
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_a0f07b57c88e616e55f08e80117c394f | https://github.com/charmbracelet/crush/issues/3044 | Status line obscured by onboarding dialog
2. 安装坑 · 来源证据:Status line obscured by onboarding dialog
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Status line obscured by onboarding dialog
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_e98d3521bdb84c1398a9b2bbf776e5ae | https://github.com/charmbracelet/crush/issues/3044 | 来源讨论提到 macos 相关条件,需在安装/试用前复核。
3. 配置坑 · 失败模式:configuration: Qwen 3.7 Max on OpenCode Go Unauthorized Error
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: Qwen 3.7 Max on OpenCode Go Unauthorized Error
- 对用户的影响:Developers may misconfigure credentials, environment, or host setup: Qwen 3.7 Max on OpenCode Go Unauthorized Error
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: Qwen 3.7 Max on OpenCode Go Unauthorized Error. Context: Observed when using linux
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_9e6004420beb68218b1e13d4bcf43db6 | https://github.com/charmbracelet/crush/issues/3027 | Qwen 3.7 Max on OpenCode Go Unauthorized Error
4. 配置坑 · 失败模式:configuration: v0.68.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.68.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.68.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.68.0. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_bbaee295de66f70f36b7dc8593a9b7bd | https://github.com/charmbracelet/crush/releases/tag/v0.68.0 | v0.68.0
5. 配置坑 · 失败模式:configuration: v0.70.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.70.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.70.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.70.0. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_13d76ec440a4dbc5cec24de4d067e76e | https://github.com/charmbracelet/crush/releases/tag/v0.70.0 | v0.70.0
6. 配置坑 · 失败模式:configuration: v0.71.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.71.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.71.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.71.0. Context: Observed when using python
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_8c04dff267efacde979bed34b0d877cd | https://github.com/charmbracelet/crush/releases/tag/v0.71.0 | v0.71.0
7. 配置坑 · 失败模式:configuration: v0.74.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.74.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.74.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.74.0. Context: Observed when using windows
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_a06bc501b775f717bcff8195feac4cd4 | https://github.com/charmbracelet/crush/releases/tag/v0.74.0 | v0.74.0
8. 配置坑 · 来源证据:Custom provider models are invisible in the TUI
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:Custom provider models are invisible in the TUI
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_fbc15acd4ea14549b9798314e4d6b7df | https://github.com/charmbracelet/crush/issues/3045 | 来源讨论提到 linux 相关条件,需在安装/试用前复核。
9. 配置坑 · 来源证据:Disabled models still appear in the TUI model picker
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:Disabled models still appear in the TUI model picker
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_c8619fe17ed64827934419fb0b4880c7 | https://github.com/charmbracelet/crush/issues/3046 | 来源讨论提到 linux 相关条件,需在安装/试用前复核。
10. 配置坑 · 来源证据:rate limited api requests (429) are not retried
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:rate limited api requests (429) are not retried
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_bc68f6499e6d498fa2fcd70a2c6bdf8f | https://github.com/charmbracelet/crush/issues/3024 | 来源类型 github_issue 暴露的待验证使用条件。
11. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:987670088 | https://github.com/charmbracelet/crush | README/documentation is current enough for a first validation pass.
12. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:987670088 | https://github.com/charmbracelet/crush | last_activity_observed missing
13. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:987670088 | https://github.com/charmbracelet/crush | no_demo; severity=medium
14. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:987670088 | https://github.com/charmbracelet/crush | no_demo; severity=medium
15. 安全/权限坑 · 来源证据:Qwen 3.7 Max on OpenCode Go Unauthorized Error
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Qwen 3.7 Max on OpenCode Go Unauthorized Error
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_446e93f99e5d4dc1adfcc57444e1ef8d | https://github.com/charmbracelet/crush/issues/3027 | 来源讨论提到 linux 相关条件,需在安装/试用前复核。
16. 能力坑 · 失败模式:capability: Custom provider models are invisible in the TUI
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: Custom provider models are invisible in the TUI
- 对用户的影响:Developers may hit a documented source-backed failure mode: Custom provider models are invisible in the TUI
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: Custom provider models are invisible in the TUI. Context: Observed when using linux
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_95736f381b4ee813c4baceb87c276b87 | https://github.com/charmbracelet/crush/issues/3045 | Custom provider models are invisible in the TUI
17. 能力坑 · 失败模式:capability: Disabled models still appear in the TUI model picker
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: Disabled models still appear in the TUI model picker
- 对用户的影响:Developers may hit a documented source-backed failure mode: Disabled models still appear in the TUI model picker
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: Disabled models still appear in the TUI model picker. Context: Observed when using linux
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_07c27ec8a35d211b3baf8f95bdc94049 | https://github.com/charmbracelet/crush/issues/3046 | Disabled models still appear in the TUI model picker
18. 能力坑 · 失败模式:capability: I hope to enable support for glm, qwen, kimi and minimax in the eastopenrouter.
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: I hope to enable support for glm, qwen, kimi and minimax in the eastopenrouter.
- 对用户的影响:Developers may hit a documented source-backed failure mode: I hope to enable support for glm, qwen, kimi and minimax in the eastopenrouter.
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: I hope to enable support for glm, qwen, kimi and minimax in the eastopenrouter.. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_63a8cad40e7a346a6d7d99b6a8c6c551 | https://github.com/charmbracelet/crush/issues/3043 | I hope to enable support for glm, qwen, kimi and minimax in the eastopenrouter.
19. 能力坑 · 失败模式:capability: rate limited api requests (429) are not retried
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: rate limited api requests (429) are not retried
- 对用户的影响:Developers may hit a documented source-backed failure mode: rate limited api requests (429) are not retried
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: rate limited api requests (429) are not retried. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_issue | fmev_4fd1758958ecbb14a35cdcd3d5d1999a | https://github.com/charmbracelet/crush/issues/3024 | rate limited api requests (429) are not retried
20. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:987670088 | https://github.com/charmbracelet/crush | issue_or_pr_quality=unknown
21. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:987670088 | https://github.com/charmbracelet/crush | release_recency=unknown
22. 维护坑 · 失败模式:maintenance: nightly
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: nightly
- 对用户的影响:Upgrade or migration may change expected behavior: nightly
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: nightly. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_5728cb735d1e881463679d2371cb1b72 | https://github.com/charmbracelet/crush/releases/tag/nightly | nightly
23. 维护坑 · 失败模式:maintenance: v0.69.0
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.69.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.69.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.69.0. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_5566acb97cddbf499b1f66a5e1c3c551 | https://github.com/charmbracelet/crush/releases/tag/v0.69.0 | v0.69.0
24. 维护坑 · 失败模式:maintenance: v0.69.1
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.69.1
- 对用户的影响:Upgrade or migration may change expected behavior: v0.69.1
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.69.1. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_9d60f677f778da5c768a8a4010d2b98f | https://github.com/charmbracelet/crush/releases/tag/v0.69.1 | v0.69.1
25. 维护坑 · 失败模式:maintenance: v0.72.0
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.72.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.72.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.72.0. Context: Observed when using windows
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_aaf5977fa237d63e149c54782afa2165 | https://github.com/charmbracelet/crush/releases/tag/v0.72.0 | v0.72.0
26. 维护坑 · 失败模式:maintenance: v0.73.0
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.73.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.73.0
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.73.0. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_17c84212866ab12078588df528f11ade | https://github.com/charmbracelet/crush/releases/tag/v0.73.0 | v0.73.0
27. 维护坑 · 失败模式:maintenance: v0.74.1
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this maintenance risk before relying on the project: v0.74.1
- 对用户的影响:Upgrade or migration may change expected behavior: v0.74.1
- 建议检查:Before packaging this project, run the relevant install/config/quickstart check for: v0.74.1. Context: Source discussion did not expose a precise runtime context.
- 防护动作:State this as source-backed community evidence, not as Doramagic reproduction.
- 证据:failure_mode_cluster:github_release | fmev_b32360eb9d88abe0b1576258d57cfdbb | https://github.com/charmbracelet/crush/releases/tag/v0.74.1 | v0.74.1
来源:Doramagic 发现、验证与编译记录