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

@render-harness/cap-slack

v0.8.2

Published

Slack Events and Web API capability pack for the Render agent harness.

Readme

@render-harness/cap-slack

Slack Events and Web API tools for agents in the Render harness.

Use this pack when an agent should receive Slack Events API webhooks, keep one conversation per Slack thread, and optionally reply or react in Slack.

Configuration

Drop the pack into render-harness.yaml:

capabilities:
  - pack: "@render-harness/cap-slack"
    config:
      signingSecretEnv: "SLACK_SIGNING_SECRET"
      botTokenEnv: "SLACK_BOT_TOKEN"
      accessMode: "read"

Set these environment variables on the entry that loads the agent:

  • SLACK_SIGNING_SECRET: Slack signing secret used to verify Events API requests.
  • SLACK_BOT_TOKEN: Slack bot token used for thread reads and optional write tools.

Connector

The pack mounts the slack connector at /connectors/slack. Configure that URL in Slack's Events API settings.

The connector accepts Slack URL verification challenges and enqueues a run for app_mention and message events. Events from bots are ignored. By default, message edit events are ignored.

Each Slack thread maps to one harness conversation, so follow-up messages in the same thread continue the same conversation.

Config Keys

| Key | Type | Default | Notes | | --- | --- | --- | --- | | agent | string | default agent | Agent name to enqueue runs for. | | userId | string | cap-slack | User ID stored on enqueued runs. | | signingSecretEnv | string | SLACK_SIGNING_SECRET | Env var that contains the Slack signing secret. | | botTokenEnv | string | SLACK_BOT_TOKEN | Env var that contains the Slack bot token. | | accessMode | read or read_write | read | Enables write tools only when set to read_write. | | allowedChannels | string[] | all channels | Restricts accepted events and tool calls to listed Slack channel IDs. | | includeEdits | boolean | false | Enqueue message_changed events when true. |

Tools

Read tools are available when SLACK_BOT_TOKEN is set:

  • slack.get_thread — read a Slack thread's messages.
  • slack.get_channel_history — read recent Slack channel messages.
  • slack.get_user_info — resolve a Slack user ID (for example U0B4357MH7H) to a display name, real name, and handle.
  • slack.get_channel_info — resolve a Slack channel ID (for example C0AQHA6M3PS) to a channel name and metadata.

slack.get_thread and slack.get_channel_history also auto-enrich their responses so agents don't have to render raw IDs:

  • Each message gains a user_display_name field with the best available label (display_namereal_namename).
  • Each message gains a text_resolved field where <@U…> mentions become @display_name and <#C…|name> mentions become #name.
  • The response gains a resolved_users map keyed by user ID and a resolved_channel object describing the requested channel.

User and channel lookups are cached for the lifetime of the agent process to keep enrichment cheap across turns.

Channel and user inputs

Every tool that takes a channel parameter (slack.send_message, slack.get_thread, slack.get_channel_history, slack.get_channel_info, slack.add_reaction, slack.update_message) accepts any of:

  • A Slack channel ID — C0AQHA6M3PS, G0…, D0…. Used verbatim.
  • A #channel-name — resolved to a channel ID via conversations.list (cached for the agent process). Requires channels:read and/or groups:read scope on the bot token. The bot must also be a member of the channel for write actions.
  • An @user-handle — resolved to a user ID via users.list (cached) and opened as a DM channel via conversations.open. Requires users:read scope plus im:write (and chat:write for sending).
  • A Slack mention literal — <#C0AQHA6M3PS|name> or <@U0B4357MH7H>. The wrapping is stripped and the inner ID is used.

slack.get_user_info accepts a user ID (U0B4357MH7H), an @handle, or a bare handle (ada.lovelace); the latter two require users:read.

allowedChannels is enforced after resolution, against the canonical channel ID. So allowedChannels: ["C0AQ…"] correctly accepts slack.send_message({ channel: "#that-channels-name" }) because the resolver returns C0AQ… before the gate check fires.

If the bot lacks the lookup scope, the tool returns an actionable error naming the scope (e.g. Slack missing_scope: 'channels:read' needed (bot currently has: 'chat:write'). Add 'channels:read' to the bot's OAuth scopes in the Slack app config (api.slack.com → OAuth & Permissions → Bot Token Scopes), reinstall the app to the workspace, and redeploy.) instead of failing silently. Agents that only ever address channels by ID don't need the read scopes; the resolver fast-paths C… / G… / D… / U… inputs without any API call.

Scope coverage for name lookups

The resolver lists public and private channels in separate conversations.list calls and aggregates results from whichever succeeds. A bot with only channels:read gets a working name → id index for public channels; the private-channel call fails (caught, ignored). A bot with both scopes indexes both. A bot with neither sees the actionable missing_scope error above with the first missing scope named.

Other common Slack errors are also rewritten with hints: not_in_channel → "invite the bot with /invite @<bot>", channel_not_found → "ID invalid, archived, or not visible to the bot", invalid_auth / token_revoked → "reissue SLACK_BOT_TOKEN". Any other Slack platform code passes through verbatim with the slack.<code> annotation appended so the agent can branch on it.

Set accessMode: read_write to enable write tools:

  • slack.send_message
  • slack.add_reaction
  • slack.update_message

Use permissions.requireApproval for write tools if the agent should ask before posting or changing Slack messages.

Request timeouts and retries

The underlying @slack/web-api WebClient defaults to no per-request timeout and retries up to ten times over roughly 30 minutes, which lets a single rate-limited or transient-failure response hang a tool call indefinitely from the agent's perspective. This pack overrides those defaults with a 15-second per-request timeout and a bounded retry policy (3 retries, 0.5s → 3s backoff), so a failing call surfaces as a clear tool error within ~70 seconds worst case instead of appearing stuck. Agents using slack.send_message against high-traffic channels should still expect the occasional rate-limit error and either back off or use permissions.requireApproval to throttle posts.

Test Commands

pnpm --filter @render-harness/cap-slack build
pnpm --filter @render-harness/cap-slack test