Working with the graph
These are the tools your agent calls all day. You rarely invoke them by hand — but knowing what each one does, and the order they go in, is how you tell whether the agent is using pincher well.
The mental model
One symbols table feeds three layers, all populated in a
single parse pass:
- Byte-offset store — every symbol records its exact start/end byte. Reading a function is one SQL row plus one file seek; no re-parsing, no whole-file read.
- Knowledge graph —
CALLS,IMPORTS,READS/WRITESedges between symbols. - FTS5 search — BM25 full-text ranking over symbol names, signatures, and docs.
The navigation tools each lean on one or more of those layers.
search — find code by name or keyword
Always the first call when you don't have a symbol ID yet.
search runs BM25 over the code corpus and returns ranked hits
with signatures. It supports prefix (auth*), phrase
("token validation"), and filters by kind,
language, and corpus (code /
config / docs).
search query="processOrder"
search query="auth*" kind=Function language=Go
symbol, symbols, context — read a symbol
Once you have an ID ({file}::{qualified_name}#{kind}):
symbol— one symbol's source via the byte-offset seek.symbols— a batch of IDs in one round trip.context— the symbol plus its direct imports and callees. This is the one to reach for before editing: you see the function and everything it depends on in a single response, ~90% cheaper than reading the files.
context id="internal/db/db.go::db.Open#Function"
trace — follow the call graph
trace walks CALLS-family edges with a breadth-first search and
tags each hop with a risk label (CRITICAL = direct caller, HIGH = two
hops, …). Use direction=inbound for "who calls this",
outbound for "what does this call".
trace name="processOrder" direction=inbound
trace inbound on the symbol you're about to edit — it is
the cheap way to see the blast radius before you touch anything.
query — structural questions in pinchQL
When you want relationships, not text matches, query takes
pinchQL — a pragmatic Cypher-shaped subset with MATCH,
WHERE, RETURN, single-hop joins, and bounded
variable-length traversal:
# every caller of Open
MATCH (a)-[:CALLS]->(b) WHERE b.name="Open" RETURN a.name
# functions in the server package with no inbound calls (audit shape)
MATCH (n:Function) WHERE n.file_path CONTAINS "server" RETURN n.name
architecture & neighborhood — orient
architecture is the once-at-the-start call for an unfamiliar
repo: entry points, hotspots (most-called symbols), language breakdown,
node and edge counts. neighborhood returns the other symbols
in the same file as a seed — handy for planning an in-file refactor.
The workflow shape
The tools compose into one loop, and it's worth recognizing when the agent follows it:
architecture → orient (once, on unfamiliar code)
search / query → find the symbol
context / symbol → read it
trace → check impact, if you're changing behavior
…edit…
changes → verify the blast radius before you're done
For audit-shaped questions ("find every X without Y"), skip straight to
query with a property predicate.