ezolabs/ezo-watcher

Utilisez cette compétence lorsque l'utilisateur demande de configurer, ajouter, vérifier ou réparer la surveillance, les alertes, les vérifications de disponibilité ou un Watcher pour ce projet — 'surveiller ceci', 'surveiller mon application', 'm'avertir quand ça casse', 'pourquoi l'alerte ne s'est pas déclenchée', ou pour étendre une configuration .watcher existante. Elle pilote l'interface en ligne de commande `watcher` de bout en bout : initialiser le projet, le scanner pour les points de télémétrie (et lire le code pour les silences qu'un scan ne peut pas voir), ajouter des sources et un canal, prouver que chaque vérification peut passer au rouge avec `watcher doctor --live --prove`, exécuter le serveur, et l'héberger localement ou sur Cloudflare.

Qu'est-ce que ezo-watcher ?

EZO Watcher installe un mur d'alertes et un système de radiomessagerie directement dans le projet de l'utilisateur : configuration en tant que code dans le dossier .watcher/, un seul processus Node local, aucun compte nécessaire. Cette compétence guide l'agent IA à travers le cycle complet d'installation, de vérification et de dépannage en utilisant l'interface CLI `watcher`. Elle commence par initialiser le projet, le scanner pour détecter automatiquement les points de télémétrie (HTTP/S, bases de données, TLS) et lit le code source pour les points de silence que le scan automatique ne peut pas détecter (comme les tâches cron, les files d'attente, l'actualisation des données). L'agent ajoute des sources de surveillance (une par point réel) et au moins un canal de notification (fichier local ou externe comme e-mail/SMS), puis prouve que chaque vérification peut réellement échouer via la commande `watcher doctor --live --prove`. Enfin, il exécute le serveur localement ou l'héberge via Cloudflare Tunnel. Un classement clair guide l'agent pour surveiller en priorité la sonde de préparation la plus profonde d'un service de production, suivie des points de silence. La compétence gère également les incidents : reproduction, correction et vérification que la correction résout l'alerte.

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

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

EZO Watcher est un mur d'alertes et un système de radiomessagerie installé dans le projet de l'utilisateur : configuration en tant que code dans .watcher/, un seul processus Node local, aucun compte. Votre travail consiste en l'installation complète et éprouvée — pas une liste de suggestions.

