-
Notifications
You must be signed in to change notification settings - Fork 1
Reading by Symbol
ambits -p . show 'src/search.rs::is_binary'{"schema_version":2,"results":[{"query":"src/search.rs::is_binary","selector":"id",
"matches":[{"id":"src/search.rs::is_binary","name":"is_binary","lines":[386,392],
"bytes":[15143,15444],"content_hash":"b3:53a28842…","label":"fn","estimated_tokens":115,
"definition":"/// Whether `buf` looks like something a reader would want printed.\n…\nfn is_binary(buf: &[u8]) -> bool {\n buf.iter().take(BINARY_SNIFF_BYTES).any(|&b| b == 0)\n}"}]}]}A selector is either:
- a symbol id —
<path>::<name-path>, exactly whatrestore-context,rgandcallersprint. Nested symbols join with/:src/app.rs::App/handle_key,README.md::Ambits/Quick start. - a content hash —
b3:<hex>, full or at least 8 hex characters.
Several resolve per invocation, so a batch of lookups costs one process:
ambits -p . show b3:53a28842 'src/digest.rs::grouped' 'src/app.rs::App/handle_key'| Field | Meaning |
|---|---|
lines |
1-based, inclusive — the same range restore-context prints |
bytes |
Byte offsets, for callers that want to slice the file themselves |
content_hash |
BLAKE3 over whitespace-normalized source |
label |
Syntactic kind: fn, struct, impl, h2, … |
children |
Immediate child names, so a container can be walked without a second scan |
definition |
The exact source span, sliced by byte offset rather than reconstructed from lines |
truncated |
Present and true only when --max-bytes cut the definition |
read_depth |
How deeply this session has read the symbol |
The top-level coverage object (session_id, symbols_read) is present only
when a coverage journal was loaded. That is what tells a consumer whether a
missing read_depth means unread or unknown.
--no-body returns location metadata only. --max-bytes N caps each
definition and flags it "truncated": true; it is unlimited by default,
because a cut definition is no longer valid source and shortening one is the
caller's decision.
A definition includes what is about the item directly above it, so editing any of it marks the symbol changed and a search hit inside it is attributed to it:
- its doc comments and any comments glued above it (no blank line between);
- in Rust, its attributes —
#[derive(..)],#[test],#[cfg(..)]— and the docs above those.
And leaves out what is about something else:
- a comment separated from the item by a blank line;
- module docs (
//!,/*! */) and inner attributes (#![..]), which describe the enclosing module; - a comment trailing the previous line's code (
const A: u8 = 1; // about A).
matches is an array because ids are not guaranteed unique — Rust allows a
type several inherent impl blocks in one file, and nothing in the name
distinguishes them. A content hash always names exactly one symbol.
- Empty
matches— no such symbol. -
"selector": "unrecognized"— the query was neither an id nor a hash.
The command exits 0 either way: "nothing matches" is an answer, not a
failure.
Reading a symbol instead of its file is a large saving. src/filter.rs is
several hundred lines — thousands of tokens to read whole — while the handful
of PathFilter methods a caller actually needs come to a few hundred.
estimated_tokens on every match makes that cost visible before the body is
fetched: ask with --no-body first, then fetch only what is worth it.
show lookups are credited as reads, like a plain Read — see
Restoring Context → Lookups count as reads.
Start
For the agent
For you
Reference