@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.

Packages

Package details

extension

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