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

@cemoody/pi-crust-ext-terminal

v0.1.3

Published

Browser terminal (PTY) for pi-crust, as a sidebar activity view. Streams a real shell over the realtime gateway.

Readme

@cemoody/pi-crust-ext-terminal

A browser terminal for pi-crust, packaged as an extension. It adds a Terminal item to the sidebar that streams a real shell (PTY) for the active session over pi-crust's realtime gateway.

  • Server (server.mjs): registers the pty:* protocol on the shared Socket.IO gateway via ctx.server.realtime.onConnection, spawning a real shell with node-pty. The shell's working directory is the session's cwd — it can never escape the session root.
  • Web (web.mjs): a self-contained ESM module that renders a wterm DOM terminal and connects a dedicated socket to the page origin. React is provided by the host.

Requirements

  • pi-crust with the ctx.server.realtime extension API. This shipped in core via PR #219 — you need a pi-crust release newer than 0.2.2. On an older host the extension refuses to activate with a clear error (and the Settings "Add a source" install returns a 400 with that message), rather than half-loading.
  • Recommended: pi-crust ≥ 0.3.2. Earlier releases work, but:
    • ≥ 0.3.0 is needed to install via Settings without a server restart (older hosts require a restart after install).
    • ≥ 0.3.2 renders the dedicated terminal sidebar glyph; older hosts fall back to the generic extension icon (the terminal still works).
  • Node ≥ 22 (for node-pty's prebuilt binaries / native build).

Install

In pi-crust, open Settings → Extensions → Add a source and enter:

npm:@cemoody/pi-crust-ext-terminal

Or add it to your pi-crust settings.json:

{
  "packages": [
    { "source": "npm:@cemoody/pi-crust-ext-terminal", "kind": "npm" }
  ]
}

You can also install from a git URL (git:https://github.com/cemoody/pi-crust-ext-terminal) or a local checkout path.

Usage

After installing, a Terminal entry appears in the sidebar. Click it to open a shell bound to the active session's working directory. Closing the tab (or disconnecting) tears the shell down — no orphan processes.

A small toolbar (top-right, styled like the host's action buttons) offers:

  • Copy — copy the visible terminal buffer to the clipboard.
  • Clear — send Ctrl+L to redraw a clean screen.
  • Restart — tear down and relaunch the shell in place.
  • Maximize / Restore — resize the terminal to fill the viewport; press Esc or the Restore button to return to the inline panel.

How it works

client ─ pty:open  { sessionId, cols, rows } ─► server ─ ack { ok, ptyId }
       ─ pty:input { ptyId, data }           ─►        ─ ack { ok }
       ─ pty:resize{ ptyId, cols, rows }     ─►        ─ ack { ok }
       ─ pty:close { ptyId }                 ─►        ─ ack { ok }
       ◄─ pty:data { ptyId, seq, data }
       ◄─ pty:exit { ptyId, exitCode, signal? }

Each browser connection owns only the PTYs it opened (per-connection scope), so there is zero cross-talk between terminals and a disconnect always cleans up.

Development

npm install
npm run build   # bundles src/web.src.mjs -> web.mjs (wterm + socket.io-client inlined; React external)
npm test        # vitest unit tests for the PtyManager + realtime protocol

web.mjs is a generated artifact (committed for convenience and published) — edit src/web.src.mjs and re-run npm run build.

License

MIT