npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@faiku/pi-inline-image-paste

v0.1.2

Published

Pi extension that attaches pasted images inline to your prompt instead of inserting a temporary file path

Readme

@faiku/pi-inline-image-paste

A pi extension that attaches pasted images to your message as real image content, instead of dropping a temporary file path into the text.

Out of the box, pasting a screenshot into pi inserts the path of a file in your temp directory. With this extension the image itself is queued: a thumbnail appears above the editor, a [image N] token marks its place in your text, and on send the token is swapped for the image bytes. The model receives the picture; the transcript shows a short note describing it.

What it does

| Action | Result | |---|---| | ctrl+v with an image on the clipboard | Image queued, thumbnail shown, [image N] inserted at the cursor | | ctrl+v with text on the clipboard | Pasted as text, exactly as pi does it | | Drag and drop an image file into the terminal, or paste its path | The image is queued and the path is replaced | | A terminal that streams image bytes into the paste | The image is queued from the raw byte stream | | /image-attach shot.png | Same, by hand |

The paste keybinding is whatever app.clipboard.pasteImage is bound to in your keybindings, so a rebinding is picked up automatically. It defaults to ctrl+v (alt+v on Windows). On macOS use ctrl+v, not cmd+v: terminals deliver cmd+v as a text paste, and there is usually nothing to read from the clipboard in that case.

Commands

| Command | Effect | |---|---| | /image-attach <path> [path…] | Attach image files to the next message | | /image-list | Show the queued images with their number, size, and format | | /image-clear | Drop every queued image and remove the tokens from the editor | | /image-notes | Toggle the [image N: 1440x900 PNG, 231 KB] note in sent messages |

The preview

Above the editor you get a strip of thumbnails, drawn with the terminal's own graphics protocol (kitty, iTerm2, WezTerm, Ghostty) and a compact #1 1440x900 PNG label everywhere else, plus a caption:

 #1 screenshot.png  #2 diagram.png  +1 more
 3 images attached · 1.2 MB · /image-clear to remove
> compare these two [image 1] [image 2] [image 3]

Behaviour worth knowing

  • The token is the manifest. An image is queued when its [image N] token is in the editor, and dropped as soon as you delete that token: the thumbnail leaves with it, without waiting for the message. Clearing the editor therefore drops the queued images too; re-paste or use /image-attach to get them back. A submitted message that somehow has no token (RPC, print mode) still sends everything queued, so nothing is lost on a path with no editor to watch.
  • pi does not render images in the transcript. It only draws the text part of a user message, so each image leaves a one-line note behind. /image-notes turns the notes off; the images are still sent, and a message made only of images falls back to (2 images attached) so the turn is not blank.
  • Queued images are cleared on send, including while the model is streaming (ctrl+v mid-answer works: the image joins the steered or follow-up message).
  • Limits are enforced per message: 20 images and 32 MB by default. The extension asks before queueing anything over the limit.
  • Extension commands run before the input event, so typing /model-global never swallows your attachments.
  • Formats: PNG, JPEG, GIF, and WebP. Anything else is rejected with a message rather than attached.
  • Images are never written to disk. Bytes are held in memory and passed straight to the model.
  • The raw-stdin capture only ever withholds an image paste; every other byte is forwarded to pi's input pipeline unchanged and in its original order, and the original listeners are restored on session_shutdown, including on /reload.

Configuration

Optional block in <agent-dir>/settings.json (default ~/.pi/agent/settings.json):

{
  "imagePaste": {
    "maxImages": 20,
    "maxTotalMb": 32,
    "showNotes": true,
    "showPreview": true,
    "maxThumbnails": 4
  }
}

showNotes is the only key /image-notes writes; it is merged into the file, leaving everything else alone.

Install

From npm (recommended):

pi install npm:@faiku/pi-inline-image-paste

Try it for a single run without installing:

pi -e npm:@faiku/pi-inline-image-paste

From a local checkout:

ln -s "$PWD" ~/.pi/agent/extensions/pi-inline-image-paste

Per project, or for one run:

pi --extension ./index.ts
# add to <project>/.pi/settings.json
{ "extensions": ["/absolute/path/to/pi-inline-image-paste"] }

Development

npm install          # dev-only: types for typechecking
npm test             # unit tests for sniffing, capture, attachments, config
npm run typecheck    # tsc --noEmit

Layout: index.ts (wiring: events, capture, editor reconciliation, commands), lib/images.ts (magic-byte sniffing, dimensions, formatting), lib/raw-stdin.ts (byte-level paste interception), lib/paste.ts (paste keybinding and dropped-path parsing), lib/clipboard.ts (clipboard backends), lib/attachments.ts (tokens, notes, the send-time transform), lib/attachment-bar.ts (thumbnail strip), lib/config.ts and lib/settings.ts (settings).

The extension ships as TypeScript source — pi loads .ts entry points directly, so there is no build step.

A note on the capture layer

pi reads stdin and decodes every chunk as UTF-8 before an extension sees it, which turns image bytes into replacement characters. So a terminal that streams an image into the paste cannot be handled through pi's string-level input hook. This extension therefore takes over the data listeners on process.stdin for the duration of the session, inspects raw bytes, and forwards everything that is not an image paste to the listeners it displaced. In practice the clipboard and drag-and-drop paths carry the feature on their own; the raw path exists so a byte-streaming terminal is not left with a corrupted paste in the editor.

License

MIT

pi-inline-image-paste