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

pi-opener

v0.1.0

Published

Pi extension: open files in $EDITOR via herdr, with per-extension openers (pdf, images, …)

Readme

pi-opener

Pi extension that opens files in your real editor.

  • Terminal editors ($EDITOR / $VISUAL / nvim) open in a herdr split pane by default
  • Pane reuse — later /opens target the same editor pane (or drive nvim/vim/hx in-place)
  • Per-extension openers send PDFs, images, etc. to the OS handler (open on macOS, xdg-open on Linux)
  • Configurable wrapper — herdr-first, or tmux/wezterm/direct via wrapperCommand
  • Slash commands /open / /o (project files) and /recent / /rec (chat-mentioned paths)
  • LLM tool open_file

Install

From npm (recommended)

pi install npm:pi-opener

Or pin a version:

pi install npm:[email protected]

Project-local install (writes .pi/settings.json):

pi install -l npm:pi-opener

From git

pi install git:github.com/yzuyr/pi-opener
# or
pi install https://github.com/yzuyr/pi-opener

From a local checkout

pi install /absolute/path/to/pi-opener
# or, from this repo:
pi install .

Then /reload (or restart pi).

Note: Terminal splits work best inside herdr (HERDR_PANE_ID). Without herdr, set wrapperCommand or use external openers / direct launch.

Usage

/open                     # pick from project files (cwd, ignore-aware)
/o                        # alias for /open
/open src/ind<Tab>        # filesystem path completions
/open src/index.ts
/open src/index.ts:42     # jump to line when the editor supports it

/recent                   # pick from paths mentioned in this chat
/rec                      # alias for /recent
/recent src/foo.ts:10     # open a chat-mentioned path directly

| Command | Source | | ----------------- | -------------------------------------------------------------------------------------------------------------- | | /open, /o | Files under cwd (skips node_modules, .gitignore, etc.) | | /recent, /rec | Paths scraped from this session that still exist on disk (including ignored paths if the chat referenced them) |

Pi has no built-in command-alias API, so short names are registered as separate commands sharing handlers.

The agent can also call open_file.

Config

Primary configuration is loaded from ~/.config/pi-opener/config.yaml (or config.yml).

~/.config/pi-opener/config.yaml

wrapperCommand: herdr

opener:
  code: druk %p:%l # files (line optional → 0)
  dir: druk %p # directories — no %l
  pdf: xdg-open %p # extension keys: with or without leading dot
  md: glow -p %p

See config.example.yaml.

| Key | Meaning | | ---------------- | ------------------------------------------------------------------------------ | | opener.code | Default code editor (default / * / editor also accepted) | | opener.dir | Directory opener (directory / folder aliases). Default: platform opener | | opener.<ext> | Opener for that extension (pdf, .pdf, md, …) | | wrapperCommand | How terminal openers launch (see below). Aliases: wrapper, wrapper_command |

Directories are detected via stat and never go through opener.code, so a file template like %p:%l will not produce dirpath:0 unless you put %l in opener.dir yourself.

wrapperCommand (herdr-first, not herdr-only)

Terminal openers (nvim, bunx druk, …) are launched through a wrapper. Default is herdr when HERDR_PANE_ID is set; otherwise the command runs directly.

Herdr pane reuse and right-split direction are built-in. If you want to change the split direction or force a new pane every time, set a custom wrapperCommand.

# default behavior (can omit)
wrapperCommand: herdr

# never use a wrapper — spawn the opener directly
wrapperCommand: none

# custom split / terminal launcher (e.g. tmux down split)
wrapperCommand: "tmux split-window -v %c"
wrapperCommand: ["wezterm", "cli", "split-pane", "--", "%@"]

| Value | Effect | | --------------------------- | -------------------------------------------------------------------- | | herdr (default) | herdr pane split + run; falls back to direct if herdr is unavailable | | none / direct / false | run opener argv directly (no split) | | string | shell-ish command; %c = full opener command (quoted) | | string array | argv prefix; %@ or %c splices opener argv, else argv is appended |

External openers (xdg-open, opener.dir default, media) never use the wrapper.

Placeholders

| Token | Value | | ----- | --------------------------- | | %p | Absolute file path | | %l | Line number, or 0 if none | | %c | Column, or 0 if none |

If %p is omitted, the path is appended automatically (with editor-specific line jumps when possible).

Platform default openers

| OS | Command | | ------------- | ----------------- | | macOS | open | | Linux / other | xdg-open | | Windows | cmd /c start "" |

Applied to common media extensions (pdf, images, audio, video). Override per-extension under opener:.

mode is auto-detected for xdg-open, open, start, gio, wslview, cmdexternal (detached). Everything else defaults to terminal (launched via wrapper).

Line numbers

| Editor | Jump (when no %l in template) | | ------------------------------ | ------------------------------- | | nvim / vim / vi / nano / emacs | +LINE | | helix | file:LINE | | vscode / cursor / zed | --goto file:LINE | | sublime | file:LINE | | kate | --line=LINE |

Prefer explicit templates when you care: code: nvim +%l %p.

Development

bun install          # or: npm install
bun test
bun run typecheck
npm pack --dry-run   # verify publish contents

Pure logic lives in src/core.ts; the Pi extension entrypoint is src/index.ts.

Publish (maintainers)

# 1. ensure clean tree, tests green
bun test && bun run typecheck

# 2. bump version in package.json if needed
# 3. publish
npm publish --access public

# 4. users install with:
#    pi install npm:pi-opener

Pi installs packages with production deps only (npm install --omit=dev), so runtime deps must stay in dependencies (ignore, yaml). Pi-provided packages stay in peerDependencies (@earendil-works/pi-coding-agent, @earendil-works/pi-tui, typebox).