Doramagic 项目包 · 项目说明书
crush 项目
让每个人都能享受优雅的智能体编程 💘
Crush Overview & System Architecture
Crush 是 Charm 团队推出的终端原生 AI 编程助手,定位为 "Your new coding bestie"。它将 LLM、工具调用、文件系统和 IDE 协议统一在同一进程内,既可作为交互式 TUI 客户端使用,也对外暴露可被 IDE 等宿主嵌入的服务端 API。
继续阅读本节完整说明和来源证据。
项目定位与核心能力
Crush 是 Charm 团队推出的终端原生 AI 编程助手,定位为 "Your new coding bestie"。它将 LLM、工具调用、文件系统和 IDE 协议统一在同一进程内,既可作为交互式 TUI 客户端使用,也对外暴露可被 IDE 等宿主嵌入的服务端 API。
主要能力概括如下:
- 多模型支持:兼容 OpenAI 与 Anthropic 协议,可通过 Catwalk 数据库动态拉取模型列表,并支持 OpenAI-Compat 与 Anthropic-Compat 自定义 Provider。资料来源:README.md
- 会话化与上下文保持:以 Session 为单位维护多轮对话,可在运行中切换模型而保留上下文。资料来源:internal/app/app.go:34-40
- LSP 增强:在 LLM 决策时引入语言服务器诊断信息,事件通过
LSPEvent与全局lspBroker广播。资料来源:internal/app/lsp_events.go:21-50 - 多协议扩展:内置
stdio/http/sse三种 MCP 传输,并支持 shell 风格变量展开($VAR、${VAR:-default}、$(...))。资料来源:README.md - 跨平台部署:覆盖 macOS、Linux、Windows(PowerShell/WSL)、Android、FreeBSD、OpenBSD 与 NetBSD;通过 Homebrew、NPM、Arch、nix、FreeBSD pkg、Winget、Scoop 等多渠道分发。资料来源:README.md
社区高频诉求(参见 Issue #457 关于 Claude Code Max 订阅认证、Issue #1734 关于 Build/Plan 模式、Issue #990 关于 Agent Client Protocol)多围绕认证方式、IDE 集成与多模态交互展开,反映出 Crush 在多 Provider 与多端集成上的演进方向。
系统架构总览
下图展示了 Crush 主要子系统之间的协作关系。CLI/TUI 入口首先构造 App,再由其持有 Coordinator(驱动 Agent 运行)、LSPManager、Skills Manager、各类 Service(Session、Message、History、Permission、FileTracker),并以 pubsub.Broker[tea.Msg] 串联事件流。Backend 作为状态层同时服务本地 TUI 与远程 HTTP/SSE 客户端。
flowchart TB
subgraph Client["客户端层"]
TUI["TUI (Bubble Tea)"]
CLI["crush run (headless)"]
IDE["IDE / ACP 客户端"]
end
subgraph Server["服务端 / 应用层"]
HTTP["HTTP + SSE Server"]
App["App 实例"]
Backend["Backend (Workspace 集合)"]
end
subgraph Core["核心子系统"]
Coord["agent.Coordinator"]
Skills["skills.Manager"]
LSP["LSPManager + lspBroker"]
Cfg["config.ConfigStore"]
DB[("DB (sessions/messages/history)")]
end
subgraph Ext["外部能力"]
LLM["LLM Provider (OpenAI/Anthropic/Catwalk)"]
MCP["MCP Servers (stdio/http/sse)"]
LSPSrv["LSP Servers (gopls, ts-ls...)"]
end
TUI --> App
CLI --> App
IDE --> HTTP
HTTP --> Backend
App --> Backend
App --> Coord
App --> Skills
App --> LSP
App --> Cfg
Backend --> DB
Coord --> LLM
Coord --> MCP
LSP --> LSPSrv
Skills -.读取 SKILL.md.-> Coord
Cfg -.监听 ConfigChanged.-> Backend各模块说明:
App聚合根:作为运行期容器,持有所有 Service 引用、LSPManager和Skills协调器,并提供runCompletions通道将每次顶级 turn 的终止信号桥接到全局事件流,确保多订阅者(尤其是 SSE 客户端)能在所有消息更新 flush 之后再收到完成事件。资料来源:internal/app/app.go:34-55Backend状态层:以 Workspace 列表承载每个项目空间,配置变更通过pubsub.Event[proto.ConfigChanged]通知所有订阅方刷新本地缓存。资料来源:internal/backend/config.go:23-29Server传输层:支持 Unix 域套接字(maxUnixSocketPathLen=104,跨 macOS/Linux 兼容)与 TCP,回退路径为$XDG_RUNTIME_DIR或os.TempDir(),便于本地 IDE 同机嵌入。资料来源:internal/server/server.go:17-35
核心执行流:Agent 调度的 "Accept / Run" 双阶段
社区中关于 Agent 工具偶发无返回 的问题,正是源于其 "接受即返回、运行在后台" 的双阶段调度模型:
BeginAccepted(sessionID)立刻返回一个AcceptedRun句柄并落库,使Backend.SendMessage能立即向前端响应 "已受理"。RunAccepted(ctx, accept, sessionID, prompt, attachments...)在派发的 goroutine 中真正驱动 LLM 工具循环,调用MarkRunCompletePublished(ctx)标记权威终态以避免runAgent重复发出 fallbackRunComplete。- 测试中常用
gatedCoordinator在RunAccepted入口设置 gate,从而在 "已接受但未激活" 窗口内精确触发Cancel,验证取消语义。资料来源:internal/backend/accepted_run_integration_test.go:18-37 与 internal/backend/agent_runcomplete_test.go:21-39
错误传播路径同样由该模式决定:若 RunAccepted 已发布 RunComplete,即便最终 AgentResult 返回 error,Backend 也不会再次广播同一条终结事件,避免客户端收到重复或互相覆盖的状态。资料来源:internal/backend/agent_runcomplete_test.go:21-39
配置、扩展与多客户端语义
Crush 的配置按以下优先级覆盖:项目级 .crush.json → crush.json → $HOME/.config/crush/crush.json。运行时状态(窗口、UI 等)写入 $HOME/.local/share/crush/crush.json,路径可通过 CRUSH_GLOBAL_CONFIG / CRUSH_GLOBAL_DATA 覆盖。Provider 元数据默认从 Catwalk 自动更新,可通过 options.disable_provider_auto_update 或环境变量 CRUSH_DISABLE_PROVIDER_AUTO_UPDATE 关闭,并支持 crush update-providers 手动更新(含本地 JSON 回退与重置为内嵌版本)。资料来源:README.md
扩展面包括:
- LSP:
lsp.<lang>.{command,args,env},在 Agent 决策回路中作为上下文源。资料来源:README.md - MCP:
stdio/http/sse三种 transport,配合 shell 风格变量展开支持文件型 Secret。资料来源:README.md - Skills:从全局
$CRUSH_SKILLS_DIR/~/.config/agents/skills等路径,或项目级.agents/skills/.crush/skills/.claude/skills/.cursor/skills递归发现SKILL.md;通过 YAML frontmatter 的user-invocable与disable-model-invocation控制是否进入命令面板与是否被模型自动触发。资料来源:README.md(社区曾反馈隐藏目录与深度嵌套会引入噪声技能,对应 Issue #2938 与 Issue #2991)
多客户端一致性由服务端 + Workspace 事件总线保证:每个 Workspace 拥有独立 App 与 events 通道,SSE 订阅者通过统一的 pubsub.Broker 接收消息更新,并由 runCompletions 桥接 Agent 终止信号,使远程 IDE 客户端与本地 TUI 在同一事件序列上保持一致。资料来源:internal/server/e2e_test.go:18-50 与 internal/app/app.go:34-55
See Also
- README.md — 安装、配置、Provider 列表
- internal/app/app.go — App 聚合根结构
- internal/backend/config.go — Backend 与 ConfigChanged 事件
- internal/server/server.go — HTTP/Unix Socket 传输层
- Issue #3118 — Agent 工具偶发无返回问题
- Issue #2938 / Issue #2991 — 技能目录扫描与
.crushignore行为
来源:https://github.com/charmbracelet/crush / 项目说明书
Agent Loop, Tools, Skills, MCP & LSP
本页面描述 Crush 中驱动每一次模型交互的核心子系统:负责调度代理循环的后端、协调工具与子代理的调用、加载用户/项目级 Skills,并经由 MCP 与 LSP 协议接入外部能力。该层独立于具体传输协议(HTTP / ACP),由 backend 包统一抽象。资料来源:[internal/backend/backend.go:1-12]()。
继续阅读本节完整说明和来源证据。
Agent Loop(代理循环)
后端入口是 Backend.SendMessage(workspaceID, proto.AgentMessage),它接收 SessionID、RunID、Prompt 等字段并交给 agent.Coordinator 处理。SendMessage 会先校验工作区与协调器状态,返回的错误包括 ErrWorkspaceNotFound、ErrAgentNotInitialized 与 agent.ErrEmptyPrompt。资料来源:internal/backend/agent_test.go:28-58。
协调器的 RunAccepted(ctx, accept *agent.AcceptedRun, sessionID, prompt string, attachments ...message.Attachment) 负责"已接受但尚未活跃"窗口的执行,并在结束时返回 *fantasy.AgentResult。为了支持 crush run 等无头调用在指定 RunID 上同步等待结果,即便在 RunAccepted 之前就发生错误(例如模型列表更新失败),后端也必须发布一次终结性的 RunComplete 事件,否则调用方会永久阻塞在 RunCompletions() 订阅上。资料来源:internal/backend/agent_runcomplete_test.go:36-67。accepted_run_integration_test.go 中的 gatedCoordinator 用闭锁(gate)将真实协调器包裹起来,从而在确定性时间窗口内对取消信号进行注入测试。资料来源:internal/backend/accepted_run_integration_test.go:23-43。
internal/server/events.go 中的辅助函数 isSessionBusy(ws, sessionID) 与 attachedClients(ws, sessionID) 分别用于查询某会话是否仍有进行中的代理运行,以及当前正在观察该会话的客户端数量(nil 工作区被视作 0/false 以便 REST handler 直接透传)。messageToProto 将内部 message 切片(TextContent、ReasoningContent、ToolCall、ToolResult、Finish、ImageURLContent、BinaryContent)一一映射到 proto 类型对外发送。资料来源:internal/server/events.go。
flowchart LR
A[外部 SendMessage] --> B{Backend 校验}
B -- 工作区或协调器错误 --> X[返回 Err*]
B -- 通过 --> C[agent.Coordinator<br/>BeginAccepted]
C --> D[AcceptedRun 句柄]
D --> E[RunAccepted<br/>执行 Agent]
E -- 成功 --> F[RunComplete RunID]
E -- 失败 --> F
X -. 必须兜底发布 .-> F
F --> G[SSE 订阅者<br/>收到终态]Tools(工具系统)
工具由模型在循环中调用,并通过 ToolCall / ToolResult 部件在事件流中往返。messageToProto 显式覆盖了 ToolCall(ID、Name、Input、Finished)与 ToolResult(ToolCallID、Name、Content、Data、MIMEType、Metadata、IsError)两类,因此工具结果既可承载结构化文本也可承载二进制数据。资料来源:internal/server/events.go。
社区中关于工具的若干高频问题体现了其当前局限:
agent子代理工具偶发返回空输出,会让父模型在不知情的情况下重复工作并消耗预算,参见 issue #3118。- 文件类工具在 v0.76.0 中仍未读取
.crushignore,参见 issue #3116。 - v0.74.1 修复了
bash工具在执行git rebase -i等交互式命令时挂起的问题。
Skills(技能系统)
技能以 SKILL.md 文件形式存在,可放在全局目录 ~/.config/crush/skills 或项目相对目录中。其 YAML frontmatter 支持 user-invocable: true 与 disable-model-invocation: true:前者让技能出现在命令面板(Ctrl+P)并以 user:skill-name 或 project:skill-name 命名;后者用于禁止模型自动触发但仍允许用户手动调用。资料来源:README.md。
后端在装配命令面板时调用 skills.Catalog(activeSkills, paths, "") 枚举条目,再由 commands.FromSkillCatalog(entries) 生成命令对象;测试用例验证了软链接目录能被正确解析到 filepath.Join(link, skills.SkillFileName),例如 user:linked-skill。资料来源:internal/commands/commands_test.go。技能状态变化通过 pubsub.Event[skills.Event] 广播,载荷为 []*skills.SkillState(Name、Path、State、Err),常见状态有 StateNormal 与 StateError(例如 frontmatter 解析失败),并以 SSE envelope 进行往返封装。资料来源:internal/server/events_test.go。
社区反馈表明扫描策略仍需完善:在配置路径下递归查找 SKILL.md 时,跳过隐藏目录(. 开头)与限制嵌套深度是常见诉求,分别参见 issue #2938 与 issue #2991。
MCP & LSP(外部协议集成)
MCP(Model Context Protocol) 通过 Backend.GetMCPResources、ReadMCPResource、GetMCPPrompt 暴露给上层。资源响应以 MCPResourceContents(URI、MIMEType、Text、Blob)形式返回;提示(prompt)则展开为字符串注入到对话上下文中。资料来源:internal/backend/config.go。
LSP(Language Server Protocol) 的事件总线定义在 internal/app/lsp_events.go 中。LSPEventType 仅有两类:LSPEventStateChanged 与 LSPEventDiagnosticsChanged;LSPClientInfo 记录每个 LSP 客户端的 Name、State、Error、Client、DiagnosticCount 与 ConnectedAt。后端用 pubsub.NewBrokerLSPEvent 与 csync.NewMapstring, LSPClientInfo 分别承载广播与最新状态,订阅者通过 SubscribeLSPEvents(ctx) 拿到通道。资料来源:internal/app/lsp_events.go:11-65。调用方在 Backend 层则会收到 ErrLSPClientNotFound 等显式错误,便于把"找不到的 LSP 客户端"与"代理未初始化"区分开。资料来源:internal/backend/backend.go:24-36。
参见
- 配置与自定义 Provider:README.md
- 后端传输抽象层:internal/backend/backend.go
- 运行生命周期集成测试:internal/backend/accepted_run_integration_test.go
- LSP 事件流:internal/app/lsp_events.go
来源:https://github.com/charmbracelet/crush / 项目说明书
Configuration, Providers & Authentication
本页介绍 Crush 的配置体系、模型提供方(Provider)接入方式以及认证流程。配置决定了 Crush 在启动时如何加载 LLM、工具、技能与服务器端行为,提供方定义了与上游模型 API 的兼容协议,认证则涵盖了 API Key、OAuth 刷新以及 Copilot 凭据导入等机制。
继续阅读本节完整说明和来源证据。
1. 配置文件与优先级
Crush 在启动时按照以下顺序查找配置文件,项目级配置优先于用户级配置:
.crush.json(项目根目录)crush.json(项目根目录)$HOME/.config/crush/crush.json(用户全局)
同时可以通过环境变量覆盖配置与数据目录的存放位置:
CRUSH_GLOBAL_CONFIG:覆盖用户配置文件路径CRUSH_GLOBAL_DATA:覆盖运行期状态数据目录(Unix 下默认为$HOME/.local/share/crush/crush.json,Windows 下为%LOCALAPPDATA%\crush\crush.json)
配置文件本体是一个 JSON 对象,例如:
{
"providers": { "...": "..." },
"options": { "...": "..." }
}
资料来源:README.md:35-90
2. 提供方(Provider)类型
Crush 支持多种协议兼容的提供方,自定义提供方既可走 OpenAI 协议,也可走 Anthropic 协议。README 中特别强调 OpenAI 类型存在两种语义:
openai:用于直接代理或路由到 OpenAI 自身openai-compat:用于接入兼容 OpenAI 接口的第三方服务(如 Deepseek)
下表列出了 README 与客户端代码中涉及的关键提供方接入点:
| 入口 | 用途 | 引用位置 |
|---|---|---|
SetProviderAPIKey | 在服务器端设置某个提供方的 API Key | internal/client/config.go |
ImportCopilot | 从服务器导入 GitHub Copilot Token | internal/client/config.go |
RefreshOAuthToken | 按作用域刷新提供方 OAuth Token | internal/client/config.go |
providers 字段 | 在 crush.json 中声明提供方列表 | README.md |
context_window 字段 | 控制模型上下文窗口(社区曾报告未被正确遵守) | internal/config/*.go(间接) |
一个典型的 OpenAI 兼容提供方配置示例如下:
{
"$schema": "https://charm.land/crush.json",
"providers": {
"deepseek": {
"type": "openai-compat",
"base_url": "https://api.deepseek.com/v1",
"api_key": "$DEEPSEEK_API_KEY",
"models": [
{ "id": "deepseek-chat", "name": "Deepseek V3" }
]
}
}
}
资料来源:README.md:120-180、internal/client/config.go:5-30
3. 认证与凭据管理
Crush 客户端通过 HTTP 调用服务器后端来管理凭据,关键入口位于 internal/client/config.go:
SetProviderAPIKey(ctx, id, key):以 POST/workspaces/{id}/config/set形式写入 API Key。ImportCopilot(ctx, id):调用/workspaces/{id}/config/import-copilot,从服务器拉取 Copilot OAuth Token。RefreshOAuthToken(ctx, id, scope, providerID):在 OAuth 过期时主动刷新,避免出现 v0.75.0 中曾修复的“多会话同时触发刷新对话框”问题。
服务器侧的对等实现在 internal/server/config.go 中以 handlePostWorkspaceConfigSet 等处理器暴露,并通过 backend.SetConfigField(id, scope, key, value) 写入配置存储。scope 决定了配置是项目级还是全局级,从而支持多工作区、多客户端共享同一份身份。
资料来源:internal/client/config.go:1-50、internal/server/config.go:1-30
4. 服务端后端与配置运行时
internal/backend/backend.go 定义了与协议无关(HTTP/ACP)的工作区、会话、Agent、权限与事件管理。配置存储以 *config.ConfigStore 形式注入 Backend:
New(ctx, cfg, shutdownFn):构造一个新的后端实例。GetWorkspace(id)与ListWorkspaces():根据 ID 或列表查询工作区。CreateWorkspace(...):基于解析后的路径创建工作区,路径索引pathIndex决定了同一目录的“first-wins”复用语义。
HTTP 层在 internal/server/proto.go 中通过 handleGetConfig 将后端 Config() 序列化为 JSON 暴露给客户端,配合 handlePostControl 处理 shutdown 等系统指令。
flowchart LR CLI[CLI / IDE 客户端] -->|HTTP| Server[internal/server] Server -->|SetConfigField| Backend[internal/backend] Backend --> ConfigStore[(config.ConfigStore)] Backend --> Workspace[Workspace + App] Workspace --> AgentCoordinator[Agent Coordinator] ConfigStore -.作用域.-> Project[项目级 .crush.json] ConfigStore -.作用域.-> Global[$HOME/.config/crush/crush.json]
资料来源:internal/backend/backend.go:1-90、internal/server/proto.go:1-40、internal/app/app.go:30-70
5. 常见失败模式与社区反馈
- 上下文窗口未生效(issue #824):在配置中显式设置
context_window后,模型请求仍可能超过上限并导致循环报错。需要在providers[*].models[*]上确认与 LLM 实际一致。 - Copilot 模型支持(issue #348):社区长期要求接入 GitHub Copilot 模型,目前可通过
ImportCopilot走 OAuth 流程引入凭据,但模型列表需手动声明。 - Claude Code Max 订阅认证(issue #457):期望以订阅凭据替代 API Key,仍是开放需求。
See Also
- Skills & LSPs(技能与语言服务器)
- Agent Runtime & Tool Execution
- HTTP Server & Multi-Client Sessions
来源:https://github.com/charmbracelet/crush / 项目说明书
TUI, Sessions, Workspace & Operations
Crush 是一套面向终端的 AI 编码助手,其核心交互入口是基于 Bubble Tea 的 TUI(Terminal User Interface)。TUI 依赖一组后台服务来呈现会话、调度 Agent 并管理多工作区。App 结构体集中保存这些服务的句柄,包括 session.Service、message.Service、history.Service、permiss...
继续阅读本节完整说明和来源证据。
1. 系统架构与 TUI 角色
Crush 是一套面向终端的 AI 编码助手,其核心交互入口是基于 Bubble Tea 的 TUI(Terminal User Interface)。TUI 依赖一组后台服务来呈现会话、调度 Agent 并管理多工作区。App 结构体集中保存这些服务的句柄,包括 session.Service、message.Service、history.Service、permission.Service、filetracker.Service 以及 agent.Coordinator 资料来源:internal/app/app.go:55-75。
App 还维护一个事件代理 events *pubsub.Broker[tea.Msg],负责把 Agent 通知、Run 完成信号、技能变更等消息统一以 tea.Msg 的形式投递到 TUI 的 Update 循环中 资料来源:internal/app/app.go:75-100。这种"把领域事件包装为 tea.Msg"的设计,是 Crush 将"运行时语义"与"UI 呈现"解耦的关键。
LSP 管理器(LSPManager)与技能管理器(Skills)同样会向 TUI 暴露状态,它们通过 serviceEventsWG 与 eventsCtx 绑定生命周期,会随 TUI 一同启动和退出 资料来源:internal/app/app.go:80-110。在测试场景中,App.ShutdownForTest 会逆序触发所有 cleanupFuncs,模拟生产环境的数据库释放、LSP 卸载和 MCP 关闭 资料来源:internal/app/testing.go:1-15。
2. Session 与 Agent 运行
每个 Session 是一条独立的对话线;Agent Run 则是一次完整的 LLM 回合。App.AgentCoordinator 是统一入口,Backend 通过它驱动 Session。SendMessage 是最核心的操作:给定 SessionID 与 Prompt 时,Coordinator 启动一次运行并把消息分派出去 资料来源:internal/backend/agent_test.go:1-40。
为避免空请求浪费 token,SendMessage 在 Prompt 为空时立即返回 agent.ErrEmptyPrompt,并阻止后续派发 资料来源:internal/backend/agent_test.go:30-45。当 Coordinator 未初始化时,SendMessage 返回 ErrAgentNotInitialized;这两条前置条件让上层 REST 接口 POST /v1/workspaces/{id}/agent 行为可预测 资料来源:internal/server/agent_cancel_test.go:15-45。
Session 是否"忙"(有 Agent 正在运行)由 isSessionBusy(ws, sessionID) 判定:它查询 ws.App.AgentCoordinator.IsSessionBusy,并对 nil 工作区宽容处理 资料来源:internal/server/events.go:50-70。同时,attachedClients 返回当前正在查看该 Session 的客户端数量,便于在多客户端并发时进行一致性管理 资料来源:internal/server/events.go:65-85。
每次 Agent 跑完后,框架要求产生权威的"运行完成"信号。TestRunAgent_PreRunErrorPublishesTerminalRunComplete 表明:即使 RunAccepted 之前的步骤失败(例如 readyWg 或 UpdateModels 异常),后端仍会发布一个带 RunID 的终止性 RunComplete 事件,避免 crush run 在 RunID 上无限阻塞 资料来源:internal/backend/agent_runcomplete_test.go:30-60。
3. Workspace 管理
Workspace 是 Crush 的一等概念,代表一个被打开的工程目录。Backend 通过 csync.Map 维护 workspaces 与一个 pathIndex,实现"同一解析路径重复创建时取先创建者"的 first-wins 语义 资料来源:internal/backend/backend.go:30-60。
工作区键的规范化由 resolveWorkspaceKey 完成:先 filepath.Abs、再尝试 filepath.EvalSymlinks;当路径不存在时优雅回退到已清理的绝对路径 资料来源:internal/backend/backend.go:120-145。这种设计让符号链接路径与真实路径在同一 Workspace 上不会产生重复条目。
每个 Workspace 维护自己的 clients map[string]*clientState 与一个可选的 shutdownFn。当最后一个客户端断开时框架会触发 releaseHold;若没有活跃 SSE 流,工作区将被关闭并最终触发整台 Server 的关停 资料来源:internal/backend/backend_test.go:40-75。releaseHold 本身是幂等的——重复调用不会重复触发关闭 资料来源:internal/backend/backend_test.go:60-95。
为防止客户端在创建 Workspace 后未及时接入,Backend 引入 DefaultCreateGrace(创建宽限期)。在宽限期内首个 SSE attach 会把创建保留(creation hold)转化为流保留(stream claim),避免被超时回收 资料来源:internal/backend/backend.go:25-55。SetCreateGrace 暴露给测试,用以快速构造短超时场景 资料来源:internal/backend/backend.go:55-70。
sequenceDiagram
participant TUI as TUI
participant C as HTTP Client
participant S as Server/Controller
participant B as Backend
participant A as App/Coordinator
participant Sess as Session
TUI->>C: POST /workspaces (path, clientID)
C->>S: HTTP request
S->>B: CreateWorkspace
B->>B: resolveWorkspaceKey + hold(clientID)
B-->>S: Workspace
S-->>C: 200 OK (proto.Workspace)
TUI->>C: POST /v1/workspaces/{id}/agent
C->>S: AgentMessage{SessionID, Prompt}
S->>B: SendMessage
B->>A: AgentCoordinator.Run
A->>Sess: execute turn
Sess-->>A: token / tool / message events
A-->>TUI: tea.Msg via events broker
A-->>B: terminal RunComplete(RunID)4. 客户端操作与事件流
客户端通过 internal/client 与服务交互。Client.CreateWorkspace 走 POST /workspaces 并把 ClientID 写入请求体;Client.GetWorkspace 访问 GET /workspaces/{id} 资料来源:internal/client/proto.go:1-50。两个方法都通过 HTTP 状态码做硬校验:非 200 立即返回错误,避免空 body 解析。
Server 端,HTTP 控制器把 REST/SSE 流量桥接到 Backend 的传输无关操作上。handlePostControl 解析 proto.ServerControl,遇到 shutdown 命令调用 c.backend.Shutdown() 触发优雅退出;其它命令返回 400 资料来源:internal/server/proto.go:30-65。handleGetConfig 与 handleGetWorkspaces 则分别把配置和工作区列表以 JSON 形式回给客户端 资料来源:internal/server/proto.go:50-90。
事件流方面,Agent/Skills/Message 事件会被包装进 SSE 信封。messageToProto 把内部 message.Message 转换为 proto.Message,其中 ToolResult 会保留 ToolCallID、Name、Content、Data、MIMEType 与 Metadata,让前端能在统一的"工具结果"通道中渲染 资料来源:internal/server/events_test.go:1-50。技能事件经过 wrapEvent 包装后,State(StateNormal/StateError)与 Err 字段都被序列化保留,便于 TUI 在技能配置错误时给出明确提示 资料来源:internal/server/events_test.go:40-80。
5. 常见故障模式
社区中已观察到几类与本主题强相关的问题:
- Agent 工具偶发无输出:当
agent子调用未返回任何 token 时,会浪费预算并迫使父 LLM 重新规划 资料来源:#3118、#3117]()。 .crushignore未生效:尽管 README 声明 Crush 默认遵守.gitignore,但部分工具路径未读取.crushignore资料来源:#3116。- Vim 模式:TUI 内建编辑器尚未支持 Vim 键位,社区持续请求 资料来源:#1199。
- 超长请求未受
context_window约束:偶发出现超出context_window的请求并进入失败循环 资料来源:#824。 - Headless 模式仅输出最后一条消息:
crush run目前会打印整个思考过程,社区建议提供--last-message之类的开关 资料来源:#2265。
See Also
- README.md
- internal/app/app.go
- internal/backend/backend.go
- internal/server/proto.go
- internal/client/proto.go
来源:https://github.com/charmbracelet/crush / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能影响授权、密钥配置或安全边界。
可能影响授权、密钥配置或安全边界。
可能影响授权、密钥配置或安全边界。
Developers may misconfigure credentials, environment, or host setup: Context limit not respected in requests
Pitfall Log / 踩坑日志
项目:charmbracelet/crush
摘要:发现 29 个潜在踩坑项,其中 3 个为 high/blocking;最高优先级:安全/权限坑 - 来源证据:Context limit not respected in requests。
1. 安全/权限坑 · 来源证据:Context limit not respected in requests
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Context limit not respected in requests
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/824 | 来源讨论提到 macos 相关条件,需在安装/试用前复核。
2. 安全/权限坑 · 来源证据:[HYPER] all inputs have 0% cache hit
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[HYPER] all inputs have 0% cache hit
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/3110 | 来源类型 github_issue 暴露的待验证使用条件。
3. 安全/权限坑 · 来源证据:feat: skip hidden directories during recursive skill scanning
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:feat: skip hidden directories during recursive skill scanning
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/2938 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
4. 配置坑 · 失败模式:configuration: Context limit not respected in requests
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: Context limit not respected in requests
- 对用户的影响:Developers may misconfigure credentials, environment, or host setup: Context limit not respected in requests
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/824 | Context limit not respected in requests
5. 配置坑 · 失败模式:configuration: Crush tools does not respect .crushignore.
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: Crush tools does not respect .crushignore.
- 对用户的影响:Developers may misconfigure credentials, environment, or host setup: Crush tools does not respect .crushignore.
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/3116 | Crush tools does not respect .crushignore.
6. 配置坑 · 失败模式:configuration: Vim Mode
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: Vim Mode
- 对用户的影响:Developers may misconfigure credentials, environment, or host setup: Vim Mode
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/1199 | Vim Mode
7. 配置坑 · 失败模式:configuration: feat: skip hidden directories during recursive skill scanning
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: feat: skip hidden directories during recursive skill scanning
- 对用户的影响:Developers may misconfigure credentials, environment, or host setup: feat: skip hidden directories during recursive skill scanning
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/2938 | feat: skip hidden directories during recursive skill scanning
8. 配置坑 · 失败模式: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
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/v0.70.0 | v0.70.0
9. 配置坑 · 失败模式: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
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/v0.71.0 | v0.71.0
10. 配置坑 · 失败模式: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
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/v0.74.0 | v0.74.0
11. 配置坑 · 失败模式:configuration: v0.75.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.75.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.75.0
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/v0.75.0 | v0.75.0
12. 配置坑 · 失败模式:configuration: v0.76.0
- 严重度:medium
- 证据强度:source_linked
- 发现:Developers should check this configuration risk before relying on the project: v0.76.0
- 对用户的影响:Upgrade or migration may change expected behavior: v0.76.0
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/v0.76.0 | v0.76.0
13. 配置坑 · 来源证据:Agent tool sometimes fails to return any output
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:Agent tool sometimes fails to return any output
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/3118 | 来源讨论提到 linux 相关条件,需在安装/试用前复核。
14. 配置坑 · 来源证据:Crush tools does not respect .crushignore.
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:Crush tools does not respect .crushignore.
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/3116 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
15. 配置坑 · 来源证据:Prevent Crush from finding skills deeply nested in skills directories
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:Prevent Crush from finding skills deeply nested in skills directories
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/2991 | 来源类型 github_issue 暴露的待验证使用条件。
16. 能力坑 · 能力判断依赖假设
- 严重度: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.
17. 运行坑 · 来源证据:Agent tool sometimes fails to return any output
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:Agent tool sometimes fails to return any output
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/charmbracelet/crush/issues/3117 | 来源类型 github_issue 暴露的待验证使用条件。
18. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | github_repo:987670088 | https://github.com/charmbracelet/crush | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | github_repo:987670088 | https://github.com/charmbracelet/crush | no_demo; severity=medium
20. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | github_repo:987670088 | https://github.com/charmbracelet/crush | no_demo; severity=medium
21. 能力坑 · 失败模式:capability: Agent tool sometimes fails to return any output
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: Agent tool sometimes fails to return any output
- 对用户的影响:Developers may hit a documented source-backed failure mode: Agent tool sometimes fails to return any output
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/3117 | Agent tool sometimes fails to return any output
22. 能力坑 · 失败模式:capability: Flag to output final message only (headless mode)
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: Flag to output final message only (headless mode)
- 对用户的影响:Developers may hit a documented source-backed failure mode: Flag to output final message only (headless mode)
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/2265 | Flag to output final message only (headless mode)
23. 能力坑 · 失败模式:capability: [HYPER] all inputs have 0% cache hit
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this capability risk before relying on the project: [HYPER] all inputs have 0% cache hit
- 对用户的影响:Developers may hit a documented source-backed failure mode: [HYPER] all inputs have 0% cache hit
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/3110 | [HYPER] all inputs have 0% cache hit
24. 能力坑 · 失败模式:conceptual: Agent tool sometimes fails to return any output
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this conceptual risk before relying on the project: Agent tool sometimes fails to return any output
- 对用户的影响:Developers may hit a documented source-backed failure mode: Agent tool sometimes fails to return any output
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/3118 | Agent tool sometimes fails to return any output
25. 运行坑 · 失败模式:performance: Prevent Crush from finding skills deeply nested in skills directories
- 严重度:low
- 证据强度:source_linked
- 发现:Developers should check this performance risk before relying on the project: Prevent Crush from finding skills deeply nested in skills directories
- 对用户的影响:Developers may hit a documented source-backed failure mode: Prevent Crush from finding skills deeply nested in skills directories
- 证据:failure_mode_cluster:github_issue | https://github.com/charmbracelet/crush/issues/2991 | Prevent Crush from finding skills deeply nested in skills directories
26. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | github_repo:987670088 | https://github.com/charmbracelet/crush | issue_or_pr_quality=unknown
27. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | github_repo:987670088 | https://github.com/charmbracelet/crush | release_recency=unknown
28. 维护坑 · 失败模式: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
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/nightly | nightly
29. 维护坑 · 失败模式: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
- 证据:failure_mode_cluster:github_release | https://github.com/charmbracelet/crush/releases/tag/v0.74.1 | v0.74.1
来源:Doramagic 发现、验证与编译记录