graft

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

graft

graft

graft/
holds a graph of this repo: small markdown nodes that each explain one part in prose and name the exact
file:line
spans they cover, plus a wiring graph of who-calls-what. Querying a node costs a few hundred tokens; rebuilding that understanding by reading source costs thousands, and misses the edges.
Every command below is
$0
, needs no API key, and returns in under a second. There are six of them. Pick the one that fits the task, run it, act on the answer; don't chain tools hoping for more. Most tasks need one call.
graft/
保存着此仓库的一张图:它由小型 Markdown 节点组成,每个节点用文字说明一个部分,并标明其涵盖的确切
file:line
区间;此外还有一张“谁调用谁”的连接图。查询一个节点只需几百个 token;而通过阅读源代码重新建立这种理解需要数千个 token,并且会遗漏调用关系。
以下每条命令的费用都是
$0
,无需 API key,并且不到一秒即可返回。一共有六条命令。选择适合任务的一条,运行它并根据答案采取行动;不要串联多个工具碰运气。大多数任务只需调用一次。

The tools

工具

1 ·
graft ask "<question>" --source
: locate + understand (the default)

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

Ranked retrieval over the graph, routed automatically between prose nodes and the wiring graph, returning the top hits with exact
file:line
.
  • --source
    inlines the code at each hit, the ≤8-line crux of each definition, so the result IS the code you need, no follow-up file read. Add
    --full
    only when the crux is too small to act on.
  • --in <path>
    narrows to a subtree before ranking;
    -n N
    caps results (default 8).
  • Use it when the question is conceptual or locational: "how does auth work", "where is rate-limiting handled", "what assembles the request pipeline".
  • One ask usually answers. A genuinely multi-part question needs one ask per distinct sub-aspect, never the same question reworded. Few or weak hits mean switch tool (grep / skeleton / callers), don't re-ask.
在图上执行排序检索,自动在说明节点和连接图之间进行路由,返回带有确切
file:line
的最佳匹配项。
  • --source
    会在每个命中处内联代码,展示每个定义不超过 8 行的 核心代码,因此结果本身就是执行所需的代码,无需再读取文件。只有当核心代码过少、无法据此行动时,才添加
    --full
    。
  • --in <path>
    会在排序前将范围限定到某个子树;
    -n N
    用于限制结果数量(默认 8)。
  • **适用场景:**概念理解或位置查找,例如“身份验证如何工作”“速率限制在哪里处理”“是什么组装了请求流水线”。
  • 一次 ask 通常就能给出答案。真正包含多个独立方面的问题,应当针对每个独立方面分别调用一次 ask,绝不能只是换个说法重复同一个问题。命中数量少或相关性弱时,应换用其他工具(grep / skeleton / callers),不要重复 ask。

2 ·
graft grep "<pattern>"
: exhaustive find

2 ·
graft grep "<pattern>"
:穷尽式查找

Regex (or
--fixed
for a literal) over every indexed file, hits grouped by enclosing symbol and ranked by coupling; it also reports files it couldn't read.
  • Use it when you need every occurrence: all call sites, all uses of a constant, all providers.
    ask
    is ranked top-N and will miss instances; grep won't. One grep replaces a spray of asks.
  • Search a short symbol name or literal, not a full guessed signature: an over-specific regex (
    func (s *Server) GenerateHandler
    ) returns nothing even when the code is indexed. If a grep misses, loosen it (drop the receiver and signature, keep the bare name) and retry
    graft grep
    — do NOT switch to raw
    grep -rn
    , which is slower and unranked.
  • -i
    case-insensitive;
    --in <path>
    scopes to a subtree. Raw
    grep -rn
    is only for files graft genuinely doesn't index (docs, configs, brand-new files).
对每个已索引文件执行正则搜索(或使用
--fixed
进行字面量搜索),命中项会按其所属的外围符号分组,并按耦合度排序;还会报告无法读取的文件。
  • **适用场景:**需要查找每一次出现的位置,例如所有调用点、常量的所有用法、所有 provider。
    ask
    返回的是排序后的前 N 项,必然会遗漏部分实例,而 grep 不会。一次 grep 可以取代连续发起大量 ask。
  • 搜索时应使用简短符号名或字面量,不要使用完整且凭猜测拼出的签名:过于具体的正则表达式(例如
    func (s *Server) GenerateHandler
    )即使代码已被索引,也可能没有结果。如果 grep 未命中,应放宽条件(去掉 receiver 和签名,只保留基本名称)后重试
    graft grep
    ——不要改用原始
    grep -rn
    ,后者速度更慢,而且没有排序结果。
  • -i
    表示不区分大小写;
    --in <path>
    可将范围限定到某个子树。只有在处理 graft 确实未索引的文件(文档、配置文件、新创建的文件)时,才使用原始
    grep -rn
    。

