pi-path-guard

Pi extension package that normalizes path-like tool arguments and enriches filesystem/edit failures.

Packages

Package details

extension

Install pi-path-guard from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-path-guard
Package
pi-path-guard
Version
0.1.1
Published
Jun 4, 2026
Downloads
not available
Author
conte777
License
MIT
Types
extension
Size
52 KB
Dependencies
0 dependencies · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./extensions"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-path-guard

pi-path-guard is a pi package that reduces common tool-call failures by normalizing path-like arguments, running filesystem preflight checks, and appending actionable diagnostics to failed tool results.

Install

pi install npm:pi-path-guard
# or
pi install git:github.com/org/pi-path-guard@v1

The package is discovered through package.json:

{
  "keywords": ["pi-package"],
  "pi": { "extensions": ["./extensions"] }
}

What it does

  • Normalizes path-like arguments before tool_call execution:
    • ~/Work/x/Users/conte/Work/x
    • ~/Users/conte
    • @file.tsfile.ts
    • file:///tmp/x/tmp/x
    • Unicode spaces → normal spaces
  • Blocks calls that are known to fail in strict mode:
    • read(path=".") before EISDIR
    • missing files for read, edit, ctx_execute_file
    • missing parent directories for write
    • invalid GitNexus repo: "~"
  • Enriches failed tool_result messages with:
    • closest matches for edit mismatches
    • line numbers for non-unique edit blocks
    • stale-read and formatter hints
    • generic path diagnostics for ENOENT, Path not found, EISDIR
    • ctx_execute command-not-found hints
  • Handles nested calls in multi_tool_use.parallel.
  • Parses mcp.args JSON strings, normalizes path-like fields inside, then serializes back to JSON.

Before / after

Directory read

Before:

read EISDIR

After:

Blocked: read expects a file, but got a directory:
/Users/conte/Work/project

Use ls/find instead:
- ls(path="/Users/conte/Work/project")
- find(path="/Users/conte/Work/project", pattern="...")

Missing path

Blocked before tool execution: path does not exist.

Raw: ~/Work/foo
Normalized: /Users/conte/Work/foo
Parent exists: /Users/conte/Work

Similar paths:
- /Users/conte/Work/foo-service
- /Users/conte/Work/foobar

Edit mismatch

Edit diagnostic: edits[0].oldText was not found.

Closest matches:
1. lines 118-126, similarity 0.82
   read(path="package/src/orchestrator-gate.ts", offset=112, limit=22)

Likely causes:
- file changed since last read
- formatter changed whitespace
- oldText copied from stale content

Configuration

Configuration is read from the first available JSON source:

  • .pi/path-guard.json
  • path-guard.config.json
  • .path-guard.json
  • package.json pathGuard key
  • PATH_GUARD_CONFIG_JSON environment variable

Environment overrides:

  • PATH_GUARD_MODE=strict|warn|off
  • PATH_GUARD_HOME_DIR=/Users/conte
  • PATH_GUARD_TELEMETRY=1|0

Default config:

{
  "pathGuard": {
    "mode": "strict",
    "homeDir": "/Users/conte",
    "normalize": {
      "tilde": true,
      "atPrefix": true,
      "fileUrl": true,
      "unicodeSpaces": true
    },
    "preflight": {
      "enabled": true,
      "blockReadDirectories": true,
      "blockMissingReadPaths": true,
      "blockMissingEditPaths": true,
      "blockMissingWriteParents": true
    },
    "editDiagnostics": {
      "enabled": true,
      "maxClosestMatches": 5,
      "contextLines": 6
    },
    "telemetry": {
      "enabled": true
    },
    "overrideBuiltinTools": false
  }
}

Modes:

  • strict — normalize and block bad calls.
  • warn — normalize and show warnings instead of most blocks.
  • off — collect no interventions; hooks return without mutation.

Commands

  • /path-guard-stats — shows session counters.
  • /path-guard-config — shows effective config.
  • /path-guard-reset — resets session-local stats, read tracking, and formatter tracking.

Safety

pi-path-guard does not override built-in tools by default. It uses tool_call and tool_result middleware so built-in rendering and result shapes remain intact.

It intentionally does not normalize dangerous free-text fields such as oldText, newText, command, code, query, prompt, content, or message.

Tests

npm test
npm run pack:dry-run

Publishing

Before publishing, verify package contents:

npm test
npm run pack:dry-run

Then publish from the package root:

npm publish

The published tarball is intentionally limited by the files field to runtime extension sources, README.md, and LICENSE.