@timmyjl12/pi-paste0.1.1
Attach large pasted text as a local markdown attachment with a paste-as-is vs. attach choice
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
@timmyjl12/pi-paste
Keeps large pastes out of model context. When you paste a large blob into the pi TUI, pi-paste offers to attach it as a local markdown file instead of inlining it — so the model gets a short file reference it can
readon demand, not a 100 KB paste.
pi-paste is a Pi extension that intercepts large interactive pastes on the public input event and presents a "Paste as-is" vs. "Attach as markdown" choice, modeled on the large-paste menu in oh-my-pi and built on the stable patterns of pi-pasteboard.
How it works
When you submit input in the TUI that is large (≥ 64 KiB or ≥ 100 lines by default), pi-paste shows a selector:
- Paste as-is — deliver the input to the agent unchanged (the default pi behavior).
- Attach as markdown — write the text to a private local
.mdfile and replace the prompt with a short reference to that file.
The choice is a convenience, never a gate: pressing Esc (or choosing "Paste as-is") delivers the original text, and any error fails open so your input is never lost.
Example
You paste 500 lines of logs. Instead of inlining them, the model receives:
Pasted content saved to C:\Users\you\AppData\Local\Temp\pi-paste\<session>\paste-1.md. Read that file if needed; do not ask the user to paste it again.
and can read the file on demand.
Install
pi install npm:@timmyjl12/pi-paste
For one run without installing:
pi -e npm:@timmyjl12/pi-paste
The package manifest exposes ./index.ts as a Pi extension.
Configuration
All settings are environment variables.
| Variable | Default | Purpose |
|---|---|---|
PI_PASTE_ROOT |
<os.tmpdir()>/pi-paste |
Storage root for attachment files |
PI_PASTE_MIN_BYTES |
65536 (64 KiB) |
Byte threshold that counts as a large paste |
PI_PASTE_MIN_LINES |
100 |
Line threshold that counts as a large paste |
PI_PASTE_TTL_MS |
604800000 (7 days) |
Retention period for attachment directories |
PI_PASTE_SELECT_TIMEOUT_MS |
300000 (5 min) |
Timeout for the paste-choice selector (auto-dismisses to paste-as-is) |
PI_PASTE_DEBUG |
unset | When 1, emit debug logs to stderr |
An input triggers the choice 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
0600(owner-only) under a root created with mode0700. This guarantee is enforced on POSIX; on Windows, access is governed by the inherited per-user temp ACL rather than mode bits. - Writes are atomic (temp file + rename) and the file mode is enforced with
chmodso a permissive umask cannot widen it. - The per-session counter is derived from existing files, so an extension 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, and only the file reference enters the prompt — never the paste contents.
- Expired per-session directories are removed best-effort on
session_start(TTL, default 7 days). The live session's directory is never cleaned. - The extension loads in all four pi modes (tui, rpc, json, print); the choice is offered only in
tuimode. In other modes, input passes through unchanged.
Bypass logic
The choice is not offered when the input is:
- not in TUI mode (
rpc/json/print); - extension-sourced or non-interactive;
- a steering message (
streamingBehavior === "steer"); - carrying images;
- below both size thresholds.
Slash (/), bang (!), and likely @-file-reference heuristics apply only below the size thresholds. They detect hand-typed prompts; scanning a large paste for them would misfire on ordinary content — git-diff @@ hunk headers, @decorator lines, comment blocks starting with /** — and silently skip exactly the pastes this extension exists to intercept. Large interactive input always offers the choice.
Development
npm run typecheck # TypeScript compilation check
npm run lint # ESLint
npm run format # Prettier
npm test # node:test unit tests
npm run check # all of the above (typecheck && lint && format:check && test)
License
MIT — see LICENSE.