3 ·
graft skeleton <file>
: a file's API at a glance

3 ·
graft skeleton <file>
:快速查看文件 API

Signatures-only view of one file (every function / method / type with its span) in ~200 tokens, ~10x cheaper than reading the file.
  • Use it when you need "what's in this file / what can I call here" before editing or wiring into it. One skeleton is the whole answer for a file; don't re-skeleton the same file, and don't skeleton every file
    map
    already named.
仅显示签名的视图,列出每个函数/方法/类型及其区间,约需 200 token,成本约为读取整个文件的十分之一。
  • **适用场景:**编辑某个文件或将代码接入该文件之前,需要了解“这个文件里有什么/这里可以调用什么”。一次 skeleton 就能回答整个文件的问题;不要对同一文件重复执行 skeleton,也不要对
    map
    已列出的每个文件都执行 skeleton。

4 ·
graft callers <symbol>
: the exact edges

4 ·
graft callers <symbol>
:精确的依赖边

Precomputed call/reference edges, not a text search. Symbol can be bare (
Foo
), qualified (
Class.method
), or package-qualified (
pkg.Fn
).
  • default
    --direction in
    : who calls/references this; run before you rename, delete, or change its signature.
  • --direction out
    : what this symbol itself calls/depends on (the old
    callees
    ).
  • --depth N
    : walk transitively N hops for the full blast radius (the old
    impact
    );
    --depth 2
    is the usual "what breaks if I touch this".
  • --depth all
    : the entire connected closure — every source reachable through the edges. Reach for this before a refactor, rename, or any multi-file change: it surfaces the sibling and downstream files (platform variants, a module you must split out) that a single-file edit would miss.
使用预先计算的调用/引用边,而不是文本搜索。符号可以是基本名称(
Foo
)、限定名称(
Class.method
)或包限定名称(
pkg.Fn
)。
  • 默认的
    --direction in
    用于查找谁调用或引用了该符号;重命名、删除或更改其签名前,应先执行此操作。
  • --direction out
    用于查看该符号自身调用或依赖的内容(即旧版的
    callees
    )。
  • --depth N
    会以传递方式遍历 N 跳,展示完整的影响范围(即旧版的
    impact
    );
    --depth 2
    通常用于回答“如果修改这里,会破坏什么”。
  • --depth all
    会展示整个连通闭包——所有可通过这些边到达的源文件。进行重构、重命名或任何多文件更改之前,应使用此选项,以发现单文件编辑可能遗漏的同级文件和下游文件(平台变体、需要拆分出来的模块等)。

5 ·
graft map
: orientation for an unfamiliar repo or area

5 ·
graft map
:快速了解陌生仓库或区域

A token-budgeted tour: directory clusters, per-directory hubs, and global hotspots, straight from the wiring graph.
  • Use it when you land in a repo cold or are asked for "the architecture".
    map
    alone is the answer: read the hub cards it names; do NOT then skeleton or ask your way through every subsystem it lists.
    --max-dirs N
    widens it.
按 token 预算生成导览,直接从连接图中展示目录集群、各目录的枢纽以及全局热点。
  • **适用场景:**刚进入一个仓库,或被要求介绍“系统架构”时。
    map
    本身就是答案:阅读它指出的枢纽卡片;不要随后再通过 skeleton 或 ask 逐一了解它列出的每个子系统。
    --max-dirs N
    可扩大导览范围。

6 · Lifecycle:
graft build
/
graft check

6 · 生命周期:
graft build
/
graft check

