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

dialnow

v0.2.0

Published

Give your Claude Code a phone number. Talk to it, and it calls you back when the work's done.

Readme

dial — give your Claude Code a phone number

Talk to your Claude Code, and have it call you back when the work's done. Type as usual, or talk; Claude answers out loud in Dial's voice. After dial login, a phone call to Dial routes into your session — so you can hand off a task, hang up, and get rung back with the result. It does not modify or fork Claude Code — it runs the real claude inside a pseudo-terminal and layers voice + a bridge on top.

┌──────────────── dial (wrapper) ───────────────┐
│  your keyboard ──────────────► the real       │
│  Ctrl-T / hands-free mic ────►  `claude` (pty) │
│                                                │
│  claude reply ── Stop hook ──► daemon ── TTS ──► 🔊
│                        └── <callme> ─► Dial rings your phone 📞
│  a Dial phone call ◄──► bridge ◄──► this session
└────────────────────────────────────────────────┘
  • Voice inCtrl-T or hands-free; your speech streams to Deepgram live STT and is typed into the same session as if you'd typed it.
  • Voice out — a Stop hook sends each reply to a tiny local daemon that speaks it.
  • Bridge — after dial login, a phone call to Dial reaches this session, and Claude can ring you back when a task finishes.

Requirements

  • macOS (playback uses afplay)
  • Node ≥ 22 (the bridge uses the built-in WebSocket)
  • ffmpegbrew install ffmpeg (microphone capture)
  • DEEPGRAM_API_KEY in your environment (or a .env in the cwd)
  • claude on your PATH

Setup

cd voice-cli
npm install          # builds node-pty
npm link             # makes `dial` global
dial login           # connect your phone (opens the browser, sign in)

Use

Instead of claude, run:

dial                 # shows a quick menu: new / continue / resume / hands-free
dial --resume        # or pass claude flags straight through
dial "fix the build" # a prompt goes straight to a new session
  • Talk: press Ctrl-T, speak, Ctrl-T to send. (Talk when the prompt is empty.)
  • Hands-free: press Ctrl-G (or launch with --handsfree, or say "go hands-free" into a Ctrl-T recording). The mic stays open — just talk; a ~1.2 s pause sends your words. The mic is muted while Dial speaks, so it never hears itself. Leave with Ctrl-G or by saying "hands-free off" / "stop listening".
  • Type: just type — Claude is completely normal underneath.
  • Barge-in: pressing Ctrl-T while it's talking cuts the speech off (and in push-to-talk mode starts recording). Esc just silences it.
  • Replies are spoken short: the screen keeps Claude's full answer, but only a 1–2 sentence conversational summary is read aloud (Claude appends it in a <say>…</say> block; if it doesn't, we speak the first sentence or two).

Check your setup any time:

dial-voice doctor
dial-voice mic       # live mic test — prints what it hears as you speak

Config (env)

| Var | Default | What | |-----|---------|------| | DEEPGRAM_API_KEY | — | required | | DIAL_VOICE_MODEL | aura-2-… (from DEEPGRAM_TTS_MODEL) | the spoken voice | | DEEPGRAM_MODEL | nova-3 | STT model | | DIAL_VOICE_PORT | 8788 | local speak daemon | | DIAL_MIC | auto-detected | avfoundation audio-device index | | DIAL_MAX_SECONDS | 30 | max single push-to-talk utterance | | DIAL_PTT | 20 (Ctrl-T) | push-to-talk key byte | | DIAL_HF_KEY | 7 (Ctrl-G) | hands-free toggle key byte |

Find your mic index if 0 is wrong:

ffmpeg -f avfoundation -list_devices true -i "" 2>&1 | grep -A20 audio

Phone bridge (call your Claude from anywhere)

With the bridge configured, this session registers with the Dial server as your "local Claude." On a Dial call (iOS app / phone), say "talk to my Claude" — the server routes your words here as text, Claude answers, and the reply is spoken into the call. Audio never leaves the call; your Mac exchanges text only.

DIAL_USER_ID=<your dial user id> DIAL_BRIDGE_SECRET=<server DIAL_INTERNAL_SECRET> dial-voice

(or put both in your .env). dial-voice doctor shows the bridge status. While a phone turn is pending, the reply goes to the call instead of the local speakers.

Notes

  • First run prompts for microphone permission (macOS gives it to your terminal app).
  • dial-voice init installs the hooks globally instead (opt-in); the default never touches ~/.claude/settings.json.
  • Set DIAL_VOICE_LOG=/tmp/hook.log to debug the speak hook.