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

beckoned

v0.1.1

Published

One system notification when any of your AI coding sessions needs your attention — across every project you have open.

Readme

beckoned

One system notification when any of your AI coding sessions needs you, across every project and terminal tab you have open.

The problem

Run more than one Claude Code session at once (different projects, different terminal tabs, different editor windows) and you lose track of which one is sitting idle waiting on a permission prompt, a question, or just finished. Each session can notify you on its own, but there's no single place that says "hey, this one, in that project, needs you."

How it works

Claude Code already fires a Notification hook with the session's working directory and what kind of attention it needs (a permission prompt, an idle prompt, waiting on input, or a finished task). beckoned is:

  1. A tiny hook script (beckoned-hook). Claude Code runs this on every Notification event, for every session, system-wide. It reads the event off stdin and forwards a one-line JSON message to...
  2. A background daemon (beckoned-daemon). It runs continuously via launchd, listens on a local Unix socket, and turns each incoming event into a native macOS notification tagged with the project name and the editor/terminal it's running in, along with what it needs from you. Repeated events from the same session within a few seconds get folded into one notification instead of a flood. Clicking the notification reuses the exact window it came from, via the editor's own CLI (<cli> -r <path>) when it's a VS Code fork (Antigravity, VS Code, Cursor, Windsurf, ...), or just brings the app forward generically otherwise. No Accessibility permission needed either way.

No menu bar app, no telemetry. Everything stays local by default. The one optional exception is mobile push (below), which is an explicit opt-in.

What it looks like

Real notifications, captured live, not mockups. Same banner shape every time, just the message changes with what the session actually needs:

Click any of them and the exact window it came from comes forward, not a new one.

Install (macOS)

npm install -g beckoned
beckoned-setup

npm install compiles the native notifier (needs Xcode Command Line Tools, xcode-select --install, for the one-time Swift build; it's skipped automatically if they're missing, with a note on how to finish it later). beckoned-setup is the separate, explicit step that copies the built runtime into ~/.beckoned/opt, installs beckoned-daemon as a launchd user agent (starts on login, restarts if it crashes), generates a mobile-push topic (below), and prints the exact hook configuration to add to ~/.claude/settings.json. Registering the hook in your global settings, not a per-project one, is what makes every session on the machine report in, no matter which directory it's running from. Re-run beckoned-setup any time, after an upgrade or after switching Node versions, to refresh it; see scripts/setup.sh for why that copy step exists.

Once that's done, confirm it's actually working before wiring up a real tool:

beckoned-test

