ezolabs/ezo-watcher (Vigia EZO)

Use esta habilidade sempre que o usuário pedir para configurar, adicionar, verificar ou corrigir monitoramento, alertas, verificações de uptime ou um Watcher para este projeto — 'monitore isso', 'vigie meu app', 'me avise quando quebrar', 'por que o alerta não disparou', ou estendendo uma configuração .watcher/ existente. Ela conduz o CLI `watcher` de ponta a ponta: inicializa o projeto, escaneia pontos de telemetria (e lê o código para os silêncios que a varredura não enxerga), adiciona fontes e um canal, prova que cada verificação pode ficar vermelha com `watcher doctor --live --prove`, executa o servidor e o hospeda localmente ou no Cloudflare.

O que é ezo-watcher (Vigia EZO)?

O EZO Watcher é uma parede de alertas e pager instalado **no projeto do usuário**: configuração como código em `.watcher/`, um único processo Node local, sem conta. Sua função é realizar a instalação completa e comprovada — não uma lista de sugestões. O CLI é a fonte da verdade. Cada tópico abaixo é impresso por ele: **`watcher skills <topic>`** (tópicos: `install`, `discover`, `sources`, `channels`, `hosting`, `cloudflare`, `netdata`, `operate`, `fix`, `telemetry`), ou leia `references/<topic>.md` ao lado deste arquivo. Execute cada comando como `watcher <verbo>`, nunca a palavra isolada (`doctor` colide com o `/doctor` do agente anfitrião). A habilidade suporta os principais agentes de IA (Claude Code, Cursor, Codex) e plataformas de CLI. Ela segue um ciclo rigoroso: inicializar, escanear, escolher fontes por ranking, adicionar, executar o loop do doutor, comprovar, paginar e hospedar. O ranking prioriza a rota de readiness mais profunda do processo de produção, sondas de readiness já declaradas, heartbeats para jobs agendados, e só depois sistemas existentes como Sentry, Grafana ou Netdata. A varredura perde seis classes de silêncio — schedules gerados em tempo de instalação, cron criado em tempo de execução, workers de fila pull, stale na configuração do produto, diretório de estado gravável e endpoints de dependência em constantes de código — que devem ser lidos manualmente no código. Cada fonte deve ter uma asserção que possa realmente mudar de estado; `watcher doctor --live --prove` é o portão que garante que uma verificação pode ficar vermelha. Segredos são nomes de variáveis de ambiente na configuração e valores apenas em `.watcher/.env`. Um único canal funcional vale mais que cinco configurados — comprovado com `watcher test-alert`. Se o projeto não tem servidor e nem job agendado, adicione `watcher add host --id host`; só na ausência total de runtime usa-se `watcher doctor --no-runtime-surface`.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ezolabs/ezo-watcher/tree/HEAD/skills/ezo-watcher

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

EZO Watcher é uma parede de alertas e pager instalado no projeto do usuário: configuração como código em .watcher/, um único processo Node local, sem conta. Sua função é realizar a instalação completa e comprovada — não uma lista de sugestões.

O CLI é a fonte da verdade. Cada tópico abaixo é impresso por ele: watcher skills <topic> (tópicos: install, discover, sources, channels, hosting, cloudflare, netdata, operate, fix, telemetry), ou leia references/<topic>.md ao lado deste arquivo. Execute cada comando como watcher <verbo>, nunca a palavra isolada (doctor colide com o /doctor do agente anfitrião).

Instalar o CLI

CI=1 npm_config_yes=true npm i -g ezo-watcher
watcher --version

Sem instalação global: npx -y ezo-watcher <verbo> executa o mesmo CLI. A partir de um checkout: npm ci && npm run build && npm link. Node 24+. Detalhes completos, incluindo a instalação da última versão principal do GitHub: watcher skills install.

O ciclo