Every tool above refreshes the graph itself before answering, so what those tools return always describes the code as it is right now — including edits you just made and have not committed. You do not need to run
build
after editing.
One caveat, if you
grep
the markdown under
graft/
directly: those cards are a projection, rebuilt at the end of the turn rather than on each query, so after an edit they can lag. The tools above never do — prefer them, and treat a card's spans as stale if you have edited that file this turn.
build
is for the LLM layer (
--deep
adds a concept map; skip unless asked);
check
fails when
graft/
is stale, for CI.
上述每个工具都会在回答前自行刷新图,因此其返回结果始终描述当前代码状态,包括刚刚编辑但尚未提交的修改。编辑后不需要运行
build
。
需要注意一个例外:如果直接 grep
graft/
下的 Markdown,这些卡片只是代码库状态的投影,会在每轮结束时重建,而不是在每次查询时重建,因此编辑后可能滞后。上述工具不会出现这种情况——应优先使用这些工具;如果本轮编辑过某个文件,应将相关卡片中的区间视为过期信息。
build
用于 LLM 层(
--deep
会额外生成概念图;除非明确要求,否则应跳过);
check
会在
graft/
过期时失败,可用于 CI。

Scenarios: the shortest path through a coding task

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

When you're…Reach forCalls
Onboarding / "explain this codebase"
graft map
, then read the named hub cards
1
Understanding a flow ("how does X work")
graft ask "<flow>" --source
1
Finding where a change belongs
graft ask "where is <behavior>" --source
1
Editing a symbol you can already name
graft grep "<symbol>"
, edit at the
file:line
(skip
ask
— you know where it is)
1
Renaming / deleting / changing a signature
graft callers <sym> --depth 2
first
1
Refactor / multi-file change (before editing)
graft callers <sym> --depth all
— map every connected file, don't stop at the first
1
"What does this depend on?"
graft callers <sym> --direction out
1
Finding every occurrence of a pattern
graft grep "<literal>"
1
"What's the API of this file?"
graft skeleton <file>
1
Debugging a failure in area X
graft ask "<symptom>" --source
, then
callers
on the suspect
1–2
Judging a diff's risk before merge
graft callers <changed sym> --depth 2
1 / symbol
Working inside one repo of a monorepoadd
--in <scope>/
to ask / grep / callers
n/a
In a multi-repo workspace, graft ranks fairly so the biggest repo can't drown the rest, and every hit carries a
[scope/]
label naming its sub-project; when you already know where you're working, narrow with
graft ask "<task>" --in <scope>/
.
当你正在……使用调用次数
熟悉项目/“解释这个代码库”
graft map
,然后阅读其指出的枢纽卡片
1
理解某个流程(“X 如何工作”)
graft ask "<flow>" --source
1
查找某项更改应放在哪里
graft ask "where is <behavior>" --source
1
编辑一个已经知道名称的符号
graft grep "<symbol>"
,然后在
file:line
处编辑(跳过 ask——你已经知道代码在哪里)
1
重命名/删除/更改签名先执行
graft callers <sym> --depth 2
1
重构/多文件更改(编辑前)
graft callers <sym> --depth all
——映射所有相连文件,不要停在第一个
1
“它依赖什么?”
graft callers <sym> --direction out
1
查找某个模式的所有出现位置
graft grep "<literal>"
1
“这个文件的 API 是什么?”
graft skeleton <file>
1
排查区域 X 中的故障
graft ask "<symptom>" --source
,然后对可疑符号执行
callers
1–2
合并前判断 diff 的风险
graft callers <changed sym> --depth 2
每个符号 1 次
在 monorepo 中的单个仓库内工作为 ask / grep / callers 添加
--in <scope>/
不适用
在多仓库工作区中,graft 的排序较为公平,因此最大的仓库不会淹没其他仓库;每个命中项都带有用于标识子项目的
[scope/]
标签。当你已经知道要在哪里工作时,可以使用
graft ask "<task>" --in <scope>/
缩小范围。

Spend the fewest calls

