pi-encoding-fs
Encoding-aware read/write/edit/grep for Pi — transparent GB18030/GBK/GB2312 support
Package details
Install pi-encoding-fs from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-encoding-fs- Package
pi-encoding-fs- Version
0.4.0- Published
- Jul 22, 2026
- Downloads
- 133/mo · 133/wk
- Author
- yuanwentao
- License
- MIT
- Types
- extension
- Size
- 45.3 KB
- Dependencies
- 2 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-encoding-fs
Encoding-aware read / write / edit / grep for Pi.
Transparently handles GB18030 / GBK / GB2312 files while preserving Pi's native TUI
(diff view, syntax highlighting, line numbers).
How it works
The extension registers tools with the same names as Pi's built-ins, overriding them.
read/write/edit reuse Pi's own tool skeletons via createXxxToolDefinition, injecting
encoding conversion only at the byte-IO layer, so Pi keeps computing and rendering diffs in
UTF-8. grep is self-implemented so it can search Chinese text inside GB-encoded files.
Encoding is decided per file: the extension walks up from the file's directory to the
nearest .encoding-converter.json. If none is found, it passes through as plain UTF-8
(identical to not having the extension installed).
The extension also injects a short note into the system prompt so the agent knows the
built-in tools already handle GB↔UTF-8 transcoding (no need to run iconv or re-save
files), and — when no config exists — how to create a .encoding-converter.json itself
if it ever reads garbled Chinese. The note is constant so prompt caching stays effective.
Configuration
Place .encoding-converter.json in any directory. It applies to files at or below it,
unless a deeper config overrides it.
{
"sourceEncoding": "GB18030",
"confidenceThreshold": 0.8,
"overrides": [
{ "pattern": "docs/**", "sourceEncoding": "UTF-8" },
{ "pattern": "legacy/**", "sourceEncoding": "GBK" }
]
}
sourceEncoding: default encoding when detection is uncertain; also used for new files.confidenceThreshold: minimum chardet confidence (0-1) to trust auto-detection.overrides: glob rules relative to the config file's directory; most specific wins.
Requirements
- A Pi agent (peer dependency;
>=0.80.0). - Encoding detection (for
read/write/edit) uses Python 3 +chardetwhen available. If Python is missing, the extension silently falls back tosourceEncodingfrom config. grepuses ripgrep (rg) for fast, encoding-aware search. Ifrgis not found onPATH,greptransparently falls back to Pi's built-in grep (which cannot search inside GB-encoded files).
Install
From npm:
pi install npm:pi-encoding-fs
From git:
pi install git:github.com/15wtyuan/pi-encoding-fs
Notes / limitations
- Only
read/write/edit/grepare overridden.bash,find, andlsare not touched (e.g. acatinsidebashwon't decode GB files). grepshells out toripgrepwith--encodingper encoding group (derived from the nearest.encoding-converter.json), so searching Chinese inside GB18030 files is both correct and fast. It excludes.git/.svn/.hg/node_modulesby default. Honoring.gitignoreand aligning match limits with Pi's built-in grep are planned.
edit preview for GB-encoded files
Pi's edit tool reads the file in two places: execute() (via this extension's
encoding-aware operations.readFile, correct) and the TUI streaming preview
(computeEditsDiff(), which uses the built-in readFile(path, "utf-8") and bypasses
this extension). For a GB18030/GBK file the preview would read raw GB bytes as UTF-8
(mojibake), fail to match a Chinese oldText, and flash a false red
"Could not find the exact text in " box during streaming — even though the real
edit succeeds.
This extension overrides edit's renderCall so that non-UTF-8 files get an
encoding-aware preview instead: it reads through operations.readFile, computes the
diff with Pi's public generateDiffString + renderDiff, and renders a header that
matches Pi's native edit styling. UTF-8 files delegate to Pi's original renderer
unchanged.
Known trade-offs of this approach (no upstream change required):
- The preview uses exact
oldTextmatching only (Pi's private fuzzy matcher isn't exported). If the model'soldTextneeds fuzzy normalization (trailing whitespace / smart-quote drift) the preview shows just the header, then the real edit runs and Pi'srenderResultreplaces it with the actual diff. GB files never get a false red error box anymore. - The UTF-8 vs GB decision is a byte-level probe (
TextDecoder("utf-8",{fatal:true})throws on GB bytes), mtime-cached. A genuinely single-byte legacy encoding (ISO-8859 / Windows-1252) would be treated as non-UTF-8 and routed through the encoding-aware preview; this is harmless as long as a matching.encoding-converter.jsonexists.
License
MIT