Se .watcher/ já existe, execute watcher doctor --json e watcher scan --json primeiro, depois adicione apenas o que o ranking indica como faltando; não reinicie sobre uma instalação funcional.

  1. Init. watcher init na raiz do projeto. Idempotente, nunca pergunta; escreve .watcher/config.json, .watcher/.env (0600), .watcher/data/, adiciona os dois últimos ao gitignore, escolhe uma porta livre de 7717 para cima, imprime um primeiro resumo do doctor.
  2. Scan. watcher scan --json → {signals, suggestedCommands}. Em uma pequena amostra rotulada manualmente, seu protótipo encontrou 15 de 19 pontos HTTP/TLS mas apenas 2 de 10 pontos de silêncio (watcher skills discover): trate seus comandos como candidatos, depois faça a passagem de silêncio primeiro abaixo lendo o código.
  3. Escolha pelo ranking (próxima seção). Uma fonte por ponto real; nunca invente uma fonte para parecer verde.
  4. Add. Para cada fonte escolhida: watcher add <kind> --id <id> … --found-at <file:line> --read "<o que prova>". Os --found-at/--read são proveniência e watcher doctor avisa sem eles. --dry-run pré-visualiza. Depois um canal: watcher add channel <type> --id <id> … (veja watcher skills channels). Se nenhuma credencial estiver disponível — uma máquina headless, nenhuma conta de fornecedor, um usuário que não escolheu um pager — adicione a opção sem credencial, watcher add channel file --id local: ele escreve uma linha JSON por notificação em .watcher/data/ e é um canal real e testável, não um esboço. watcher add … --replace reescreve um id existente; watcher rm <id> remove um.
  5. Loop do Doctor. watcher doctor --json; se ok:false, corrija o primeiro fail através de seu next e execute novamente. Se channel.missing avisar e o usuário quiser um telefone tocando, faça o canal do passo 8 agora e volte. Exit 0 passa, 1 falha, 64 é uso.
  6. Run. watcher run --detach (ou watcher service install para sobreviver a reboot). Depois watcher doctor --live --json para ler o servidor em execução.
  7. Prove. watcher doctor --live --prove --json até retornar {"ok": true, "live": true}. --prove move a leitura própria de cada fonte além de seu limite e falha a menos que a regra realmente mude (source.assertion-not-red; uma asserção de http-probe vazia falha source.assertion-vacuous): uma resposta http-probe é mutada, um heartbeat é avaliado após uma execução perdida mais sua graça, uma leitura de host é movida além de seus limites de disco/memória/carga, uma conexão tcp falha, um vencimento cai dentro de pageDays. Um tipo cujo alerta é o que seu remetente reporta (grafana, vmalert, sentry, netdata, feed, webhook) é um source.prove-unsupported nomeado, nunca uma falha. Se o projeto não tem servidor e nenhum job agendado, adicione watcher add host --id host — a máquina em si, lida localmente sem nada instalado — e prove. Apenas um projeto com nenhum servidor, nenhum job agendado e nenhum host para vigiar executa watcher doctor --no-runtime-surface --json → {"ok": true, "live": false, "reason": "no-runtime-surface"}, reportado claramente; uma fonte configurada sempre vence sobre --no-runtime-surface (o relatório então avisa doctor.no-runtime-surface-ignored). Não chame uma instalação não comprovada de concluída.
  8. Page. Adicione um canal e execute watcher test-alert; confirme que chegou no dispositivo que importa. Uma credencial ausente é uma omissão nomeada, nunca um passe.
  9. Host (opcional). A escada é local → serviço → Docker/VPS → Cloudflare Tunnel (padrão para "hospedar com minha chave Cloudflare") → Containers beta. watcher skills hosting, watcher skills cloudflare.
  10. Instale a habilidade para a próxima vez. watcher skills install --target all --dir . a escreve no projeto. No Claude Code execute /reload-skills depois — um diretório de habilidades de nível superior criado no meio da sessão não é detectado de outra forma.

Dia dois — ler a parede, reconhecer, comentar, silenciar, estacionar, verificar novamente — é watcher skills operate.

Quando algo quebra

Um incidente é uma alegação com evidência, não uma notificação. O ciclo, completo, é watcher skills fix:

  1. watcher status --brief para uma linha, ou watcher incidents --output json para as chaves (MCP: watch_state, depois list_incidents).
  2. get_fix_context { key } (CLI: watcher incident <key> --fix-context): o incidente, a configuração da fonte e do alvo com credenciais como nomes de variáveis de ambiente, as asserções da regra e a que falhou, onde o endpoint foi encontrado, a última boa ao lado da última má observação, o comando exato que re-executa a verificação, e next.
  3. Reproduza a partir desse comando. Um limite não é uma causa.
  4. Corrija a causa, reimplante ou reinicie para que a correção entre em vigor.
  5. verify_fix { key, by } (CLI: watcher recheck <key> --wait): ele re-verifica, aguarda a resposta fresca da fonte, e registra a confirmação quando todos os alertas estão resolvidos — ou diz qual asserção ainda falha, para que a correção possa ser reparada. Nunca marque um incidente como resolvido antes de uma re-verificação estar verde; park é para uma correção que foi mesclada e ainda não está ativa, confirm_resolution para uma que a fonte já fechou.
  6. comment o que você encontrou no caminho. Uma correção silenciosa deixa a próxima pessoa sem nada.

Ranking: o que vigiar, em ordem

  1. A rota de readiness mais profunda do processo de produção, asserindo um campo que muda quando uma dependência está indisponível. Nunca um {"ok": true} / {"status": "ok"} hardcoded — isso é liveness, e não pode ficar vermelho para a falha que importa.
  2. Uma sonda de readiness que a plataforma já declara: /readyz, /health/ready, um healthcheck do compose, um readinessProbe do Kubernetes, um caminho de saúde do fly/railway/render. Espelhe de fora com o mesmo caminho e porta.
  3. Nenhum servidor → um heartbeat por job agendado. Silêncio é o sinal.
  4. Nenhum servidor e nenhum job agendado → watcher add host --id host (carga, memória, espaço livre, opcionalmente um arquivo pid; nada instalado) e prove. Apenas nenhum servidor, nenhum job agendado e nenhum host para vigiar → watcher doctor --no-runtime-surface --json, reporte NO_RUNTIME_SURFACE, pare. Uma fonte configurada sempre vence sobre --no-runtime-surface. Nunca invente uma fonte.
  5. Depois os sistemas que já existem — Sentry, Grafana, Netdata, um remetente de entrada — vinculados a credencial. Uma credencial ausente é uma omissão nomeada com um código e um next, nunca um passe silencioso.

