mcpField
G
graft

graft

github.com/trailhq开发10.9k201 次安装1 天前更新
代码仓库

关于 graft

graft 是面向编码 Agent 的命令行技能,通过带源码位置的图谱笔记和调用关系帮助理解代码库。它支持定位代码、查看文件 API,以及评估修改影响。

主要功能

  1. 01排序检索代码与概念
  2. 02穷举索引文本搜索
  3. 03快速查看文件 API 签名
  4. 04追踪调用与引用关系
  5. 05浏览代码库结构
  6. 06检查图谱是否过期

适用场景

  1. 01查找某项行为的实现位置
  2. 02列出某个符号的所有出现处
  3. 03修改函数前检查调用方
  4. 04熟悉陌生代码库

MCP 相关

连接 graft MCP 服务后,可通过它使用检索、搜索、文件 API、调用追踪、代码库映射和新鲜度检查工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trailhq/trail-code --skill graft

安装后在 Claude Code 中输入/graft确认已加载。

详细介绍

graft

graft/ 存放着本仓库的图谱:其中包含一些简短的 Markdown 节点,每个节点都用文字说明一个部分,并标出其涵盖的确切 file:line 范围;此外还有一张连接图,展示谁调用了什么。查询一个节点只需几百个 token;通过阅读源码来重建这些理解则要花费数千个 token,还会遗漏连接关系。

下面的每条命令都是 $0,无需 API 密钥,且会在一秒内返回结果。一共有六条。选择适合当前任务的命令,运行并根据结果采取行动;不要为了获得更多信息而串联调用工具。大多数任务只需调用一次。

工具

1 · graft ask "<question>" --source:定位并理解(默认选项)

对图谱进行排序检索,自动在文字节点和连接图之间路由,并返回排名靠前的结果及确切的 file:line。

  • --source 会在每个命中结果中内嵌代码,也就是每个定义不超过 8 行的关键代码,因此结果本身就是你需要的代码,无需再读取文件。仅当关键代码过短、无法采取行动时才添加 --full。
  • --in <path> 会先将检索范围缩小至某个子树,再进行排序;-n N 会限制结果数量(默认值为 8)。
  • 适用场景: 问题涉及概念或定位,例如:“身份验证如何运作”“在哪里处理速率限制”“是什么组装了请求处理管线”。
  • 通常一次 ask 就能解答问题。真正包含多个部分的问题,需要针对每个不同的子问题分别调用一次 ask,绝不要只是换一种说法重复询问同一个问题。命中结果很少或相关性较弱时,应改用其他工具(grep / skeleton / callers),不要再次提问。
2 · graft grep "<pattern>":全面查找

在每个已索引文件中进行正则表达式搜索(使用 --fixed 可按字面值搜索),命中结果会按所属符号分组,并按耦合程度排序;它还会报告无法读取的文件。

  • 适用场景: 需要查找所有匹配项,例如所有调用点、常量的所有用法或所有提供方。ask 只返回排序靠前的 N 个结果,会漏掉部分实例;grep 不会。一次 grep 可代替大量 ask。
  • 搜索较短的符号名称或字面值,不要使用猜测的完整签名:过于具体的正则表达式(func (s *Server) GenerateHandler)即使代码已被索引,也会返回空结果。如果 grep 没有命中,放宽搜索条件(去掉接收者和签名,只保留名称),然后重试 graft grep——不要改用原始 grep -rn,它速度较慢且不会排序。
  • -i 不区分大小写;--in <path> 将搜索范围限制在某个子树内。仅当文件确实未被 graft 索引(文档、配置文件、刚创建的文件)时,才使用原始 grep -rn。
3 · graft skeleton <file>:快速查看文件 API

仅显示单个文件的签名视图(每个函数 / 方法 / 类型及其范围),约需 200 个 token,成本约为读取文件的 1/10。

  • 适用场景: 编辑文件或接入该文件之前,需要了解“此文件包含什么 / 可以在这里调用什么”。一个 skeleton 就能完整回答某个文件的问题;不要对同一文件重复运行 skeleton,也不要对 map 已列出的每个文件都运行 skeleton。
4 · graft callers <symbol>:确切的连接关系

查询预先计算的调用 / 引用关系,而非进行文本搜索。符号可以是裸名称(Foo)、限定名称(Class.method)或包限定名称(pkg.Fn)。

  • 默认 --direction in:查询谁调用 / 引用了该符号;重命名、删除或更改其签名之前应先运行。
  • --direction out:查询该符号本身调用 / 依赖的内容(旧版 callees)。
  • --depth N:按传递关系向外遍历 N 跳,查看完整影响范围(旧版 impact);--depth 2 通常用于回答“修改它会造成什么影响”。
  • --depth all:查看完整的连通闭包——通过这些连接可到达的所有源文件。进行重构、重命名或任何涉及多个文件的更改之前,请使用此选项:它会显示单文件修改可能遗漏的同级文件和下游文件(平台变体、必须拆分出去的模块)。
5 · graft map:快速了解陌生代码库或区域

