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

@arvoretech/pi-slack-bridge

v1.5.1

Published

PI extension that bridges the active Pi session to a Slack thread: mirrors messages both ways, one Slack thread per Pi session

Readme

Slack Bridge

Extensão do Pi que conecta a sua sessão Pi do terminal a uma thread no Slack, espelhando mensagens nos dois sentidos. Cada sessão Pi vira uma thread no Slack.

  • O que você digita no terminal aparece na thread.
  • A resposta do agente aparece na thread.
  • O que você responder na thread é injetado de volta na sessão Pi (via sendUserMessage).

A extensão roda dentro da sua sessão Pi (o terminal é o host). Não é um bot standalone.

Como funciona

| Sentido | Gatilho | Ação | |---|---|---| | Pi → Slack | input (terminal) | posta a mensagem do usuário na thread (convertida para mrkdwn do Slack) | | Pi → Slack | turn_start | atualiza o status nativo da thread (assistant.threads.setStatus) | | Pi → Slack | tool_execution_start | posta cada chamada de tool como uma linha na thread (ex: :computer: \bash` pnpm test) e atualiza o status | | Pi → Slack | tool_execution_start(tool de pergunta) | detectaask_user_question/questionnairee posta o enunciado com as opções numeradas na thread | | Pi → Slack |turn_end| posta a resposta final na thread (convertida para mrkdwn) e limpa o status | | Slack → Pi | mensagem na thread vinculada |pi.sendUserMessage()` (steer se ocupado, normal se ocioso). Se havia pergunta pendente, o número escolhido é resolvido para o rótulo da opção |

Quem inicia a thread

A vinculação sessão ↔ thread funciona nos dois sentidos:

  • Sessão inicia: você digita no terminal → a extensão cria a thread no Slack (mensagem raiz no canal) e passa a espelhar nela.
  • Slack inicia: você abre uma conversa nova com o app no Slack e manda uma mensagem → a sessão Pi aberta (que ainda não tem thread vinculada) adota essa thread e injeta a mensagem.

O que vier primeiro define a thread. A partir daí o vínculo é fixo: só mensagens daquela thread chegam na sessão, e as respostas vão só para ela. O thread_ts é persistido via appendEntry, então sobrevive a /reload.

Status nativo (animação)

Durante um turno a extensão usa o status nativo de Assistant do Slack (assistant.threads.setStatus) — a animação "is typing…" com o passo atual (ex: bash: pnpm test). Ao postar a resposta final, o status é limpo. Requer um app com scope assistant:write.

Markdown

Toda mensagem do agente e do terminal passa por slackify-markdown antes de ser postada, convertendo Markdown/GFM (headings, **negrito**, listas, links [texto](url), blocos de código) para o mrkdwn do Slack (*negrito*, <url|texto>, ). As mensagens não usam emoji decorativo.

Tool calls e perguntas

  • Cada chamada de tool vira uma linha na thread com o nome da tool e um resumo do argumento principal (ex: `bash` pnpm test). Quando a tool termina, essa mesma mensagem é editada com o resultado (> ok: … ou > erro: …), então você acompanha início e fim de cada passo sem poluir a thread.
  • Quando o agente chama uma tool de pergunta (ask_user_question ou questionnaire), a bridge posta o enunciado com as opções como botões (Block Kit). Ao clicar, a mensagem é atualizada mostrando Respondido: *opção* e a escolha volta pro agente automaticamente. Também é possível responder por texto na thread (útil para múltipla escolha ou resposta livre). Perguntas com vários itens só voltam pro agente quando todas forem respondidas.
  • Os botões exigem Interactivity habilitado no app do Slack (o manifest já inclui). Como a bridge roda em Socket Mode, não é preciso configurar Request URL.

Setup

1. Slack App (Socket Mode + Assistant)

A forma mais rápida é usar o manifest pronto: slack-app-manifest.yaml.

  1. https://api.slack.com/apps → Create New AppFrom an app manifest
  2. Escolha o workspace → cole o conteúdo de slack-app-manifest.yaml (aba YAML) → Create
  3. Basic InformationApp-Level TokensGenerate Token and Scopes → scope connections:write → copie o xapp-... (este é o SLACK_BRIDGE_APP_TOKEN)
  4. Install App → instale no workspace → em OAuth & Permissions copie o Bot User OAuth Token xoxb-... (este é o SLACK_BRIDGE_BOT_TOKEN)
  5. Abra uma conversa (DM) com o app no Slack. Pegue o ID do canal (D...) — abra a DM, clique no nome do app no topo → o ID aparece no rodapé do painel de detalhes. Esse é o SLACK_BRIDGE_CHANNEL. Para usar um canal em vez de DM, convide o bot (/invite @Pi Bridge) e use o ID do canal (C...).

O manifest já habilita: Socket Mode, o modo Assistant (necessário para receber mensagens da DM via message.im + assistant_thread_started) e os scopes chat:write, assistant:write, im:*, channels:history, groups:history.

Nota: num app Assistant, toda mensagem do usuário na DM chega já com thread_ts (a thread do assistant). Não há "mensagem de topo" sem thread — a extensão adota a thread pelo thread_ts da primeira mensagem.

2. Variáveis de ambiente

SLACK_BRIDGE_BOT_TOKEN=xoxb-...
SLACK_BRIDGE_APP_TOKEN=xapp-...
SLACK_BRIDGE_CHANNEL=C0123456789
SLACK_BRIDGE_USER_IDS=U0123456789

| Variável | Obrigatória | Descrição | |---|---|---| | SLACK_BRIDGE_BOT_TOKEN | sim | Bot token xoxb-... (aceita SLACK_BOT_TOKEN como fallback) | | SLACK_BRIDGE_APP_TOKEN | sim | App-level token xapp-... (aceita SLACK_APP_TOKEN como fallback) | | SLACK_BRIDGE_CHANNEL | sim | ID do canal/DM onde as threads serão criadas (DM começa com D) | | SLACK_BRIDGE_USER_IDS | não | Allowlist de user IDs que podem mandar do Slack (vazio = qualquer um). Ignorada em DMs. |

Sem as 3 obrigatórias a extensão fica inativa silenciosamente.

Uso

Abra uma sessão Pi normalmente. A bridge conecta no session_start. A thread é criada quando a sessão fala primeiro (você digita no terminal) ou quando você inicia a conversa pelo Slack — o que vier primeiro. Rode /slack-bridge para ver o status.

Comandos

| Comando | Descrição | |---|---| | /slack-bridge | Mostra o status da ponte (ativa / inativa / variáveis faltando) |