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 运行)、LSPManagerSkills 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 引用、LSPManagerSkills 协调器,并提供 runCompletions 通道将每次顶级 turn 的终止信号桥接到全局事件流,确保多订阅者(尤其是 SSE 客户端)能在所有消息更新 flush 之后再收到完成事件。资料来源:internal/app/app.go:34-55
  • Backend 状态层:以 Workspace 列表承载每个项目空间,配置变更通过 pubsub.Event[proto.ConfigChanged] 通知所有订阅方刷新本地缓存。资料来源:internal/backend/config.go:23-29
  • Server 传输层:支持 Unix 域套接字(maxUnixSocketPathLen=104,跨 macOS/Linux 兼容)与 TCP,回退路径为 $XDG_RUNTIME_DIRos.TempDir(),便于本地 IDE 同机嵌入。资料来源:internal/server/server.go:17-35

核心执行流:Agent 调度的 "Accept / Run" 双阶段

社区中关于 Agent 工具偶发无返回 的问题,正是源于其 "接受即返回、运行在后台" 的双阶段调度模型:

  1. BeginAccepted(sessionID) 立刻返回一个 AcceptedRun 句柄并落库,使 Backend.SendMessage 能立即向前端响应 "已受理"。
  2. RunAccepted(ctx, accept, sessionID, prompt, attachments...) 在派发的 goroutine 中真正驱动 LLM 工具循环,调用 MarkRunCompletePublished(ctx) 标记权威终态以避免 runAgent 重复发出 fallback RunComplete
  3. 测试中常用 gatedCoordinatorRunAccepted 入口设置 gate,从而在 "已接受但未激活" 窗口内精确触发 Cancel,验证取消语义。资料来源:internal/backend/accepted_run_integration_test.go:18-37 与 internal/backend/agent_runcomplete_test.go:21-39

错误传播路径同样由该模式决定:若 RunAccepted 已发布 RunComplete,即便最终 AgentResult 返回 errorBackend 也不会再次广播同一条终结事件,避免客户端收到重复或互相覆盖的状态。资料来源:internal/backend/agent_runcomplete_test.go:21-39

配置、扩展与多客户端语义

Crush 的配置按以下优先级覆盖:项目级 .crush.jsoncrush.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

扩展面包括:

  • LSPlsp.<lang>.{command,args,env},在 Agent 决策回路中作为上下文源。资料来源:README.md
  • MCPstdio / 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-invocabledisable-model-invocation 控制是否进入命令面板与是否被模型自动触发。资料来源:README.md(社区曾反馈隐藏目录与深度嵌套会引入噪声技能,对应 Issue #2938Issue #2991

多客户端一致性由服务端 + Workspace 事件总线保证:每个 Workspace 拥有独立 Appevents 通道,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),它接收 SessionIDRunIDPrompt 等字段并交给 agent.Coordinator 处理。SendMessage 会先校验工作区与协调器状态,返回的错误包括 ErrWorkspaceNotFoundErrAgentNotInitializedagent.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 切片(TextContentReasoningContentToolCallToolResultFinishImageURLContentBinaryContent)一一映射到 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 显式覆盖了 ToolCallIDNameInputFinished)与 ToolResultToolCallIDNameContentDataMIMETypeMetadataIsError)两类,因此工具结果既可承载结构化文本也可承载二进制数据。资料来源: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: truedisable-model-invocation: true:前者让技能出现在命令面板(Ctrl+P)并以 user:skill-nameproject: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.SkillStateNamePathStateErr),常见状态有 StateNormalStateError(例如 frontmatter 解析失败),并以 SSE envelope 进行往返封装。资料来源:internal/server/events_test.go。

社区反馈表明扫描策略仍需完善:在配置路径下递归查找 SKILL.md 时,跳过隐藏目录(. 开头)与限制嵌套深度是常见诉求,分别参见 issue #2938issue #2991

MCP & LSP(外部协议集成)

MCP(Model Context Protocol) 通过 Backend.GetMCPResourcesReadMCPResourceGetMCPPrompt 暴露给上层。资源响应以 MCPResourceContentsURIMIMETypeTextBlob)形式返回;提示(prompt)则展开为字符串注入到对话上下文中。资料来源:internal/backend/config.go。

LSP(Language Server Protocol) 的事件总线定义在 internal/app/lsp_events.go 中。LSPEventType 仅有两类:LSPEventStateChangedLSPEventDiagnosticsChangedLSPClientInfo 记录每个 LSP 客户端的 NameStateErrorClientDiagnosticCountConnectedAt。后端用 pubsub.NewBrokerLSPEventcsync.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 在启动时按照以下顺序查找配置文件,项目级配置优先于用户级配置:

  1. .crush.json(项目根目录)
  2. crush.json(项目根目录)
  3. $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 Keyinternal/client/config.go
ImportCopilot从服务器导入 GitHub Copilot Tokeninternal/client/config.go
RefreshOAuthToken按作用域刷新提供方 OAuth Tokeninternal/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.Servicemessage.Servicehistory.Servicepermission.Servicefiletracker.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 暴露状态,它们通过 serviceEventsWGeventsCtx 绑定生命周期,会随 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 是最核心的操作:给定 SessionIDPrompt 时,Coordinator 启动一次运行并把消息分派出去 资料来源:internal/backend/agent_test.go:1-40。

为避免空请求浪费 token,SendMessagePrompt 为空时立即返回 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 之前的步骤失败(例如 readyWgUpdateModels 异常),后端仍会发布一个带 RunID 的终止性 RunComplete 事件,避免 crush runRunID 上无限阻塞 资料来源: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.CreateWorkspacePOST /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。handleGetConfighandleGetWorkspaces 则分别把配置和工作区列表以 JSON 形式回给客户端 资料来源:internal/server/proto.go:50-90。

事件流方面,Agent/Skills/Message 事件会被包装进 SSE 信封。messageToProto 把内部 message.Message 转换为 proto.Message,其中 ToolResult 会保留 ToolCallIDNameContentDataMIMETypeMetadata,让前端能在统一的"工具结果"通道中渲染 资料来源:internal/server/events_test.go:1-50。技能事件经过 wrapEvent 包装后,StateStateNormal/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 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 来源证据:Context limit not respected in requests

可能影响授权、密钥配置或安全边界。

high 来源证据:[HYPER] all inputs have 0% cache hit

可能影响授权、密钥配置或安全边界。

high 来源证据:feat: skip hidden directories during recursive skill scanning

可能影响授权、密钥配置或安全边界。

medium 失败模式:configuration: Context limit not respected in requests

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 发现、验证与编译记录