@jmcombs/pi-better-toolsy
Drop-in replacements for Pi's built-in ls, read, grep, find, edit, and write tools — adds .gitignore awareness, path-traversal protection, and $ injection-safe edits.
Package details
Install @jmcombs/pi-better-toolsy from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@jmcombs/pi-better-toolsy- Package
@jmcombs/pi-better-toolsy- Version
1.1.3- Published
- Jun 7, 2026
- Downloads
- 998/mo · 211/wk
- Author
- jmcombs
- License
- MIT
- Types
- extension
- Size
- 33.4 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
],
"image": "https://raw.githubusercontent.com/jmcombs/pi-extensions/main/assets/better-toolsy/preview.png"
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@jmcombs/pi-better-toolsy
Drop-in replacements for Pi's built-in ls, read, grep, find, edit, and write tools — transparently adds .gitignore awareness, path-traversal protection, and injection-safe edits without changing how the agent works.
Quick Start
pi install @jmcombs/pi-better-toolsy
That's it. The agent uses its normal tool names and your implementations run automatically.
How It Works
Pi exposes six built-in file tools that the LLM is trained to call by name. This extension overrides all six with Node.js implementations that add correctness and safety guarantees the originals lack.
| Tool | What's added |
|---|---|
ls |
.gitignore filtering, dotfile suppression, directories listed as name/ |
read |
50 KB size guard, accurate line-number prefixes when using offset |
grep |
Relative paths in all results, ripgrep fast-path with Node.js fallback, ignoreCase / literal / context flags, .gitignore filtering |
find |
.gitignore filtering, path-based gitignore patterns (dist/**), reliable result cap |
edit |
$-injection-safe replacement (slice arithmetic, not String.replace), uniqueness validation, multiple edits in one call |
write |
Path-traversal guard, automatic parent directory creation |
Because the overrides use the same tool names, the agent's trained behavior is completely unchanged — it calls grep, edit, etc. as always, and the improvements are invisible.
Path Safety
Every tool resolves user-supplied paths through safeResolve(), which blocks directory traversal attacks (../../etc/passwd). Paths are always resolved relative to the current working directory.
.gitignore Awareness
ls, grep, and find load .gitignore at the search root and skip ignored entries. Path-based patterns (dist/**, packages/*/node_modules/) are matched against the full relative path, not just the basename, so nested ignores work correctly.
$ Injection Safety
The built-in edit tool uses String.prototype.replace, which silently expands special $-patterns in replacement text ($&, $`, $', $$). This is especially dangerous in TypeScript source files full of template literals and $-prefixed identifiers. The override uses slice arithmetic so replacement text is always treated as a literal string.
Multi-Edit Support
The edit tool accepts an array of { oldText, newText } pairs and applies them in sequence within a single call. Each edit is validated for uniqueness before any change is written to disk.
Development
This package lives in the pi-extensions monorepo.
# From the repo root
npm ci
npm run check
To test changes locally against a real Pi session:
pi -e ./packages/better-toolsy
License
MIT © Jeremy Combs
