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

claude-needs-you

v0.1.0

Published

Pauses your music when Claude Code needs you — Spotify & Apple Music, Windows & macOS

Readme

YOUR MUSIC HAS BEEN DRAFTED

Claude Needs You (cny) is a zero-dependency CLI that wires itself into Claude Code's hooks and turns your music player into a notification channel.

Music plays while Claude works. The instant Claude stops and waits for you, the music pauses:

  • a permission prompt appears
  • Claude asks a question (AskUserQuestion)
  • Claude reaches the end of its turn and hands the keyboard back

The moment you answer, the music resumes - exactly where it left off, in whichever player was actually playing.

No API keys. No OAuth. No accounts. No dependencies. Windows talks to the system media session (SMTC), macOS talks to osascript, and both control Spotify and Apple Music all the same.

ENLIST NOW

npm i -g claude-needs-you && cny init

That's the whole enlistment. cny init installs the hooks into your user-level ~/.claude/settings.json; restart Claude Code (or start a new session) and you're on duty.

Prefer to enlist a single repo instead of the whole machine?

cny init --project     # writes .claude/settings.json in the current project

Check your papers at any time:

cny status

HOW IT WORKS

  ┌─────────────────────────────────────────────────┐
  │  Claude Code hook event                         │
  │  Notification · PreToolUse · Stop ·             │
  │  PostToolUse · UserPromptSubmit · SessionEnd    │
  └────────────────────────┬────────────────────────┘
                           ▼
  ┌─────────────────────────────────────────────────┐
  │  cny hook <intent>                              │
  │  pause  ·  resume  ·  cleanup                   │
  └────────────────────────┬────────────────────────┘
                           ▼
  ┌─────────────────────────────────────────────────┐
  │  state machine - ~/.cny/state.json              │
  │  seq counter + 400 ms debounce                  │
  │  pausedPlayers[]  (resume only what we paused)  │
  └────────────────────────┬────────────────────────┘
                           ▼
  ┌─────────────────────────────────────────────────┐
  │  SMTC (Windows)   ·   osascript (macOS)         │
  └────────────────────────┬────────────────────────┘
                           ▼
  ┌─────────────────────────────────────────────────┐
  │  Spotify   ·   Apple Music                      │
  └─────────────────────────────────────────────────┘

Eight Claude Code hooks each call cny hook <intent>. The intent is baked into the arguments, so the hook never has to guess what happened. A tiny state file at ~/.cny/state.json remembers which players CNY itself paused, and a sequence counter plus a 400 ms debounce absorbs the race between "a tool just finished" and "a permission prompt is about to appear" - so your music never blips on for a quarter second before going quiet again.

Hook wiring

Everything cny init writes into your settings:

| Event | Matcher | Command | async | timeout | |---|---|---|---|---| | Notification | permission_prompt | hook pause --reason=permission | true | 10 | | PreToolUse | AskUserQuestion | hook pause --reason=question | true | 10 | | Stop | - | hook pause --reason=idle | true | 10 | | StopFailure | - | hook pause --reason=idle | true | 10 | | UserPromptSubmit | - | hook resume --immediate (no debounce - snappy) | true | 10 | | PostToolUse | * | hook resume (400 ms debounce) | true | 10 | | PostToolUseFailure | * | hook resume (400 ms debounce) | true | 10 | | SessionEnd | - | hook cleanup | true | 10 |

Every entry CNY owns is written in exec form (an absolute node path plus an absolute script path - no shell, no PATH lookup, safe when Claude Code is launched from a GUI) and ends with a --cny sentinel argument. That sentinel is how cny init and cny uninit find their own entries and leave every foreign hook byte-for-byte untouched.

FIELD MANUAL

| Command | What it does | |---|---| | cny init [--project] | Installs the hooks. Default target is ~/.claude/settings.json; --project writes .claude/settings.json in the current directory. Idempotent - re-run it any time to refresh stale node paths (hello, nvm). Backs up the settings file before the first change. | | cny uninit [--purge] | Removes only CNY's hook entries and leaves everything else alone. --purge also deletes ~/.cny/. Alias: cny remove. | | cny status | Are the hooks installed? Do the recorded paths still exist? Plus the current state and what each player is doing right now. | | cny pause | Pause manually, no debounce. Records what it paused. | | cny resume | Resume whatever CNY paused, no debounce. | | cny --help / -h | Usage. | | cny --version / -v | Version. |

Configuration

Optional. Create ~/.cny/config.json - a missing or unreadable file simply falls back to the defaults.

| Key | Default | Meaning | |---|---|---| | players | ["spotify", "applemusic"] | Which players CNY is allowed to touch. Drop one to leave it alone entirely. | | debounceMs | 400 | How long a resume waits before acting, so an incoming pause can cancel it. | | pauseOnIdle | true | Set to false to keep playing at end of turn and only pause for permission prompts and questions. | | debug | false | Append a timestamped trace to ~/.cny/debug.log. |

{
  "players": ["spotify"],
  "debounceMs": 400,
  "pauseOnIdle": true,
  "debug": false
}

Set CNY_DEBUG=1 in the environment to turn on debug logging without editing the config file.

Platform support

| | Windows | macOS | |---|:---:|:---:| | Spotify | ✅ | ✅ | | Apple Music | ✅ | ✅ |

Windows uses the built-in system media transport controls (SMTC) via Windows PowerShell 5.1, which is present on every supported Windows install. macOS uses osascript, always guarded by an is running check.

RULES OF ENGAGEMENT

CNY holds itself to an honor code:

  • It never resumes music it didn't pause. If you hand-paused Spotify before Claude asked you something, CNY records that it paused nothing - and answering the question leaves your silence intact.
  • It never launches a player. If Spotify isn't running, nothing starts it. Not on pause, not on resume, not ever.
  • It never blocks Claude Code. Every hook is registered async: true with a 10-second timeout, and failures are swallowed. A broken CNY is a silent CNY, not a stuck session.
  • It never touches hooks it doesn't own. init and uninit only ever add or remove entries carrying the --cny sentinel, and they refuse to write at all if your settings file doesn't parse.

Known limitations

  • Multiple concurrent sessions share one state file (last writer wins). Run two Claude Code sessions at once and they compete over the same pausedPlayers list - a resume from session B can un-pause a hold that session A is still counting on. Stale sessions are pruned after 12 hours, and a crashed session's held pause is released by the next resume from anyone.
  • Approving a permission that starts a long tool run keeps the music paused until the tool finishes. The resume fires on PostToolUse, so if you approve a 90-second build, that's 90 seconds of silence. This is deliberate - resuming on PreToolUse would blip the music on right before the next permission prompt.
  • Manual-pause-then-answer quirk. If you pause your player by hand while CNY is holding a pause, the next resume will start it again - CNY can't tell your pause from its own once the player is already stopped.

Discharge papers

cny uninit           # remove the hooks, keep ~/.cny/
cny uninit --purge   # remove the hooks and delete ~/.cny/ as well
npm uninstall -g claude-needs-you

License

MIT © Shay Friedman