This sends one real notification through the same daemon and notifier every adapter uses. You should see it appear within a few seconds, and clicking it should bring this terminal window forward. If nothing shows up, it prints why (usually the daemon isn't running yet, try beckoned-setup again).

From source

git clone <this repo>
cd beckoned
./scripts/setup.sh

This is the same script beckoned-setup runs. It builds the project itself first if dist/ isn't already there (gitignored on a fresh clone), the way npm install -g provides prebuilt.

Notifications come from a small native .app bundle (native/BeckonedNotifier) built specifically to give beckoned its own sender identity. See docs/known-issues/notification-sender-identity.md for why osascript/terminal-notifier weren't enough.

Mobile push (optional)

beckoned-setup generates a random ntfy topic and stores it in ~/.beckoned/config.json. Install the ntfy app (iOS/Android), subscribe to that topic, and every notification also reaches your phone, even with the app closed, since it's a real push and doesn't need ntfy open in the foreground. The topic is your only "auth" on the public ntfy.sh server, so treat it like a shared secret. Point ntfyServer in that config file at a self-hosted instance for full privacy.

Click-to-focus

No permissions needed. On first launch, macOS asks for notification permission ("beckoned Would Like to Send You Notifications"). Allow it, or notifications won't appear at all.

Antigravity, Gemini CLI, and Eigent

Everything above gets Claude Code working, and it also covers any Claude Code session running inside Antigravity's, VS Code's, Cursor's, or Windsurf's built-in terminal, since that's the same click-to-focus path, not a separate tool. The three tools below are different: they're their own AI agents, not something running inside a terminal, so each needs one more step. All three are optional, skip whichever ones you don't use.

Antigravity's own agent panel

This means the built-in agent you talk to in Antigravity's own panel, not a terminal session inside it.

Antigravity only lets you turn hooks on one project at a time. There's no single setting that covers every project the way Claude Code's does, we checked two different places that looked like they should work and neither did. So for every project where you want Antigravity's agent to notify you, open a terminal in that project and run:

beckoned-antigravity-init

This writes a .agents/hooks.json file in that project. It's safe to run again later, for example after upgrading beckoned, since it only replaces its own entry and leaves anything else in that file alone.

One thing to do afterward: add .agents/ to that project's .gitignore. The file has your machine's own file paths written into it, so it should stay local and never get committed.

Gemini CLI

This one is simpler. Run it once for your whole machine, not per project:

beckoned-gemini-init

This adds beckoned's hooks to ~/.gemini/settings.json, which Gemini CLI reads no matter which project you're in.

There's a catch worth knowing about though: Gemini CLI won't run hooks, from beckoned or anyone else, in a project it hasn't been told to trust. If a project's sessions never send a notification, open a session there and check whether it's trusted, either through the trust prompt Gemini CLI shows the first time you open a new folder, or by running /permissions inside a session.

Eigent

Eigent has no built-in way to tell another program when it needs you, so this only works if you're running a patched build of Eigent with beckoned's notify hook added to it. If that's not something you've set up, this section doesn't apply to you.

If you are running that patched build, set this before starting Eigent's backend, swapping in your own home directory:

export EIGENT_NOTIFY_COMMAND="node /Users/you/.beckoned/opt/dist/bin/beckoned-eigent-hook.js"

beckoned-setup prints this same line with your actual paths already filled in, so it's easier to just copy that instead of typing it out by hand. Once it's set, Eigent will call beckoned whenever it asks you a question or finishes a task.

Support matrix

Early days: one tool fully built, a few more scoped out. The daemon and socket protocol are already tool-agnostic (see EXTENDING.md), so what's missing per tool below is just its adapter. ✅ means built and verified live, 📋 means the hook/signal is confirmed to exist (from real docs or source, not guessed) but no adapter is built yet, 🚫 means it's been checked and there's genuinely nothing to hook into today, and ❓ means it hasn't been looked into yet. See EXTENDING.md for the detail and sources behind each row.

AI coding agents / apps

| Tool | Supported | Notes | |---|:---:|---| | Claude Code | ✅ | The reference adapter, src/hook.ts. | | Codex CLI | 📋 | notify in config.toml; payload is an argv arg, not stdin. | | Gemini CLI | ✅ | Global, run beckoned-gemini-init once per machine. Gated by Gemini CLI's own per-project folder-trust dialog. | | Antigravity (agent panel) | ✅ | Project-local only, no global path found (two tried, see EXTENDING.md). Run beckoned-antigravity-init once per project you want covered. | | Antigravity / VS Code / Cursor / Windsurf (as your terminal's editor) | ✅ | Not a separate adapter. This is the click-to-reuse-window path (ancestorApp.ts), and it works for Claude Code (or any adapted tool) running in any of these. | | Eigent AI | ✅ | Required patching Eigent's own source (it had no hook system at all), see EXTENDING.md. | | Claude Desktop | ❓ | Searched specifically; genuinely inconclusive, needs a real install to test. | | Kimi CLI | ❓ | | | Cursor (agent, not just terminal) | ❓ | | | Windsurf / Cascade (agent, not just terminal) | ❓ | | | Cline | ❓ | | | Aider | ❓ | | | GitHub Copilot (agent mode) | ❓ | |

Operating systems

| OS | Supported | Notes | |---|:---:|---| | macOS | ✅ | Native .app via UNUserNotificationCenter, launchd-managed. | | Linux | ⬜ Planned | notify-send/D-Bus port scoped in publish.md. Click-to-reuse-window won't work under Wayland, though; that's a compositor-level restriction, not a bug to fix. | | Windows | ⬜ Planned | Toast notifications need an AppUserModelID, scoped in publish.md. |

Want a tool or platform bumped up this list? Open an issue, or see EXTENDING.md for how to verify a signal exists and build the adapter yourself.

License

MIT