原始内容
pi-fff-non-ascii-guard
Pi extension that prevents fff-core panics caused by non-ASCII filenames.
See the Roadmap for the maintenance direction and planned work.
What this is
A Pi extension that detects and renames non-ASCII filenames before fff-core can panic on UTF-8 byte boundaries. It scans your workspace on session start, warns about problematic filenames, and provides a tool to safely rename them to ASCII slugs.
Problem
fff-core can panic when it slices UTF-8 paths at byte offsets that are not character boundaries — for example, paths containing Japanese characters:
thread '<unnamed>' panicked at crates\fff-core\src\constraints.rs:73:13:
byte index 65 is not a char boundary
This extension prevents the known crash by keeping scanned filenames ASCII-safe.
Features
- Session-start scan — automatically detects non-ASCII paths when a Pi session begins
- fff tool gate — blocks
grep,find_files, andfff_multi_grepwhile non-ASCII paths remain (prevents fff-core panic) - Warning notification — alerts the LLM when problematic paths are found
list_non_ascii_pathstool — list files and directories with non-ASCII path segmentssanitize_filenamestool — preview or execute safe ASCII slug renames for files- Smart exclusions — skips
.git,.obsidian,.pi,.claude,.scratch, andnode_modules - Collision disambiguation — when two files slug to the same name, appends
-2,-3, … and continues
Install
pi install git:github.com/eiei114/pi-fff-non-ascii-guard
For project-local install:
pi install -l git:github.com/eiei114/pi-fff-non-ascii-guard
Quick start
- Install the extension (see Install).
- Start a Pi session in a workspace that may contain non-ASCII filenames.
- If non-ASCII filenames are detected, Pi shows a warning with the file list.
- Ask the LLM to call
sanitize_filenameswithdryRun: trueto preview, thendryRun: falseto execute. - After paths are ASCII-safe,
grep/find_files/fff_multi_grepwork again.
While non-ASCII paths exist, Pi blocks fff search tools and returns a fix hint instead of crashing.
Usage summary
list_non_ascii_paths tool
Lists every file and directory whose relative path contains non-ASCII characters. No parameters.
sanitize_filenames tool
| Parameter | Type | Default | Description |
|---|---|---|---|
dryRun |
boolean | true |
Preview renames without executing |
Preview renames:
{ "dryRun": true }
Execute renames:
{ "dryRun": false }
Dry-run output is a stable report of each relative source path and its proposed destination path:
Dry run -- 2 file(s) to rename:
scripts/SpreadsheetToJson_wrapあり・nullなし.gs -> scripts/spreadsheettojson_wrap-null.gs
scripts/SpreadsheetToJson_wrapなし・nullあり.gs -> scripts/spreadsheettojson_wrap-null-2.gs
No filesystem changes made.
Conflict preview (auto-suffixed -2, -3, ... when needed):
[slug collision] scripts/spreadsheettojson_wrap-null.gs <- scripts/SpreadsheetToJson_wrapあり・nullなし.gs, scripts/SpreadsheetToJson_wrapなし・nullあり.gs; planned: scripts/spreadsheettojson_wrap-null.gs, scripts/spreadsheettojson_wrap-null-2.gs
If two files would collide after slug conversion, or if the first-choice destination already exists on disk, the conflict preview flags the risk before you run apply mode. The current behavior is to auto-suffix planned destinations (-2, -3, …) so the batch can proceed without manual renaming. Future collision-policy work may tune those suffix rules; for now, treat the preview as the source of truth and manually rename files first if the proposed suffixes are not what you want.
Apply mode returns a list of completed renames and any errors.
Package contents
pi-fff-non-ascii-guard/
├── extensions/
│ └── pi-fff-non-ascii-guard.ts # Extension entry
├── lib/ # Scan, slug, rename-plan helpers
├── tests/ # Smoke tests
├── .github/workflows/
│ ├── auto-release.yml # Auto-tag + release on merge to main
│ ├── ci.yml # Validate on PR / push
│ └── publish.yml # Publish to npm on tag or release
├── CHANGELOG.md
├── LICENSE # MIT
├── SECURITY.md # Vulnerability reporting
├── package.json
└── README.md
Development
Clone and validate:
git clone https://github.com/eiei114/pi-fff-non-ascii-guard.git
cd pi-fff-non-ascii-guard
npm run typecheck # type-check all TypeScript sources
npm test # smoke tests
npm run check # typecheck + tests + npm pack --dry-run
Release
Planned maintenance work is tracked in ROADMAP.md. Releases are automated:
- Bump
versioninpackage.json. - Merge to
main. - The Auto Release workflow tags
v<version>and creates a GitHub release. - The tag triggers the Publish workflow, which publishes to npm with provenance.
Security
See SECURITY.md for vulnerability reporting.
- No network requests.
- No environment variables or secrets read.
- Only renames files within the current Pi workspace directory.
- Skips hidden and internal directories (
.git,.obsidian,.pi,.claude,.scratch,node_modules).
Real incidents
This extension was created after Pi crashed while updating .pi/monofold.yaml in an Obsidian vault that contained Japanese PDF filenames.
Another crash while editing AGENTS.md in a Roblox repo with Google Apps Script files:
thread '<unnamed>' panicked at crates\fff-core\src\constraints.rs:73:13:
byte index 44 is not a char boundary; it is inside 'な' (bytes 43..46) of
`scripts\SpreadsheetToJson_wrapあり・nullなし.gs`
The fff tool gate blocks grep, find_files, and fff_multi_grep until those paths are renamed.
Observed error:
thread '<unnamed>' panicked at crates\fff-core\src\constraints.rs:73:13:
byte index 65 is not a char boundary; it is inside 'イ' (bytes 63..66) of `2_Literature\2_Tools\Pi Coding Agent - 初心者向け比較ガイド - slides.pdf`
Both offending files were renamed to ASCII slugs:
2_Literature/2_Tools/pi-coding-agent-beginner-guide-slides.pdf
2_Literature/PKM/3x-zettelkasten-ai-serial-acceleration.pdf
Links
- Repository: https://github.com/eiei114/pi-fff-non-ascii-guard
- npm: https://www.npmjs.com/package/pi-fff-non-ascii-guard
- Issues: https://github.com/eiei114/pi-fff-non-ascii-guard/issues
License
MIT © Keisu
