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-mic

v0.4.0

Published

Voice input for pi (CLI and pi-web), transcribed through an OpenAI-compatible gateway (e.g. OmniRoute to Deepgram)

Readme

pi-mic

Voice input for pi, in the terminal (CLI) and in pi-web. You speak, the audio goes to an OpenAI-compatible /v1/audio/transcriptions endpoint (for example OmniRoute with Deepgram) and the text lands in the message field without being sent.

Installation

pi install npm:pi-mic

Then, once, inside pi:

/mic setup     # picks the provider (key and baseUrl come from models.json/auth.json) and the model
/mic check     # confirms provider, key and endpoint with a silent audio clip

The configuration lives in ~/.pi/agent/pi-mic.json:

{ "provider": "omni-memory", "model": "deepgram/nova-3", "language": "pt", "device": "Microphone (HD Pro Webcam C920)" }

language and device are optional: without language the gateway detects the language; without device the system default microphone is used.

CLI

| Action | How | |---|---| | Start / stop recording | Alt+M or /mic | | Pick the microphone (Windows) | /mic device | | Configure provider/model/language | /mic setup | | Test the endpoint | /mic check |

The transcription shows up in the editor while you speak, in one of two ways:

  • Real time (Deepgram): with "realtime": { "provider": "deepgram", "apiKey": "…" } in pi-mic.json (or DEEPGRAM_API_KEY), the audio goes through Deepgram streaming and the words arrive as you speak. /mic setup configures it.
  • Segment by segment (any provider): without realtime, pi-mic splits speech on pauses and sends each segment to the provider's /audio/transcriptions, with a partial preview.

In both modes only audio with voice (loud and with pitch) goes through: keyboard, clicks and knocks do not become words. The audio keeps the microphone's native rate (48 kHz in the browser), without resampling.

In real time, when you stop, pi-mic records 500 ms more (the last syllable often comes out together with the key press), sends Finalize and waits for the final streaming results, then sends the whole recording to Deepgram's pre-recorded endpoint, which sees the full sentence; that text replaces the streaming one.

Extra options in pi-mic.json: "keyterms": ["pi-mic", "OmniRoute"] (terms Deepgram should prioritize) and "debug": true (the pi-web host saves the audio and the events of each session in ~/.pi/agent/pi-mic-debug). While recording, the editor is locked (only Alt+M to stop and Esc to cancel and restore the previous text) and the footer shows 🔴 with the microphone level.

Capture: Windows uses the native waveIn API (nothing to install); macOS/Linux use rec (SoX) or arecord. For tests, PI_MIC_FAKE_INPUT=<file.wav> (16 kHz mono) replaces the microphone.

Set language (for example "pt-BR"): short segments hurt automatic language detection.

pi-web

pi-mic runs inside pi-web itself. Install it with pi install npm:pi-mic; when a session opens in pi-web, the extension attaches to pi-web's own HTTP server, injects the microphone button into the page and transcribes the audio on the server, so the provider key never reaches the browser. No extra process or port is needed. Reload the page once after pi-web starts to get the button (pi-web shows a notice when it is ready).

The microphone button sits on the message field row, right before Send; click it or press Alt+M to record and again to stop, Esc cancels. As in the CLI, the text appears live and the field (and Send) stay locked until the transcription finishes. In pi-web /mic setup and /mic check are available; recording happens in the browser, never on the server machine.

The browser only grants the microphone in a secure context: localhost/127.0.0.1 or HTTPS. To use it from another device, put pi-web behind HTTPS inside your private network (for example tailscale serve --bg <pi-web port>). Do not expose pi-web publicly: it may have no password.

Architecture

All code is TypeScript under src/, split by layer:

| Folder | Responsibility | |---|---| | src/core | Browser-safe audio, text and transcription logic (no Node APIs) | | src/config | Reading and writing pi-mic.json | | src/providers | OpenAI-compatible gateway and Deepgram clients | | src/cli | The pi extension: capture, dictation state machine, /mic commands | | src/web/host | Attaches the mic routes and button injection to pi-web's HTTP server | | src/web/server | Mic routes: transcription, realtime stream, config, browser assets | | src/web/client | The browser script injected into pi-web |

pi loads the extension directly from src/cli/extension.ts. Only the web side is compiled (npm run build writes dist/); the extension serves dist/core and dist/web/client to the browser under /__pi-mic/assets/.

Development

Git-flow with PRs, everything in Conventional Commits (commits and PR titles; CI rejects what does not follow them, and PRs from branches outside the flow):

  1. feature/<name> (or bugfix/<name>) → PR to dev, titled like feat: … / fix: ….
  2. On every push to dev, the pipeline computes the next version from the commits since the last tag (feat → minor, fix/perf/refactor → patch, !/BREAKING CHANGE → major; before 1.0 a breaking change bumps the minor) and opens or updates the release/<version> → main PR on its own, titled chore(release): <version>. Nobody picks the version.
  3. Merging into main publishes to npm with trusted publishing, creates the tag and the GitHub release, merges main back into dev and deletes the release branch.

hotfix/<name> branches from main and goes back to main.

npm install
npm run check   # biome + no-comments + tsc + build + tests

The code base has no comments by rule: names, small functions and types carry the explanation, and npm run check fails if a comment sneaks in.