关于 coldstart
coldstart 将代码库导航与仓库内由 Agent 编写的笔记本结合,面向 AI 编码 Agent。静态索引依据代码证据定位文件和符号,笔记则关联代码,并在证据变化时标记过期。
主要功能
- 01路径、符号和代码关系的静态索引
- 02按任务搜索文件并导航符号
- 03仓库内的 Agent 编写笔记本
- 04代码锚点与基于哈希的新鲜度检查
- 05用于访问笔记本的命令行工具和 MCP 工具
适用场景
- 01编辑前定位相关文件
- 02跨会话回忆经过验证的代码库信息
- 03代码变更后检查并修正笔记
MCP 相关
可选的 MCP 模式提供搜索、查找、写入和维护笔记的工具。coldstart 也可为受支持的客户端配置 MCP 服务。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
8收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| query | string | 是 | 要查找对象的空格分隔标识符——传入任务中的所有重要 token,而不是单个关键词。camelCase/snake_case 均可。区分度越高的 token,排名越精准。 |
详细介绍
coldstart
为 AI 编码 Agent 提供可自我维护的代码库知识。
由 Agent 编写、始终锚定于代码的笔记,再加上快速、确定性的导航,让 Claude Code、Codex 和 Cursor 无需在每次会话中重新探索代码库。
两层,一个工具:
- 笔记本(
coldstart kb)——由 Agent 编写的持久笔记,记录_这个_代码库的实际运作方式:文件的用途、一个流程如何跨越多个文件、哪些不变量成立。笔记在完成实际任务后记录,在后续任务匹配时调取,并由索引确保其可靠——每条笔记都锚定于真实文件,证据已发生偏移的笔记会被标记,而不会被当作事实提供。 - 导航(
coldstart find/coldstart gs)——针对文件路径、符号名称、导出项以及导入/调用关系图构建的快速静态索引。它能在几毫秒内回答“哪些文件与这项任务相关?”,提供可核查的证据,而不是相似度分数。
无需嵌入向量,无需运行模型,也无需维护服务。Agent 已经擅长阅读和推理代码;它们浪费 token 的地方,是_寻找_正确的文件,以及_重新推导_上次会话已经弄清楚的内容。coldstart 负责这两部分,然后便不再干扰你。
安装
需要 Node.js 18+。
npm install -g @cstart/coldstart
cd your-project
coldstart init # coldstart.md + client wiring + notebook + background index warm-up
只需运行一次 coldstart init,即可完成所有设置——导航和笔记本。它会询问两项内容——体验模式(cli,推荐,或 mcp)和客户端——然后将面向 Agent 的指导写入客户端自己的规则文件(对于 Claude Code,作为导入的 coldstart.md;对于 Cursor 和 Codex,则直接内联,因为它们不会解析 @file 引用),配置客户端,并设置笔记本(骨架、git 配置,以及针对 Claude Code、Codex 和 Cursor 的捕获/回忆钩子)。传入 --experience / --client 可跳过提示。客户端不会自动检测;你始终需要自行选择。
- Claude Code → 写入
coldstart.md,并确保CLAUDE.md通过@coldstart.md导入它;同时在.claude/settings.json中注册 find/gs 搜索钩子(PostToolUse 提示 + PreToolUse find 去重保护)和笔记本回忆/捕获钩子(UserPromptSubmit + Stop/SubagentStop)——与现有设置合并,绝不覆盖。mcp体验模式还会写入.mcp.json。 - Codex → 将完整的 coldstart 指导内联到
AGENTS.md中一个带标记的代码块里(Codex 不支持@file引入,因此不会单独生成coldstart.md),重新运行时会原位刷新;并在.codex/hooks.json中注册 Codex 专用的导航和笔记本钩子。捕获钩子可解析 Codex rollout 和子 Agent 转录内容。mcp体验模式还会在.codex/config.toml中写入[mcp_servers.coldstart]。 - Cursor → 写入
.cursor/rules/coldstart.mdc——一条始终生效、内联完整 coldstart 指导的规则(Cursor 无法可靠地解析规则中的@file引用),每次初始化时都会重写;并在.cursor/hooks.json中注册 Cursor 专用的导航和笔记本钩子(preToolUsefind 去重保护、postToolUse提示、beforeSubmitPrompt回忆,以及stop/subagentStop捕获——与现有钩子合并)。捕获钩子会解析 Cursor 自己的对话转录内容。mcp体验模式还会写入.cursor/mcp.json。 - 其他 → 只写入
coldstart.md,并打印配置说明(以及mcp体验模式的 MCP 服务条目)。
对于所有客户端,PostToolUse 钩子还会主动发送 “共同编辑” 信号,无需等待询问。当 Agent 编辑过两个不同的文件后,它会列出 git 历史记录显示经常与这些文件一同变更的文件——相关的实现文件、另一种语言的测试,以及容易过时的文档。Agent 不会总是在编辑前运行 gs,因此只有主动查找时才会收到这个信号;现在它会在编辑时主动显示。此信号仅供参考:消息会明确说明,这种关联反映的是一种习惯,而非代码依赖,并要求 Agent 进行检查,而不是更改任何内容。每个任务中,每个文件最多只会列出一次;你发送新消息时,列表会重置。
随后,init 会在后台预热索引,让你首次查找时即可即时获得结果。重新运行 init 是安全的——它不会重复添加条目。
升级
npm install -g @cstart/coldstart@latest
coldstart init # re-run in each project to refresh coldstart.md
keeper 的锁文件中的版本标记会让旧的后台 keeper 在下次查找时关闭;新的 keeper 会由新二进制文件启动。无需手动重启。
说明
**从
coldstart-mcp迁移:**该软件包在 2.0.0 版本中从coldstart-mcp更名为@cstart/coldstart(CLI 现在是主要使用方式)。coldstart-mcp已弃用,但仍可安装;请使用npm uninstall -g coldstart-mcp && npm install -g @cstart/coldstart && coldstart init进行切换。coldstart-mcp二进制名称仍作为别名保留,因此现有 MCP 配置仍可正常使用。
移除 coldstart
init 会写入每个仓库的接线配置,而全局 npm uninstall 无法触及这些配置(npm 不会触发可靠的卸载钩子,也不会记录你对哪些仓库运行过 init)。因此,和 husky 一样,coldstart 提供了一个显式的反向操作:
coldstart unwire # strip coldstart's wiring from this repo (notebook kept)
coldstart unwire --purge # also delete .coldstart/notebook/ and its git plumbing
unwire 只会从 init 修改过的文件中移除 coldstart 拥有的标记——钩子条目、@coldstart.md 导入、AGENTS.md 区块、MCP 服务条目,以及 coldstart 完全拥有的文件(coldstart.md、.cursor/rules/coldstart.mdc)——绝不会移除共享文件中的自有内容。它会扫描全部四个客户端,具有幂等性(再次运行时会报告所有内容都已移除),并且默认保留笔记本,因为它是已提交的共享数据。先在每个项目中运行它,然后运行 npm uninstall -g @cstart/coldstart 移除该软件包。
知识库
由 Agent 在仓库内编写和读取的知识库,位于 .coldstart/notebook/:
coldstart kb search tile save lifecycle # plain task words, symbols, or file names
coldstart kb lookup src/models.py Tile # everything known at one exact address
coldstart kb write spec.json # the write gate (two-phase dedup)
coldstart kb commit # publish notes to git, nothing else rides along
coldstart kb view # open a single-file HTML browser of the notebook
coldstart kb repair # worklist of notes that are written but unfindable
coldstart kb repair-aliases # worklist of aliases that may no longer be true
coldstart kb status / lint / render / init / migrate
什么是笔记。 有三种形式:文件笔记(说明文件的用途——可以是单条摘要,也可以是枢纽文件中每个符号各自的说明)、流程笔记(跨文件的说明:有序步骤、不变量),以及经验教训(陷阱、规则、缺陷原因、设计理由或已确认不存在的情况)。每条笔记都带有锚点——其论述所依据的具体文件路径和符号。
笔记如何触达 Agent。 三种方式,无需养成新习惯:
find结果中的Summary:行——由先前的 Agent 验证过的文件概述,直接显示在文件的搜索结果中。[fresh]表示该文件与摘要验证时逐字节相同——Agent 无需重新阅读文件即可依赖该摘要。- 提示词发送时召回(可选钩子)——标题、别名或锚点与传入提示词匹配的笔记,会以精简的标题 + 概要 + 路径区块呈现,有严格的长度上限,并标明为参考数据。没有匹配项 → 不注入任何内容。
kb search/kb lookup——用于任务中途更换术语时搜索知识库的搜索引擎,以及用于编辑文件前精确定位的查询(path [symbol])。
为何值得信赖。 这部分是设计工作的重点:
- 新鲜度靠机制保障,而非寄希望于此。 写入时,每个锚点都会附带内容哈希;随着代码变化,索引会重新检查这些标记。偏离的笔记会显示
[evidence changed: <path>],并提示重新验证——过时知识会降级为明确标注的假设,而不是自信满满的谎言。 - 日志才是真相。 笔记存放在只追加的
.raw事件日志中(请提交该日志——合并时采用并集,因此并行分支中的笔记可以无冲突地协调)。Markdown 笔记是派生内容,会通过机械方式重新生成,并由 gitignore 忽略。 - 写入必须通过关卡。 新笔记的概念会先与现有笔记进行搜索比对——Agent 必须明确选择合并到匹配项(
--into <id>),或声明这是新概念(--new)。重复内容在写入时就会受到把关,而不是留待之后清理。 - 并发会话安全可靠。 多个 Agent 可以同时写入:每条笔记使用只追加日志;新笔记 ID 通过独占创建(同一时刻产生的重复项会成为两条可见笔记,绝不会被悄悄合并);共享文件笔记可无损合并;渲染采用原子操作(读取者永远不会看到只写了一半的笔记)。
- 可在会话中纠正。 如果 Agent 在证据仍处于上下文中时发现笔记有误,指导会要求它立即修正或撤回笔记——以后不会有比此刻更合适的 Agent。
设置: 知识库随 coldstart init 一同提供——无需单独操作。它会创建知识库骨架,为日志设置并集合并,并在 Claude Code、Codex 和 Cursor 中接入两个钩子——在会话结束时捕获,在提示词发送时召回。(如果只想为知识库(重新)接入钩子,coldstart kb init 仍可作为别名使用。)其他宿主也可以不使用钩子来操作知识库:通过完整的 kb CLI,或对无 Shell 客户端使用 kb_search / kb_lookup / kb_write / kb_status / kb_repair / kb_repair_aliases MCP 工具。
与语言无关。 知识库的新鲜度机制基于内容哈希,因此适用于任何代码库——包括导航索引无法解析的语言。对于索引可以解析的代码,笔记还会获得符号级新鲜度信息。
说明
知识库还很新。 目前已验证的情况:Agent 在真实会话中撰写的笔记,经对照代码检查后均准确无误;过时笔记的闭环流程已端到端打通(标记 → 重新阅读 → 修正);捕获、召回和并发写入在压力测试下均表现可靠。我们的预期——明确说来只是预期——是,这样的语料库会随着仓库的生命周期不断积累价值:同一个问题第二次出现时,答案只需一次
Read即可找到,无需重新推导。
导航:两种操作
| 回答的问题 | 替代的操作 | |
|---|---|---|
find <terms> | “哪些文件与此相关?”——根据文件覆盖的查询词数量为其排名(文件名、路径片段、导出符号,以及一次全仓库名称引用扫描)。 | 熟悉代码库时一连串的 grep/glob |
gs <file> | “这个文件是做什么的?”——顶层符号及其行范围、导入它的文件、调用各个符号的位置,以及名称相关的相邻项。 | 仅为了解文件结构和用法就通读整个文件 |
预期的工作流程:先用 find 查找某个概念 → 选出最合适的路径 → 用 gs 查看该文件的结构及其使用者 → 仅在需要了解方法体内的实现时使用 Read。find 的结果会附带笔记本摘要,因此通常查找步骤本身就能回答问题。
flowchart LR
A["coldstart find<br/>which files?"] --> B["coldstart gs<br/>what is it? who uses it?"] --> C["Read<br/>just the method body"]
class A,B cold
class C warm
classDef cold stroke:#16708f,stroke-width:2px
classDef warm stroke:#c26714,stroke-width:2px
find——查找与某个概念相关的文件
coldstart find auth session cookie
提示
传入任务中所有重要的标识符——符号、领域名词、你隐约记得的罕见词语——而不是只提炼出一个关键词。
find会根据每个文件覆盖的查询词数量为文件排名,并显示每个文件定义了哪些词、导入了哪些词,以及这些词聚集处的行预览。通常无需打开文件就足以找到答案。
在速度方面,find 可与原始 grep 一较高下:它的全仓库引用扫描使用 ripgrep——从 PATH 获取的版本、随附版本或编辑器自带版本(可通过 COLDSTART_RG 覆盖)——并在无法使用时回退到 git grep/grep;排名结果则来自预先构建的索引,而非实时扫描。
标志: --path GLOB(限定范围;可用逗号组合,! 表示排除) · --tests(包含测试文件) · --via(显示名称引用关系) · --json
gs——深入查看单个文件
coldstart gs src/auth/service.ts
一次调用即可返回文件的符号(含行范围)、其 1 跳范围内的内部导入项、导入该文件的位置,以及跨文件调用各个符号的位置。这能回答 “哪些地方使用了这个文件/哪些地方调用了这个符号”;它不是 grep。
标志: --symbol a,b(以内联方式提供指定的方法体) · --match TERM(将巨型文件筛选到某个区域;a|b = OR,/regex/ = 正则表达式) · --view symbols|imports|importers|callers · --json
graph——一次查看整个仓库
coldstart graph
面向人类,而非 Agent。它会写入一个自包含的 HTML 文件并将其打开:每个已索引文件都是球体上的一个点,按目录定位;点击某个点会打开一个展示其所有关联项的 2D 视图,并为每种关系标注名称(imports、calls save(), load()、edited together · 13 of 42 commits、same note · <title>)。点击某个邻近项可查看其关联项;再点击其中一项,视图便会沿关系滑动,因此你始终能看到两层关系,而不会形成不断扩大的毛线团。
无依赖项。 页面由 HTML、CSS 和一个内嵌了仓库数据的 canvas 脚本组成——无需服务端、无需构建,也不会有任何数据离开你的设备。可以通过邮件发送、放到 gist 中,或在飞机上打开。在 coldstart 自身代码库中试用。
标志: --out PATH(默认为 .coldstart/graph.html,已为你加入 gitignore) · --no-open · --json
在一次 Shell 调用中批量执行互不相关的查找
coldstart find auth; coldstart find 'session cookie'; coldstart gs src/auth/service.ts
两种调用方式,输出完全相同
coldstart 以单个二进制文件的形式提供两种入口:
- CLI(主要方式) —
coldstart find …/coldstart gs …/coldstart kb …。适用于任何支持 Shell 的 Agent(Claude Code、Cursor、终端使用)。这是最快的方式。 - MCP(适用于不支持 Shell 的客户端) —
find和gs工具,以及笔记本工具kb_search/kb_lookup/kb_write/kb_status/kb_repair/kb_repair_aliases,它们与 CLI 的输出逐字节一致。适用于没有 Shell 的客户端,例如 Claude Desktop。(kb commit仍仅限 CLI/人工使用——向 git 发布笔记绝不是 Agent 的操作。)
相同的引擎、相同的索引、相同的结果。选择你的 Agent 能使用的方式即可。
它与 Claude Code、Codex 和 Cursor 配合效果最佳:这三者都能通过 coldstart init 获得平台专属的 find/gs 钩子,以及笔记本召回/记录钩子。其他任何客户端都会获得 coldstart.md 和打印出的接入说明。
自备语义
coldstart 不使用嵌入向量,不生成摘要,也不在索引时计算语义层——这是刻意为之。语义层由 Agent 提供。 每个使用者本来就是前沿模型;在索引时预先计算含义只会重复这项工作,而且结果更差、也会过时。因此,索引只保留易于精确保留的信息——路径、符号、导出项、导入/调用图——并说明每个文件为何排名靠前。
笔记本将同一理念应用于记忆:coldstart 仍然不会自行计算含义。它存储、锚定并检查 Agent 编写内容的新鲜度——由掌握完整上下文的推理者在任务执行时,围绕实际重要的问题撰写。完整论述请见 PHILOSOPHY.md。
索引如何保持最新
coldstart 采用单个维护进程,读取端保持轻量的设计:
flowchart TD
K["keeper — coldstart --daemon<br/>watches repo, patches/rebuilds, saves cache<br/>serves nothing"] -->|debounced save| C[("on-disk cache")]
C --> F["coldstart find<br/>reads cache, prints"]
C --> G["coldstart gs<br/>reads cache, prints"]
C --> M["MCP server<br/>reads cache, stdio"]
class K cold
classDef cold stroke:#16708f,stroke-width:2px
- 每个代码仓库仅运行一个 维护进程,负责监视文件系统并保持磁盘缓存为最新状态。它不处理查询。
- CLI 读取端(
find/gs)和 MCP 服务是读取缓存的无状态读取端。代码仓库的第一个读取端会按需启动维护进程,因此未提交的编辑也能立即反映。 - 读取端从不构建索引。 缓存未命中时,它们会等待维护进程完成构建(进度输出到 stderr),而不是悄悄在查询过程中启动一次耗时数分钟的构建——更不会让三个进程同时启动。
- 没有 HTTP、没有端口、没有桥接层。维护进程将日志写入
~/.coldstart/daemon/<root>.log,并在删除其锁文件后退出。
缓存没有 TTL。 索引不会因为过旧而被丢弃——而是始终保持_正确_:
- 维护进程运行期间: 编辑操作会先经过防抖(400 ms),然后增量修补(每个文件约 2–5 ms,最多处理 30 个文件或仓库的 20%,取较大者),超出范围则触发后台完整重建(切换完成前仍使用最后一个有效索引)。编辑稳定后约 5 秒,缓存会以原子代次的方式重新保存——读取端永远不会加载到新旧数据混合的半成品。
- 维护进程启动时: 它会执行核对——将每个已索引文件的 stat 信息与存储的指纹进行对比(即使有 1.6 万个文件也只需约 150 ms),并将 git diff 与已索引的 HEAD 进行比较——然后精确修补监视期间发生的变更。过去,切换分支会迫使一个包含 1.6 万个文件的代码仓库花费 96 秒重建;现在,修补约需 3 秒。
- 作为后备保障: 每次修补都会根据索引不变量进行 lint 检查(违反不变量会触发自动重建,并记录在
status显示的修复日志中);每次保存后还会轮换执行指纹审计,以捕获监视器漏掉的事件。
维护进程还会为笔记本的锚点新鲜度生成时间戳(通过派生式单飞机制生成一个小型 sidecar)——笔记本不会加载代码索引来处理查询。
生命周期命令
coldstart status # keepers on this machine: alive? fresh? last patch/rebuild/save? repairs?
coldstart restart # kill the current repo's keeper (respawns on next lookup)
coldstart restart --root DIR # kill a specific repo's keeper from anywhere
coldstart restart --all # kill every keeper
coldstart index # build + save the cache once, up front (single-writer prep)
只要觉得有什么过时了,restart 就是正确选择——新的 keeper 会在启动时进行协调,因此它恢复后是_正确_的,而不只是能运行。status 会回答“我的索引是最新的吗?为什么?”:运行状态、缓存时长、keeper 最近一次协调/修补/重建/保存的时间戳,以及修复日志的末尾——不会探测网络。
支持的语言
导航索引:TypeScript、JavaScript、JSX/TSX、Vue、Svelte、Astro、AngularJS 1.x、Java、Kotlin、Ruby(支持 Rails:has_many/belongs_to 关联、routes.rb 资源、控制器↔视图关系)、Python(Django 约定关系)、Go、Rust、C#、PHP(Laravel 约定关系)、C++、Groovy(包括 Gradle DSL)、GraphQL、YAML、TOML、XML 和 .env 文件。
**不编入索引:**Swift、Dart——没有扩展名映射;这些文件不会被遍历或解析。
笔记本不受此限制——其新鲜度时间戳基于内容哈希,因此 Swift 仓库的笔记和 TypeScript 仓库的笔记一样可信(只是缺少符号级的新鲜度详情)。
何时_不_该使用它
- 查找文件内容中的字面字符串/短语/正则表达式 → Grep。
- 阅读实现 → 先用
gs了解结构,再用 Read。 find显示 “没有索引文件包含 […] 中的任何内容” → 仓库中不存在这些标识符。不要搜索拼写变体。
开发
npm install
npm run build
npm test
# run a query from your build:
node dist/index.js find auth --root .
# run the MCP server in a single process (no background keeper) for debugging:
node dist/index.js --root . --no-daemon
有关 coldstart 为何不自行计算语义,请参阅 PHILOSOPHY.md;有关索引流水线、进程模型和笔记本内部机制,请参阅 ARCHITECTURE.md;有关恢复流程,请参阅 TROUBLESHOOTING.md。
局限性
- 它是一个路由层加上由 Agent 编写的笔记本——不做语义分析,也不生成代码摘要。这是有意为之:使用它的 Agent 才是语义层(参阅 PHILOSOPHY.md)。
gs的调用者查询只跨一跳,且限定于文件范围。成员表达式调用(this.method()、api.method())不会解析跨文件关系;具名函数/常量调用则会解析。若要继续追踪更多跳,请对调用者所在文件调用gs。- 动态/计算导入(
import(variable))和运行时 DSL 引用(多态关联、由 gem/反射支持的模型)仍无法解析。 - 索引会跳过隐藏目录和超过 1 MB 的文件。
- keeper 按仓库和机器分别运行——不会在项目或主机之间共享。笔记本_可以_随项目迁移:其
.raw日志会提交,并在分支和机器之间进行联合合并。 - 笔记本的质量取决于编写笔记的 Agent 实际阅读了什么——笔记所述内容准确无误,但笔记不代表完整性证明。
测量结果
使用 CLI,在两个代码仓库中分别运行多次。每个问题分为两组提问,唯一的区别是是否安装了 coldstart:基线组使用纯 Claude Code 和自带的搜索工具。两组均使用 Sonnet 5,每个问题对应一个全新会话。
| 代码仓库 | 语言 | Token 数相较基线 | 召回率 | 问题数 |
|---|---|---|---|---|
| Arches | Python / Django | −64% | +2 个百分点 | 27 |
| JMRI | Java | −31% | 持平 | 25 |
问题来自已关闭的问题报告。这些报告在任何人知道故障位置之前就已编写,因此描述的是症状,而不是点名某个文件。正确答案是修复该问题的提交中涉及的源文件集合,因此,真实答案来自 git 历史,而非任何人的判断。
这两个数字不会取平均值。每轮的成本因语言而异,而节省来自减少轮数,因此,Agent 能在两三轮内解决的问题,几乎没有多少成本可节省。我们舍弃了此前针对 Kafka、Django 和 Mastodon 的基准测试:模型已经读过这三个项目,这污染了两组结果。完整方法(包括舍弃了什么以及原因)见 coldstartmcp.dev/benchmark。测试框架本身是一个独立项目 coldbench,适用于任何有 git 历史的代码仓库,包括私有仓库。两组问题均已公开,并附有标准答案文件列表以及每个问题对应的问题编号,见 coldbench/examples。
文章
深入探讨这款工具背后问题的文章——Agent 会话的实际成本,以及当测量结果与计划不符时,设计发生了什么变化。
- Agent 会话中的 Token 都花在哪里了 — 会话成本大致等于轮数 × 常驻上下文,输出所占成本可以忽略。介绍如何拆解自己的对话记录,而不是轻信他人公布的数据。
- 索引无法两次回答同一个问题 — 代码图能降低每次跳转的成本,却不会减少跳转次数;按入度排序会让叶子文件在结构上无法获得排名。
- Agent 不会调用的工具 — 有工具可用、有文档、还有明确指令,仍不足以让人采用。文中也包括我们自己的 Agent 绕过我们自己的命令的情况。
- 从四个工具到两个 — 删除了哪些工具,哪些能力确实随之消失,以及之后为何仍保持精简的工具界面。
- 代码笔记应由读过代码的人来写 — 笔记本为何在会话中记录内容,而不是事后总结对话记录。
许可证
MIT — 参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。