@arvoretech/pi-slack-bridge
PI extension that bridges the active Pi session to a Slack thread: mirrors messages both ways, one Slack thread per Pi session
Package details
Install @arvoretech/pi-slack-bridge from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@arvoretech/pi-slack-bridge- Package
@arvoretech/pi-slack-bridge- Version
1.5.2- Published
- Jul 20, 2026
- Downloads
- 1,281/mo · 212/wk
- Author
- joao.barros.arvore
- License
- MIT
- Types
- extension
- Size
- 93.3 KB
- Dependencies
- 4 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
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) |
detecta ask_user_question/questionnaire e 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_questionouquestionnaire), a bridge posta o enunciado com as opções como botões (Block Kit). Ao clicar, a mensagem é atualizada mostrandoRespondido: *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.
- https://api.slack.com/apps → Create New App → From an app manifest
- Escolha o workspace → cole o conteúdo de
slack-app-manifest.yaml(aba YAML) → Create - Basic Information → App-Level Tokens → Generate Token and Scopes → scope
connections:write→ copie oxapp-...(este é oSLACK_BRIDGE_APP_TOKEN) - Install App → instale no workspace → em OAuth & Permissions copie o Bot User OAuth Token
xoxb-...(este é oSLACK_BRIDGE_BOT_TOKEN) - 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 é oSLACK_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 pelothread_tsda 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) |