{"_id":"@arvoretech/pi-slack-watcher","name":"@arvoretech/pi-slack-watcher","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@arvoretech/pi-slack-watcher","version":"1.0.0","description":"PI extension that lets the agent watch a Slack thread, channel or DM by polling and pushes each new message to the agent to judge and act on","main":"dist/index.js","types":"dist/index.d.ts","type":"module","scripts":{"build":"tsc","dev":"tsc --watch","lint":"tsc --noEmit"},"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.74.0 <1.0.0"},"dependencies":{"@earendil-works/pi-ai":"^0.80.3"},"devDependencies":{"@earendil-works/pi-coding-agent":"^0.80.3","@types/node":"^20.10.0","typescript":"^5.3.0"},"engines":{"node":">=18"},"pi":{"extensions":["./dist/index.js"]},"keywords":["pi-package","pi","extension","slack","watch","monitor"],"repository":{"type":"git","url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","directory":"packages/slack-watcher"},"author":{"name":"Arvore"},"license":"MIT","_id":"@arvoretech/pi-slack-watcher@1.0.0","gitHead":"b4e9b6f277d0fdaccf1c34a047d89afc8c32e93c","bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-wqRNT+5EkGuWIZ7WxPrPIJ+n45fyLYP/4YNC/hyupdsvwcZdZTf+htm5ptW89avqaFlbRQDba8of19+qYuUEvg==","shasum":"e78480b7eefb09b2d0ce88f66266a08f94290128","tarball":"https://registry.npmjs.org/@arvoretech/pi-slack-watcher/-/pi-slack-watcher-1.0.0.tgz","fileCount":14,"unpackedSize":52717,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCil1SC+8YHPnvHSkVKE5S3LUXIUOLfgEKZHoKDfTEKeAIgM2p2Z4d8uAUW9YufXOjR9amTV0iSR4GaCee+hyDxLTQ="}]},"_npmUser":{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},"directories":{},"maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-slack-watcher_1.0.0_1783447084008_0.09553021305706677"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-07T17:58:03.885Z","1.0.0":"2026-07-07T17:58:04.183Z","modified":"2026-07-07T17:58:04.552Z"},"maintainers":[{"name":"joao.barros.arvore","email":"joao.barros@arvore.com.br"},{"name":"rafsouza","email":"rafasouza@protonmail.com"},{"name":"pedro.adas","email":"pedro.adas@gmail.com"},{"name":"guilhermebs","email":"guilhermebscontact@gmail.com"},{"name":"ricardoraposorfox","email":"ricardorbxx1@gmail.com"},{"name":"jott4","email":"jvgcunha2002@gmail.com"},{"name":"vitor.piovezan","email":"vitor.piovezan@arvore.com.br"}],"description":"PI extension that lets the agent watch a Slack thread, channel or DM by polling and pushes each new message to the agent to judge and act on","homepage":"https://github.com/arvoreeducacao/arvore-pi-extensions#readme","keywords":["pi-package","pi","extension","slack","watch","monitor"],"repository":{"type":"git","url":"git+https://github.com/arvoreeducacao/arvore-pi-extensions.git","directory":"packages/slack-watcher"},"author":{"name":"Arvore"},"bugs":{"url":"https://github.com/arvoreeducacao/arvore-pi-extensions/issues"},"license":"MIT","readme":"# Slack Watcher\n\nExtensão do Pi que deixa **o modelo observar** uma thread, canal ou DM do Slack. A extensão faz polling do Slack e **empurra cada mensagem nova pro agente conforme ela chega** — igual ao `pi monitor`, mas a fonte é o Slack. O modelo então julga se aquilo requer ação.\n\n- O modelo chama `slack_watch(target)` no meio da conversa quando fizer sentido.\n- A cada mensagem nova daquele alvo, a extensão injeta a mensagem na sessão (via `sendUserMessage` em modo `steer`) com um enquadramento de observador.\n- O modelo decide: **agir** (responder/reagir usando o MCP `slack-advanced`) ou **ignorar em silêncio**.\n\nNão é um bot standalone: roda **dentro** da sua sessão Pi. Os watches são *session-scoped* — param quando a sessão fecha ou no `/reload`.\n\n## Como funciona\n\n| Passo | Mecanismo |\n|---|---|\n| Ligar | o modelo chama a tool `slack_watch({ target, ... })` |\n| Observar | `setInterval` faz poll de `conversations.history` (canal/DM) ou `conversations.replies` (thread), guardando o último `ts` e deduplicando |\n| Filtrar (opcional) | pré-filtro barato na extensão: `keywords`, `mentionsOnly`, `questionsOnly` |\n| Empurrar | mensagem nova → `sendUserMessage(..., { deliverAs: \"steer\" })` com framing \"julgue se requer ação\" |\n| Agir | o modelo usa o MCP `slack-advanced` (`send_channel_message`, `add_reaction`, …) |\n\nMensagens do próprio usuário do token e de bots são ignoradas (sem eco/loop).\n\n## Por que polling com user token (e não Socket Mode)\n\nO `slack-bridge` usa Socket Mode + bot token — um bot só vê canais onde foi convidado e **não vê suas DMs**. O watcher usa um **user token** com escopos `*:history`, então enxerga **tudo que você enxerga**: threads, canais privados e DMs, sem convidar bot nenhum. É o que casa com \"thread, canal ou DM\".\n\n## Setup\n\n### Variável de ambiente\n\n```env\nSLACK_WATCHER_TOKEN=xoxp-...\n```\n\n| Variável | Obrigatória | Descrição |\n|---|---|---|\n| `SLACK_WATCHER_TOKEN` | sim | User token `xoxp-…` (aceita `SLACK_USER_TOKEN` como fallback) |\n\nEscopos necessários no token: `channels:history`, `groups:history`, `im:history`, `mpim:history`, `channels:read`, `groups:read`, `users:read`. Sem o token a extensão fica inativa silenciosamente (as tools retornam aviso).\n\n## Tools (chamadas pelo modelo)\n\n| Tool | Descrição |\n|---|---|\n| `slack_watch({ target, id?, keywords?, mentionsOnly?, questionsOnly?, pollIntervalMs? })` | começa a observar. `target` = link de mensagem/thread, `#canal`, `@usuario` (DM) ou ID (`C…`/`D…`/`G…`) |\n| `slack_unwatch({ id? , all? })` | para um watch (ou todos) |\n| `slack_watch_list()` | lista watches ativos com uptime e contadores |\n\n## Comandos\n\n| Comando | Descrição |\n|---|---|\n| `/slack-watch` | mostra os watches ativos nesta sessão |\n\n## Exemplo de uso\n\n> **você:** fica de olho no #eng-prs e me avisa se alguém reportar um deploy quebrado\n>\n> **modelo:** *(chama `slack_watch({ target: \"#eng-prs\", keywords: [\"deploy\", \"quebr\", \"erro\", \"prod\"] })`)* Observando #eng-prs. Vou te avisar se algo relevante aparecer.\n>\n> *(mensagem nova é empurrada; o modelo julga e, se relevante, responde na thread via `slack-advanced`)*\n","readmeFilename":"README.md","_rev":"1-cd9763aeaec7459805b4d59d1fd61534"}