@timmyjl12/pi-paste
Keep large pastes out of model context: choose at paste time to attach as a local markdown file, a wrapped block, or inline (like oh-my-pi)
Package details
Install @timmyjl12/pi-paste from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@timmyjl12/pi-paste- Package
@timmyjl12/pi-paste- Version
0.2.1- Published
- Nov 13, 2026
- Downloads
- 323/mo · 16/wk
- Author
- timmyjl12
- License
- MIT
- Types
- extension
- Size
- 35 KB
- Dependencies
- 0 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@timmyjl12/pi-paste
Keeps large pastes out of model context. Paste a large blob into the pi TUI and pi-paste asks where it should go: a local markdown file (the prompt gets a one-line reference), a wrapped block, or inline.
Modeled on the large-paste menu in oh-my-pi. Like omp, it acts at the moment of the paste, so only the pasted text is affected and whatever you have already typed stays in the editor.
How it works
When a terminal paste is large (≥ 100 lines or ≥ 8 KiB by default), pi-paste takes it before the editor does and shows a menu:
- Attach as local file — write the text to a private local
.mdfile and insert a short reference at the cursor. - Attach as a wrapped block — insert the text wrapped in
<attachment>tags. It still enters the context; pi collapses it to a[paste #N]marker in the editor. - Paste inline — insert the text unchanged (also what Esc does).
The menu is a convenience, never a gate: Esc, a timeout or any error puts the original text into the editor.
Example
You type Why does this fail? and paste 500 lines of logs, then choose Attach as local file. The editor, and the prompt the model receives, is:
Why does this fail? [Pasted 500 lines saved to file: C:\Users\you\AppData\Local\Temp\pi-paste\<session>\paste-1.md]
The model can read the file on demand.
Smaller pastes
Below the thresholds pi-paste does nothing. pi itself folds a paste of more than 10 lines or 1,000 characters into a [paste #N] marker in the editor, but that is display only: the full text is still sent. Lower PI_PASTE_MIN_LINES if you want the menu for those too.
Submit-time fallback
Large text that reaches the prompt without passing the menu (a clipboard read that bypasses terminal paste, or a terminal without bracketed paste) is offered once at submit: Send as-is or Attach the whole message as a file. Attaching saves the entire message, including anything typed around the paste, and tells the model to read that file.
Install
pi install npm:@timmyjl12/pi-paste
For one run without installing:
pi -e npm:@timmyjl12/pi-paste
Configuration
All settings are environment variables.
| Variable | Default | Purpose |
|---|---|---|
PI_PASTE_ROOT |
<os.tmpdir()>/pi-paste |
Storage root for attachment files |
PI_PASTE_MIN_LINES |
100 |
Line threshold that counts as a large paste |
PI_PASTE_MIN_BYTES |
8192 (8 KiB) |
Byte threshold (catches a long single line) |
PI_PASTE_TTL_MS |
604800000 (7 days) |
Retention period for attachment directories |
PI_PASTE_SELECT_TIMEOUT_MS |
300000 (5 min) |
Menu timeout; on expiry the text is pasted inline |
PI_PASTE_DEBUG |
unset | When 1, emit debug logs to stderr |
A paste triggers the menu when its UTF-8 byte length ≥ PI_PASTE_MIN_BYTES or its line count ≥ PI_PASTE_MIN_LINES.
Safety notes
- Attachment files are written with mode
0600under a root created with mode0700. This is enforced on POSIX; on Windows, access is governed by the inherited per-user temp ACL. - Writes are atomic (temp file + rename, with a bounded retry for transient Windows
EPERM/EBUSY/EACCES). - The per-session counter is derived from existing files, so a reload mid-session resumes instead of overwriting
paste-1.md. - Paste content is written only to local files. Nothing is sent to any external service.
- Expired per-session directories are removed best-effort on
session_start(default 7 days). The live session's directory is never cleaned. - The menu exists only in
tuimode. Inrpc,jsonandprintmodes input passes through unchanged.
When the menu is not offered
- the paste is below both thresholds;
- another dialog is open (the paste belongs to that dialog);
- the menu is already open for an earlier paste;
- the terminal does not send bracketed paste (the submit-time fallback applies instead).
The submit-time fallback is additionally skipped for extension-sourced input, steering messages and input carrying images.
Limits
- Verified against pi 1.5.2 with pi's real editor and session classes in tests; the terminal itself is simulated there.
- Works with extensions that replace or wrap pi's editor, as long as that editor passes bracketed pastes on to pi's own (checked with pi-typeahead, pi-advisor and pi-supervisor).
- pi's own Ctrl+V clipboard shortcut inserts text without a paste event. If your terminal passes Ctrl+V through to pi instead of pasting itself, that text skips the paste-time menu and is caught by the submit-time fallback.
Development
npm run typecheck # TypeScript compilation check
npm run lint # ESLint
npm run format # Prettier
npm test # node:test: unit tests, pi's real editor, and a real pi session with a scripted model
npm run check # all of the above
License
MIT — see LICENSE.