尽量减少调用次数

  • A node's
    covers:
    list already gives exact
    file:line
    for every symbol, so cite straight from it. The spans are generated from source and authoritative; don't re-open or re-grep files to "double-check".
  • When the task already names the file or symbol to change, go straight there:
    graft grep "<symbol>"
    for the exact
    file:line
    , then edit. Reserve
    graft ask
    for when you don't yet know where the code lives — an
    ask
    round-trip is wasted on a target you can already name.
  • Trust the answer and act. Reach for a second tool only when the first genuinely fell short: weak hits, a truncated span, or a need to be exhaustive.
  • If graft names a path that isn't on disk, its index is ahead of your checkout (a branch switch or unpulled move). Don't read the missing file —
    graft grep
    the symbol to find where it lives now, or run
    graft build
    to refresh.
  • 节点的
    covers:
    列表已经给出了每个符号的确切
    file:line
    ,因此可直接据此引用。区间由源代码生成,具有权威性;不要为了“再次确认”而重新打开文件或重新 grep。
  • 当任务已经指出要修改的文件或符号时,直接定位过去:使用
    graft grep "<symbol>"
    找到确切的
    file:line
    ,然后编辑。只有在尚不知道代码位于何处时才使用
    graft ask
    ——对于已经明确的目标,ask 往返查询是浪费。
  • 相信答案并据此行动。只有当第一次调用确实无法满足需求时,才使用第二种工具:命中相关性弱、区间被截断,或需要穷尽结果。
  • 如果 graft 给出的路径不在磁盘上,说明它的索引比当前 checkout 更新(例如切换了分支或移动尚未拉取)。不要读取这个不存在的文件——使用
    graft grep
    查找符号当前所在的位置,或运行
    graft build
    刷新索引。

Report what graft saved, every turn

每一轮都报告 graft 节省了多少

Each retrieval tool opens its output with a
[graft] tokens saved ≈ N
line: the estimated tokens that call saved versus reading the files it covers whole. Whenever you used any graft tool in a turn, close your reply with a one-line tally summing those numbers across every graft call you made, e.g.
🌱 graft saved ~12,400 tokens this turn (3 calls)
. A call with no such line (tiny files, where the pointers cost as much as the source) saved nothing, so skip it. This is the per-turn figure; the statusline carries the running session total.
Never pipe a graft command through
head
,
tail
, or
sed -n
.
Every tool is already capped and states what it dropped; clipping it costs you hits you asked for, and it silently drops the savings line the statusline's running total is parsed from.
每个检索工具都会在输出开头显示一行
[graft] tokens saved ≈ N
: 该数值估算的是此次调用与完整读取其覆盖文件相比所节省的 token。
只要本轮使用过任何 graft 工具,就应在回复结尾添加一行统计,汇总本轮所有 graft 调用所节省的数值,例如:
🌱 graft saved ~12,400 tokens this turn (3 calls)
如果某次调用没有显示这一行(通常是因为文件太小,位置指针与源代码本身的成本相同),说明没有节省任何 token,因此应跳过它。 这是每轮的统计值;状态栏会保留整个会话的累计值。
绝不要将 graft 命令通过
head
、
tail
或
sed -n
管道处理。每个工具都已经设置了结果上限,并会说明省略了什么;截断输出会丢失所需命中项,还会静默删除状态栏用于累计统计的节省信息行。

When graft isn't enough

graft 不足时

  • Span truncated ("+N more lines"): open the file at that exact range.
  • A node lacks a detail: ask a more specific question; only then read source at the exact
    file:line
    , never a whole file to rebuild understanding graft gives.
  • You may also grep / ls / cat inside
    graft/
    directly (plain markdown;
    graft/INDEX.md
    indexes the nodes), but the tools above are faster and exhaustive where it matters, so reach for them first.
When the graft MCP server is connected, these are exposed as tools too:
graft_find_code
,
graft_find_all
,
graft_file_api
,
graft_trace_calls
(with
direction
/
depth
),
graft_repo_map
,
graft_check_freshness
. Use whichever surface is available; the guidance is identical.
  • 区间被截断(“+N more lines”):在对应位置打开文件,只查看那个确切范围。
  • 节点缺少某项细节:提出更具体的问题;只有在此之后,才在确切的
    file:line
    处读取源代码,绝不能为了重建 graft 已提供的理解而读取整个文件。
  • 也可以直接在
    graft/
    中使用 grep / ls / cat(纯 Markdown;
    graft/INDEX.md
    索引了各个节点),但上述工具速度更快,并且在关键场景中更穷尽,因此应优先使用它们。
连接 graft MCP server 后,以下功能也会以工具形式提供:
graft_find_code
、
graft_find_all
、
graft_file_api
、
graft_trace_calls
(支持
direction
/
depth
)、
graft_repo_map
、
graft_check_freshness
。使用任意可用的调用入口即可;指导原则完全相同。