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

@zksecurity/slack-events

v0.2.4

Published

Pair a terminal with a pi-mom Slack event feed

Readme

Slack Events Client

Requires Node.js 24 or newer. Run on the machine that will consume your events:

npx @zksecurity/slack-events pair https://YOUR-EVENT-HOST

Leave the command running and open its printed link in your laptop's browser (or any browser with your Slack login). Confirm the matching terminal code and authorize Slack. The waiting command saves the feed credential on the originating machine, prints Paired with ..., and exits. No inbound port, SSH forwarding, or copying a credential back is needed.

Pairing does not start a listener. On the same machine, run:

npx @zksecurity/slack-events listen

The server filters events, including backlog, to conversations you have joined. Membership is cached for one minute, but new events from channels absent from the snapshot trigger a fresh check before filtering. Events without an identifiable joined channel are omitted.

listen retries temporary feed failures with exponential backoff from one to thirty seconds and honors longer Retry-After delays. Retries do not advance the read cursor or ACK events. Invalid or revoked feed credentials stop the listener. Other commands do not retry automatically.

listen stays running and prints one JSON object per event from your personal feed, including available backlog and new arrivals. It uses the saved credential; no URL or browser login is needed. Stop with Ctrl+C and run listen again later without repeating pairing.

Printing events does not acknowledge them. For durable consumption, save all events through a sequence cursor before acknowledging it:

npx @zksecurity/slack-events ack COMMITTED_CURSOR

Unacknowledged events replay after restarting the listener, subject to server retention. Deduplicate by eventId; never ACK merely because an event reached stdout or a pipe.

Other commands:

npx @zksecurity/slack-events list
npx @zksecurity/slack-events revoke SUBSCRIPTION_ID

Credentials are stored with mode 0600 in $XDG_CONFIG_HOME/slack-events/credentials.json or ~/.config/slack-events/credentials.json.

For existing browser-issued pairing codes, pair SERVER CODE is also supported.

Maintainers

From a pi-mom checkout with development dependencies installed:

npm pack ./packages/slack-events

The prepack step compiles only the dependency-free client source. Inspect and test the tarball before publishing it with npm publish TARBALL under an authorized npm account. Publishing is independent of the bot's npm package.

Read Slack context and download files

After deploying the matching server and reauthorizing the expanded user scopes:

slack-events users
slack-events channels
slack-events channels --limit 200 --cursor NEXT_CURSOR
slack-events user U012345
slack-events bot B012345
slack-events channel C012345
slack-events message C012345 1788884385.665039
slack-events history C012345 --limit 50 --cursor NEXT_CURSOR
slack-events thread C012345 1788881468.871969 --limit 50
slack-events file F012345
slack-events download F012345 ./attachment.pdf
slack-events listen

Use users and channels to discover IDs before making individual reads. They return Slack JSON with members or channels arrays containing IDs and names. channels includes public/private channels and direct/group conversations available to your user grant. Follow response_metadata.next_cursor with --cursor until it is empty; each call returns one page, and --limit accepts 1-200. The existing list command lists feed subscriptions, not Slack conversations.

Slack identifies a thread by its channel ID and root message timestamp, not a separate thread ID. Use history CHANNEL_ID to find a root message's ts, then run thread CHANNEL_ID ROOT_TS. If you have a reply, its thread_ts identifies the root; use message CHANNEL_ID MESSAGE_TS to inspect it when needed. Keep timestamps as strings with all decimal digits.

Read commands return Slack JSON, including pagination cursors. message returns one target message and its reactions through reactions.get; thread takes the parent timestamp. Download streams file bytes via the event server using the subscriber's user grant, refuses to overwrite existing paths, and writes mode 0600. External files without a Slack-hosted download are unsupported. A failed transfer may leave a partial output file; remove that file before retrying.

listen adds context.users / context.channels name maps while preserving the original event and cursor. The listener waits for the initial user/channel snapshot before polling events, then refreshes it in the background every six hours. Missing names use individual user / bot / channel lookups with a two-second deadline per request. Successful lookups are cached for six hours; failed lookups and directory refreshes retry after a minute. Failed refreshes retain the previous snapshot. Inaccessible names can remain unresolved; original IDs stay in the JSON. Standalone file shares also get context.files metadata, fetched separately with a two-second deadline; failure leaves the original event intact and the files list empty. Use file or download to retry retrieving the file.

Bot-only message authors and thread roots are resolved through bots.info when Slack omits the embedded name. This uses the existing users:read scope. Bot IDs map to names in context.users; slack-events bot BOT_ID returns the bot profile.

No read command changes the ACK cursor. The CLI uses its existing paired feed credential; Slack user tokens stay on the server. No bot credential is used.

The packaged slack-events skill is a manual for agents consuming these events and using the CLI.