Silêncio primeiro (a varredura perde estes)

Leia o código para estas seis classes; cada uma se torna um watcher add heartbeat ou um watcher add webhook --stale-after:

  1. Schedules gerados em tempo de instalação — heredocs em install.sh/setup.* que escrevem um plist, unit ou crontab, launchctl load, systemctl enable, escritas crontab.
  2. launchd/systemd/cron criados em tempo de execução — templates .plist, OnCalendar=, StartInterval, KeepAlive, node-cron, schedule(, setInterval em torno de um job, celery beat. Um heartbeat por job (--every/--schedule + --grace); N jobs significam N fontes.
  3. Trabalhadores de fila pull — worker, queue, bullmq, sqs, claim, lease, dequeue. Falha é profundidade de fila ou nenhum progresso, não uma porta: pingue um heartbeat no caminho de sucesso, ou envie uma entrada checks.list com state: failing.
  4. Staleness na própria configuração do produto — staleAfterSec, presenceTtlSec, maxAge, ttl, refreshInterval, lastRunAt. Reforce a mesma janela: watcher add webhook --id <sender> --token-env <ENV> --stale-after-sec <sec>.
  5. Gravabilidade do diretório de estado — mkdir, state/, data/, sqlite, arquivos de lock. Pingue apenas após uma escrita bem-sucedida; um simples test -w não é uma fonte.
  6. Endpoints de dependência mantidos como constantes de código — process.env.X ?? "https://…", literais host:porta, bases gRPC/ClickHouse/LLM. watcher add http-probe (HTTPS GET) ou watcher add tcp-probe --host --port, com --found-at a constante.

Coloque o ping no caminho de sucesso do job — POST /ingest/heartbeat/<id>, com /fail para uma execução falha e /<exit-code> para um específico. watcher add heartbeat cunha o token em .watcher/.env (0600) quando a variável nomeada ainda não tem valor, ou escreve o --secret-value que você passar, e imprime as linhas exatas ($NIGHTLY_TOKEN abaixo é o nome que ele escolhe para --id nightly; um --token-env que você passar é a variável que ele imprime em vez disso):

set -a; . .watcher/.env
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>?token=$NIGHTLY_TOKEN"                 # após uma execução bem-sucedida
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>/fail?token=$NIGHTLY_TOKEN"            # após uma execução falha
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>/<exit-code>?token=$NIGHTLY_TOKEN"     # com o código de saída do job

Um coletor que não é um job envia sua lista completa: POST /ingest/<source> com {"checks":{"list":[{"id":"…","service":"…","state":"ok","lastRunAt":"…"}]}} — a forma completa e os estados estão em watcher skills sources.

Se uma rota de saúde retorna apenas um literal, encontre uma mais profunda ou adicione uma: GET /readyz → 200 {"db":{"ok":true}} quando a dependência responde, 503 {"db":{"ok":false}} quando não responde. Editar o projeto do usuário é permitido — você é o agente escrevendo o arquivo. Depois asserir no campo que muda, nunca em {"ok":true}.

Regras

  • Nunca aponte uma fonte para o próprio /healthz do Watcher — source.self-probe rejeita.
  • Uma fonte deve asserir algo que possa mudar. Um 200 simples é apenas liveness (source.bare-200); watcher doctor --live --prove é o portão, --found-at é um aviso (source.untraced).
  • Segredos são nomes de variáveis de ambiente na configuração e valores apenas em .watcher/.env. Nunca leia valores de .env durante a varredura, nunca cometa .watcher/.env ou .watcher/data/.
  • Um canal funcional vale mais que cinco configurados. Prove com watcher test-alert. Nenhuma credencial? watcher add channel file --id local e prove: o arquivo é um canal real, e uma credencial ausente é uma omissão nomeada, nunca um passe.
  • Reporte o que você provou — fontes adicionadas, saída de comando e toda omissão nomeada. Se o agente não puder completar um degrau (credencial ausente, nenhuma zona), diga qual e por que em uma linha.

Mais detalhe, quando um passo precisar: watcher skills discover (catálogo completo de sinais e a lista de verificação de silêncio), watcher skills sources (cada tipo, flags, exemplos), watcher skills channels, watcher skills hosting, watcher skills cloudflare, watcher skills netdata, watcher skills operate (ferramentas MCP e triagem de incidentes).

Habilidades Relacionadas