L'interface CLI est la source de vérité. Chaque sujet ci-dessous s'imprime depuis celle-ci : watcher skills <topic> (sujets : install, discover, sources, channels, hosting, cloudflare, netdata, operate, fix, telemetry), ou lisez references/<topic>.md à côté de ce fichier. Exécutez chaque commande en tant que watcher <verbe>, jamais le mot nu (doctor entre en conflit avec le /doctor de l'agent hôte).

Installer l'interface CLI

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

Pas d'installation globale : npx -y ezo-watcher <verbe> exécute la même CLI. Depuis un dépôt cloné : npm ci && npm run build && npm link. Node 24+. Détail complet, y compris l'installation depuis la dernière version de GitHub : watcher skills install.

La boucle

Si .watcher/ existe déjà, exécutez d'abord watcher doctor --json et watcher scan --json, puis ajoutez uniquement ce que le classement indique comme manquant ; ne réinitialisez pas une installation fonctionnelle.

  1. Initialisation. watcher init à la racine du projet. Idempotent, jamais de questions ; écrit .watcher/config.json, .watcher/.env (0600), .watcher/data/, ignore git des deux derniers, choisit un port libre à partir de 7717, imprime un premier résumé du docteur.
  2. Analyse. watcher scan --json → {signals, suggestedCommands}. Sur un petit échantillon étiqueté manuellement, son prototype a trouvé 15 des 19 points HTTP/TLS mais seulement 2 des 10 points de silence (watcher skills discover) : traitez ses commandes comme des candidats, puis effectuez le passage prioritaire sur le silence ci-dessous en lisant le code.
  3. Choisissez selon le classement (section suivante). Une source par point réel ; n'inventez jamais de source pour paraître vert.
  4. Ajout. Pour chaque source choisie : watcher add <type> --id <id> … --found-at <fichier:ligne> --read "<ce qu'elle prouve>". Les options --found-at/--read sont la provenance et watcher doctor émet un avertissement sans elles. --dry-run prévisualise. Ensuite, un canal : watcher add channel <type> --id <id> … (voir watcher skills channels). Si aucune information d'identification n'est disponible — une machine sans tête, aucun compte fournisseur, un utilisateur qui n'a pas choisi de système de radiomessagerie — ajoutez la solution de repli sans information d'identification, watcher add channel file --id local : il écrit une ligne JSON par notification sous .watcher/data/ et est un canal réel et testable, pas un simple substitut. watcher add … --replace réécrit un id existant ; watcher rm <id> en supprime un.
  5. Boucle du docteur. watcher doctor --json ; si ok:false, corrigez le premier fail via son next et réexécutez. Si channel.missing prévient et que l'utilisateur souhaite qu'un téléphone sonne, effectuez le canal de l'étape 8 maintenant et revenez. La sortie 0 est un succès, 1 un échec, 64 une erreur d'utilisation.
  6. Exécution. watcher run --detach (ou watcher service install pour qu'il survive au redémarrage). Ensuite, watcher doctor --live --json pour lire le serveur en cours d'exécution.
  7. Preuve. watcher doctor --live --prove --json jusqu'à ce qu'il retourne {"ok": true, "live": true}. --prove déplace la lecture de chaque source au-delà de son seuil et échoue sauf si la règle bascule effectivement (source.assertion-not-red ; une assertion d'analyse http vide échoue avec source.assertion-vacuous) : la réponse d'une analyse http est modifiée, un battement de cœur est évalué après une exécution manquée plus son délai de grâce, une lecture d'hôte est déplacée au-delà de ses seuils de disque/mémoire/charge, une connexion TCP échoue, une expiration tombe dans pageDays. Un type dont l'alerte est ce que son expéditeur rapporte (grafana, vmalert, sentry, netdata, feed, webhook) est un saut nommé source.prove-unsupported, jamais un échec. Si le projet n'a pas de serveur et pas de tâche planifiée, ajoutez watcher add host --id host — la machine elle-même, lue localement sans rien installer — et prouvez-la. Seul un projet sans serveur, sans tâche planifiée et sans hôte à surveiller exécute watcher doctor --no-runtime-surface --json → {"ok": true, "live": false, "reason": "no-runtime-surface"}, rapporté simplement ; une source configurée l'emporte toujours sur --no-runtime-surface (le rapport prévient alors doctor.no-runtime-surface-ignored). N'appelez pas une installation non éprouvée comme terminée.
  8. Page. Ajoutez un canal et exécutez watcher test-alert ; confirmez qu'il est arrivé sur l'appareil qui compte. Une information d'identification manquante est un saut nommé, jamais un succès.
  9. Hébergement (optionnel). L'échelle est local → service → Docker/VPS → Cloudflare Tunnel (par défaut pour "héberger avec ma clé Cloudflare") → Conteneurs bêta. watcher skills hosting, watcher skills cloudflare.
  10. Installer la compétence pour la prochaine fois. watcher skills install --target all --dir . l'écrit dans le projet. Dans Claude Code, exécutez /reload-skills ensuite — un répertoire de compétences de niveau supérieur créé en milieu de session n'est pas détecté autrement.

Quand quelque chose casse

Un incident est une affirmation avec des preuves, pas une notification. La boucle, en entier, est watcher skills fix :

  1. watcher status --brief pour une ligne, ou watcher incidents --output json pour les clés (MCP : watch_state, puis list_incidents).
  2. get_fix_context { clé } (CLI : watcher incident <clé> --fix-context) : l'incident, la configuration de la source et de la cible avec les informations d'identification en tant que noms de variables d'environnement, les assertions de la règle et celle qui a échoué, où le point de terminaison a été trouvé, la dernière bonne observation à côté de la dernière mauvaise observation, la commande exacte qui réexécute la vérification, et next.
  3. Reproduisez-le à partir de cette commande. Un seuil n'est pas une cause.
  4. Corrigez la cause, redéployez ou redémarrez pour que la correction soit en ligne.
  5. verify_fix { clé, by } (CLI : watcher recheck <clé> --wait) : il revérifie, attend la réponse fraîche de la source, et enregistre la confirmation lorsque chaque alerte est résolue — ou indique quelle assertion échoue encore, afin que la correction puisse être réparée. Ne marquez jamais un incident comme résolu avant qu'une nouvelle vérification soit verte ; park est pour une correction qui est fusionnée mais pas encore en ligne, confirm_resolution pour une que la source a déjà fermée.
  6. comment ce que vous avez trouvé en cours de route. Une correction silencieuse ne laisse rien à la personne suivante.

Classement : quoi surveiller, dans l'ordre

  1. La route de préparation la plus profonde du processus de production, affirmant un champ qui change lorsqu'une dépendance est en panne. Jamais un {"ok": true} / {"status": "ok"} codé en dur — c'est de la vivacité, et cela ne peut pas passer au rouge pour la défaillance qui compte.
  2. Une sonde de préparation que la plateforme déclare déjà : /readyz, /health/ready, une healthcheck de compose, un readinessProbe Kubernetes, un chemin de santé fly/railway/render. Miroir de l'extérieur avec le même chemin et le même port.
  3. Pas de serveur → un battement de cœur par tâche planifiée. Le silence est le signal.
  4. Pas de serveur et pas de tâche planifiée → watcher add host --id host (charge, mémoire, espace libre, éventuellement un fichier pid ; rien installé) et prouvez-le. Seulement pas de serveur, pas de tâche planifiée et pas d'hôte à surveiller → watcher doctor --no-runtime-surface --json, rapportez NO_RUNTIME_SURFACE, arrêtez. Une source configurée l'emporte toujours sur --no-runtime-surface. N'inventez jamais de source.
  5. Ensuite, les systèmes qui existent déjà — Sentry, Grafana, Netdata, un expéditeur entrant — liés à des informations d'identification. Une information d'identification manquante est un saut nommé avec un code et un next, jamais un succès silencieux.

Silence en premier (l'analyse les manque)

Lisez le code pour ces six classes ; chacune devient un watcher add heartbeat ou un watcher add webhook --stale-after :

  1. Plannings générés à l'installation — heredocs dans install.sh/setup.* qui écrivent un plist, une unité ou une crontab, launchctl load, systemctl enable, écritures crontab.
  2. launchd/systemd/cron créés à l'exécution — modèles .plist, OnCalendar=, StartInterval, KeepAlive, node-cron, schedule(, setInterval autour d'une tâche, celery beat. Un battement de cœur par tâche (--every/--schedule + --grace) ; N tâches signifie N sources.
  3. Travailleurs de files d'attente de type pull — worker, queue, bullmq, sqs, claim, lease, dequeue. L'échec est la profondeur de la file d'attente ou l'absence de progression, pas un port : envoyez un battement de cœur sur le chemin de réussite, ou poussez une entrée checks.list avec state: failing.
  4. Obsolescence dans la propre configuration du produit — staleAfterSec, presenceTtlSec, maxAge, ttl, refreshInterval, lastRunAt. Appliquez la même fenêtre : watcher add webhook --id <expéditeur> --token-env <ENV> --stale-after-sec <sec>.
  5. Accessibilité en écriture du répertoire d'état — mkdir, state/, data/, sqlite, fichiers de verrouillage. Envoyez seulement après une écriture réussie ; un simple test -w n'est pas une source.
  6. Points de terminaison de dépendance stockés comme constantes de code — process.env.X ?? "https://…", littéraux host:port, bases gRPC/ClickHouse/LLM. watcher add http-probe (GET HTTPS) ou watcher add tcp-probe --host --port, avec --found-at la constante.

Placez le ping sur le chemin de réussite de la tâche — POST /ingest/heartbeat/<id>, avec /fail pour une exécution échouée et /<exit-code> pour un code spécifique. watcher add heartbeat génère le jeton dans .watcher/.env (0600) lorsque la variable nommée n'a pas encore de valeur, ou écrit le --secret-value que vous passez, et imprime les lignes exactes ($NIGHTLY_TOKEN ci-dessous est le nom qu'il choisit pour --id nightly ; un --token-env que vous passez est la variable qu'il imprime à la place) :

set -a; . .watcher/.env
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>?token=$NIGHTLY_TOKEN"                 # après une exécution réussie
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>/fail?token=$NIGHTLY_TOKEN"            # après une exécution échouée
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>/<exit-code>?token=$NIGHTLY_TOKEN"     # avec le code de sortie de la tâche

Un collecteur qui n'est pas une seule tâche pousse sa liste entière à la place : POST /ingest/<source> avec {"checks":{"list":[{"id":"…","service":"…","state":"ok","lastRunAt":"…"}]}} — la forme complète et les états se trouvent dans watcher skills sources.

Si une route de santé ne renvoie qu'un littéral, trouvez-en une plus profonde ou ajoutez-en une : GET /readyz → 200 {"db":{"ok":true}} lorsque la dépendance répond, 503 {"db":{"ok":false}} lorsqu'elle ne répond pas. L'édition du projet de l'utilisateur est autorisée — vous êtes l'agent qui écrit le fichier. Affirmez ensuite sur le champ changeant, jamais sur {"ok":true}.

Règles

  • Ne pointez jamais une source vers le propre /healthz du Watcher — source.self-probe le rejette.
  • Une source doit affirmer quelque chose qui peut basculer. Un simple 200 n'est que de la vivacité (source.bare-200) ; watcher doctor --live --prove est la porte d'entrée, --found-at est un avertissement (source.untraced).
  • Les secrets sont des noms de variables d'environnement dans la configuration et des valeurs uniquement dans .watcher/.env. Ne lisez jamais les valeurs .env pendant l'analyse, ne validez jamais .watcher/.env ou .watcher/data/.
  • Un seul canal fonctionnel bat cinq canaux configurés. Prouvez-le avec watcher test-alert. Aucune information d'identification du tout ? watcher add channel file --id local et prouvez-le : le fichier est un canal réel, et une information d'identification manquante est un saut nommé, jamais un succès.
  • Rapportez ce que vous avez prouvé — sources ajoutées, sortie de commande, et chaque saut nommé. Si l'agent ne peut pas terminer une étape (information d'identification manquante, pas de zone), dites lequel et pourquoi en une ligne.

Plus de détails, lorsqu'une étape en a besoin : watcher skills discover (catalogue complet des signaux et la liste de contrôle des silences), watcher skills sources (chaque type, options, exemples), watcher skills channels, watcher skills hosting, watcher skills cloudflare, watcher skills netdata, watcher skills operate (outils MCP et triage des incidents).

Skills associés