按令牌预算生成导览:目录集群、各目录的中心节点,以及全局热点,直接来自连线图。

  • 适用场景:刚接触一个代码库,或有人让你介绍“架构”时。单独使用 map 就够了:阅读它列出的中心节点卡片;不要接着用 skeleton,也不要逐个询问它列出的所有子系统。--max-dirs N 可扩大范围。
6 · 生命周期:graft build / graft check

以上每个工具在回答前都会刷新图谱本身,因此这些工具返回的内容始终反映当前代码状态——包括你刚刚做出但尚未提交的编辑。编辑后无需运行 build。

但有一点需要注意:如果你直接对 graft/ 下的 Markdown 执行 grep,这些卡片是图谱的投影,会在每轮结束时重建,而不是每次查询时重建,因此编辑后可能会滞后。以上工具不会滞后——优先使用它们;如果本轮编辑过某个文件,就应将该文件的卡片范围视为过时。

build 用于 LLM 层(--deep 会添加概念图;除非有人要求,否则跳过);check 会在 graft/ 过时的时候失败,适用于 CI。

场景:完成编码任务的最短路径

当你……使用调用次数
入门 / “解释一下这个代码库”graft map,然后阅读列出的中心节点卡片1
理解某个流程(“X 是如何工作的”)graft ask "<flow>" --source1
查找应该在哪处修改graft ask "where is <behavior>" --source1
编辑一个你已经知道名称的符号graft grep "<symbol>",然后在 file:line 处编辑(跳过 ask——你已经知道位置)1
重命名 / 删除 / 更改签名先运行 graft callers <sym> --depth 21
重构 / 多文件修改(编辑前)运行 graft callers <sym> --depth all——梳理每个关联文件,不要找到第一个就停1
“它依赖什么?”graft callers <sym> --direction out1
查找某个模式的所有匹配项graft grep "<literal>"1
“这个文件的 API 是什么?”graft skeleton <file>1
调试区域 X 中的故障graft ask "<symptom>" --source,然后对可疑对象运行 callers1–2
合并前评估差异的风险graft callers <changed sym> --depth 21 / 符号
在单体代码库的某个代码库中工作在 ask / grep / callers 中添加 --in <scope>/不适用

在多代码库工作区中,graft 会公平排序,避免最大的代码库压过其他代码库;每个匹配项都会带有一个 [scope/] 标签,用于标明其子项目。如果你已经知道正在处理哪个项目,可以使用 graft ask "<task>" --in <scope>/ 缩小范围。

尽量减少调用次数

  • 节点的 covers: 列表已经为每个符号提供了精确的 file:line,直接引用即可。这些范围由源代码生成,是权威信息;无需重新打开或重新执行 grep 来“二次确认”。
  • 如果任务已经指出要修改的文件或符号,直接着手处理:运行 graft grep "<symbol>" 获取精确的 file:line,然后编辑。只有还不知道代码在哪儿时,才使用 graft ask——对你已经能明确指出的目标来说,ask 的往返就是浪费。
  • 相信答案并采取行动。只有第一个工具确实未能满足需求时,才使用第二个工具:例如匹配结果不够理想、范围被截断,或需要穷尽搜索。
  • 如果 graft 指出的路径不在磁盘上,说明它的索引领先于当前检出内容(切换了分支,或移动操作尚未拉取)。不要读取缺失的文件——运行 graft grep 查找符号当前所在位置,或运行 graft build 刷新索引。

每轮报告 graft 节省的内容

每个检索工具都会在输出开头显示一行 [graft] tokens saved ≈ N: 这是该调用相较于完整读取其涵盖文件所节省的预估 token 数。 每当你在某一轮中使用了任何 graft 工具,请在回复末尾用一行汇总你所有 graft 调用的这些数字,例如: 🌱 graft saved ~12,400 tokens this turn (3 calls)。没有显示此行的调用(对于指针成本与源内容相当的小文件)不会节省 token,因此请跳过。此数字是每轮的统计值;状态栏显示的是整个会话的累计值。

绝不要将 graft 命令通过 head、tail 或 sed -n 进行管道处理。 每个工具都已设定输出上限,并会说明省略了哪些内容;截取输出会丢掉你需要的命中结果,也会悄悄丢掉状态栏累计值解析所需的节省信息行。

graft 不够用时

  • 内容被截断(“+N more lines”):在文件的确切范围处打开文件。
  • 节点缺少细节:提出更具体的问题;只有在此之后,才读取确切的 file:line 处的源内容,绝不要为了重建 graft 已提供的理解而读取整个文件。
  • 你也可以直接在 graft/ 中使用 grep / ls / cat(纯 Markdown;graft/INDEX.md 为节点索引),但上面的工具更快,而且在关键处覆盖更全面,因此请优先使用它们。

连接 graft MCP 服务后,这些工具也会开放使用: graft_find_code、graft_find_all、graft_file_api、graft_trace_calls(含 direction / depth)、graft_repo_map、graft_check_freshness。使用哪种方式均可;相关指导相同。

评论

支持 Markdown