Pi package that replaces the built-in bash, find, grep, read, edit, and write tools with
native-backed, simpler versions.
pi install git:github.com/Assassinss/pi-native-toolsWarm native shell sessions for faster repeated commands. Supports session, resetSession, and
timeout controls.
Native glob search with normalized relative paths. Only use when you don't know the file path —
if you already have a file name, use read directly.
Native in-process search with regex, literal, context, locations, content, count, and
files-with-matches modes. The default locations mode returns compact file:line results (grouped
as file:start-end) without copying matching source text into context. Use the returned line
numbers with read and ranges to inspect only the relevant sections, for example:
grep({ pattern: "needle", path: "." })
→ src/main.ts:12,30-34
read({ locations: "src/main.ts:12,30-34" })
// or: read({ path: "src/main.ts", ranges: [{ start: 12 }, { start: 30, end: 34 }] })
Pass the complete locations output to read({ locations }) to inspect the reported ranges directly.
Use mode: "content" when the matching text itself is needed. Use context with locations to
expand each returned line into a directly readable line range. Use grep only to search across
files for patterns, symbols, or definitions — never as a substitute for reading a file.
Read file contents. The primary way to inspect files — when you know the file path, call read
directly, don't grep or find first. Returns a snapshotId at the end of its output text for
use with edit.
Parameters: path, locations, offset / limit, explicit ranges with optional before/after context,
outline, force, binary/NUL rejection, and large-file streaming. After grep locates a symbol,
prefer ranges around its reported line instead of reading the complete file.
outline — returns a structural outline (function/class/type declarations with line numbers)
instead of full content. Supports TS/JS/Python/Rust/Go/Java/C/C++/Markdown/JSON/YAML via regex
patterns; other files fall back to top-level non-empty lines. Combine outline with ranges to
get structure + target content in one call.
Dedup — unchanged re-reads are blocked automatically. When the file's mtime hasn't changed
since the last full read, read returns a short Content unchanged ... Content is already in your context. message instead of re-sending content. Only full-file reads seed the dedup cache;
partial reads (offset/limit/partial ranges/outline-only) don't block subsequent reads of
other sections.
force — escape hatch to bypass dedup. Not mentioned in prompt guidelines or schema
description so agents don't preemptively bypass dedup; the dedup message itself tells the agent
when to use it.
Edit a file by replacing exact oldText with newText. Requires a prior read to get the
current text and snapshotId.
Parameters: path, snapshotId (required — from the last read of this file), oldText,
newText, replaceAll (default false).
Conflict responses:
not_found— oldText doesn't exist in the fileambiguous— oldText matched multiple locations; narrow and retrystale_snapshot— file changed since last read; re-read and retry
After a successful edit, the response includes a new snapshotId and the message
"Use this snapshotId for your next edit on this file — no need to re-read."
Write content to a file with streaming support, verified writes, hashline stripping, and shebang executable support on Unix-like systems.
read(path, ...) → returns text + "snapshotId: rev_xxx"
edit(path, snapshotId=rev_xxx, oldText, newText) → applies replacement + returns new snapshotId
readthe file to get current text andsnapshotIdeditwitholdText/newTextand thesnapshotIdfrom step 1- For follow-up edits on the same file, use the
snapshotIdfrom the edit response directly — no need to re-read - Only re-read when
editreturnsstale_snapshotorambiguous - To discover a file's structure before reading specific sections, use
outline=true(optionally combined withrangesfor structure + content in one call)
npm install
npm test