Communityコーディング&開発github.com

ezolabs/ezo-watcher

プロジェクトに監視、アラート、アップタイムチェックを設定・追加・確認・修正するためのスキルです。ユーザーが「これを監視して」「アプリを見張って」「壊れたらページングして」「アラートが発火しなかった理由」などと依頼したときに使用します。

ezo-watcher とは?

EZO Watcherは、ユーザーのプロジェクトに直接インストールされるアラートウォール兼ページャーです。設定はコードとして`.watcher/`ディレクトリに格納され、ローカルのNodeプロセス1つで動作し、アカウント登録は不要です。このスキルは、`watcher` CLIをエンドツーエンドで駆動し、プロジェクトの初期化、テレメトリーポイントのスキャン(コードを読んでスキャンでは見えない静かなポイントも検出)、ソースと1つのチャネルの追加、`watcher doctor --live --prove`による全チェックが確実に異常(レッド)になることの証明、サーバーの実行、ローカルまたはCloudflare上でのホスティングを自動化します。特に、プロジェクトの本番環境の readiness ルートを最優先で監視し、スケジュールジョブや cron タスクなどの「沈黙」に注意を払い、実際に動作する監視とアラートを証明するところに重点を置いています。

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

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

EZO Watcherは、ユーザーのプロジェクトにインストールされるアラートウォール兼ページャーです。設定はコードとして.watcher/に保存され、ローカルのNodeプロセス1つで動作し、アカウントは不要です。あなたの仕事は、インストール全体を実際に動作する形で完了させることです — 単なる提案リストではありません。

CLIが唯一の情報源です。以下の各トピックはCLIから出力されます:watcher skills <topic>(トピック:install、discover、sources、channels、hosting、cloudflare、netdata、operate、fix、telemetry)、またはこのファイルと同じディレクトリにあるreferences/<topic>.mdを参照してください。すべてのコマンドはwatcher <verb>の形式で実行し、単独の単語(doctorはホストエージェント自身の/doctorと衝突します)では実行しないでください。

CLIのインストール

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

グローバルインストールしない場合:npx -y ezo-watcher <verb> で同じCLIを実行できます。チェックアウトからの場合:npm ci && npm run build && npm link。 Node 24以上が必要です。GitHubからの最新メインビルドを含む詳細は:watcher skills install。

ループ

.watcher/が既に存在する場合、まずwatcher doctor --jsonとwatcher scan --jsonを実行し、ランキングで不足しているものだけを追加します。動作しているインストールを再初期化しないでください。

  1. 初期化。 プロジェクトルートでwatcher initを実行します。冪等で、プロンプトは表示されません。.watcher/config.json、.watcher/.env(0600)、.watcher/data/を作成し、最後の2つをgitignoreに追加し、7717から空いているポートを選び、最初のdoctorサマリーを表示します。
  2. スキャン。 watcher scan --json → {signals, suggestedCommands}。小さな手動ラベル付きサンプルでは、プロトタイプが19個のHTTP/TLSポイントのうち15個を発見しましたが、10個のサイレンスポイントのうち2個しか発見しませんでした(watcher skills discover):そのコマンドを候補として扱い、コードを読みながら以下のサイレンス優先パスを実行します。
  3. ランキングに従って選択(次のセクション)。実際のポイントにつき1つのソース。グリーンに見せるためにソースをでっち上げないこと。
  4. 追加。 選択した各ソースに対して:watcher add <kind> --id <id> … --found-at <file:line> --read "<何を証明するか>"。--found-at/--readは出典情報で、これらがないとwatcher doctorが警告を出します。--dry-runでプレビューできます。次に1つのチャネル:watcher add channel <type> --id <id> …(watcher skills channelsを参照)。認証情報がない場合 — ヘッドレスボックス、ベンダーアカウントなし、ページャーを選択していないユーザー — 認証情報不要のフォールバックを追加します。watcher add channel file --id local:これは通知ごとに1行のJSONを.watcher/data/に書き込み、実際にテスト可能なチャネルであり、スタブではありません。watcher add … --replaceは既存のIDを書き換え、watcher rm <id>は削除します。
  5. doctorループ。 watcher doctor --json。ok:falseの場合、最初のfailをそのnextで修正し、再実行します。channel.missingの警告が出てユーザーが電話を鳴らしたい場合は、今すぐステップ8のチャネルを追加して戻ってきます。終了コード0は成功、1は失敗、64は使用方法の誤りです。
  6. 実行。 watcher run --detach(または再起動後も持続するwatcher service install)。その後watcher doctor --live --jsonで実行中のサーバーを読み取ります。
  7. 証明。 watcher doctor --live --prove --jsonを{"ok": true, "live": true}が返るまで実行します。--proveは各ソースの読み取り値を閾値を超えて移動させ、ルールが実際に反転しない限り失敗します(source.assertion-not-red;空疎なhttp-probeアサーションはsource.assertion-vacuousで失敗します):http-probeの応答は変更され、ハートビートは見逃し実行とその猶予期間後に評価され、ホスト読み取りはディスク/メモリ/負荷の閾値を超えて移動し、tcp接続は失敗し、有効期限はpageDays内に収まります。送信元が報告するアラートの種類(grafana、vmalert、sentry、netdata、feed、webhook)は名前付きのsource.prove-unsupportedスキップとなり、決して失敗にはなりません。プロジェクトにサーバーもスケジュールジョブもない場合、watcher add host --id host — マシン自体を、何もインストールせずローカルで読み取る — を追加して証明します。サーバーがなく、スケジュールジョブもなく、監視するホストもないプロジェクトのみ、watcher doctor --no-runtime-surface --jsonを実行 → {"ok": true, "live": false, "reason": "no-runtime-surface"}と平易に報告します。設定されたソースは常に--no-runtime-surfaceより優先されます(その場合、レポートはdoctor.no-runtime-surface-ignored警告を出します)。証明されていないインストールを完了と呼んではいけません。
  8. ページング。 1つのチャネルを追加し、watcher test-alertを実行します。重要なデバイスに届いたことを確認します。認証情報の欠落は名前付きスキップとなり、決して成功にはなりません。
  9. ホスティング(オプション)。 段階はローカル → サービス → Docker/VPS → Cloudflare Tunnel(「Cloudflareキーでホストする」場合のデフォルト) → Containersベータです。watcher skills hosting、watcher skills cloudflare。
  10. 次回のためにスキルをインストール。 watcher skills install --target all --dir .でプロジェクトに書き込みます。Claude Codeではその後**/reload-skills**を実行してください — セッション中に作成されたトップレベルのスキルディレクトリは、そうしないと認識されません。

2日目 — ウォールの読み取り、確認、コメント、サイレンス、保留、再チェック — はwatcher skills operateです。

何かが壊れたとき

インシデントは証拠を伴う主張であり、単なる通知ではありません。完全なループはwatcher skills fixです:

  1. watcher status --briefで1行表示、またはwatcher incidents --output jsonでキーを表示(MCP:watch_state、次にlist_incidents)。
  2. get_fix_context { key }(CLI:watcher incident <key> --fix-context):インシデント、ソースとターゲットの設定(認証情報は環境変数名として)、ルールのアサートと失敗したもの、エンドポイントが見つかった場所、最後の正常と最後の異常の観測値、チェックを再実行する正確なコマンド、そしてnext。
  3. そのコマンドから再現します。閾値は原因ではありません。
  4. 原因を修正し、修正が反映されるように再デプロイまたは再起動します。
  5. verify_fix { key, by }(CLI:watcher recheck <key> --wait):再チェックし、ソースの新しい応答を待ち、すべてのアラートが解決されたときに確認を記録します — または、どのアサーションがまだ失敗しているかを示し、修正を修復できるようにします。再チェックがグリーンになる前にインシデントを解決済みとマークしないでください。parkは修正がマージされたがまだライブではない場合、confirm_resolutionはソースが既に閉じた場合に使用します。
  6. 途中で見つけたことをcommentします。黙って修正すると、次に来る人に何も残りません。

ランキング:何を監視するか、優先順位順

  1. 本番プロセスの最も深い readiness ルート。依存関係がダウンしたときに変化するフィールドをアサートします。ハードコードされた{"ok": true} / {"status": "ok"}は決して使用しないでください — それは生存性であり、重要な障害ではレッドになり得ません。
  2. プラットフォームが既に宣言している readiness プローブ:/readyz、/health/ready、composeのhealthcheck、KubernetesのreadinessProbe、fly/railway/renderのヘルスパス。同じパスとポートで外部からミラーリングします。
  3. サーバーがない → スケジュールジョブごとに1つのハートビート。 沈黙がシグナルです。
  4. サーバーがなく、スケジュールジョブもない → watcher add host --id host(負荷、メモリ、空き容量、オプションでpidファイル。何もインストールしません)を追加して証明します。サーバーがなく、スケジュールジョブもなく、監視するホストもない場合のみ → watcher doctor --no-runtime-surface --json、NO_RUNTIME_SURFACEを報告して停止します。設定されたソースは常に--no-runtime-surfaceより優先されます。決してソースをでっち上げないでください。
  5. 次に、既存のシステム — Sentry、Grafana、Netdata、インバウンド送信者 — 認証情報にバインドされたもの。認証情報の欠落はコードとnextを持つ名前付きスキップであり、黙って成功ではありません。

最初に沈黙(スキャンが見逃すもの)

以下の6つのクラスについてコードを読みます。それぞれがwatcher add heartbeatまたはwatcher add webhook --stale-afterになります:

  1. インストール時に生成されるスケジュール — install.sh/setup.*内のheredocでplist、unit、crontabを書き込むもの、launchctl load、systemctl enable、crontabの書き込み。
  2. ランタイムに作成されるlaunchd/systemd/cron — .plistテンプレート、OnCalendar=、StartInterval、KeepAlive、node-cron、schedule(、ジョブをラップするsetInterval、celery beat。ジョブごとに1つのハートビート(--every/--schedule + --grace)。NジョブはNソースを意味します。
  3. プルキューワーカー — worker、queue、bullmq、sqs、claim、lease、dequeue。障害はキュー深度または進行の欠如であり、ポートではありません。成功パスでハートビートをpingするか、state: failingのエントリを持つchecks.listをプッシュします。
  4. プロダクト自身の設定における古さ — staleAfterSec、presenceTtlSec、maxAge、ttl、refreshInterval、lastRunAt。同じウィンドウを適用します:watcher add webhook --id <sender> --token-env <ENV> --stale-after-sec <sec>。
  5. 状態ディレクトリの書き込み可能性 — mkdir、state/、data/、sqlite、ロックファイル。成功した書き込みの後にのみpingします。単なるtest -wはソースではありません。
  6. コード定数として保持される依存関係エンドポイント — process.env.X ?? "https://…"、ホスト:ポートリテラル、gRPC/ClickHouse/LLMベース。watcher add http-probe(HTTPS GET)またはwatcher add tcp-probe --host --port、--found-atは定数。

pingはジョブの成功パスに配置します — POST /ingest/heartbeat/<id>、失敗した実行には/fail、特定の終了コードには/<exit-code>。watcher add heartbeatは、名前付き変数にまだ値がない場合にトークンを.watcher/.env(0600)に作成するか、渡した--secret-valueを書き込み、正確な行を出力します(以下の$NIGHTLY_TOKENは--id nightlyに対して選ばれた名前です。渡した--token-envは代わりに出力される変数です):

set -a; . .watcher/.env
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>?token=$NIGHTLY_TOKEN"                 # 成功した実行の後
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>/fail?token=$NIGHTLY_TOKEN"            # 失敗した実行の後
curl -fsS -m 10 "${WATCHER_URL:-http://127.0.0.1:7717}/ingest/heartbeat/<id>/<exit-code>?token=$NIGHTLY_TOKEN"     # ジョブの終了コード付き

1つのジョブではないコレクターは、代わりに完全なリストをプッシュします:POST /ingest/<source> with {"checks":{"list":[{"id":"…","service":"…","state":"ok","lastRunAt":"…"}]}} — 完全な形状と状態はwatcher skills sourcesにあります。

ヘルスルートがリテラルのみを返す場合、より深いものを見つけるか、追加します:GET /readyz → 依存関係が応答する場合は200 {"db":{"ok":true}}、応答しない場合は503 {"db":{"ok":false}}。ユーザーのプロジェクトの編集は許可されています — あなたはファイルを書き込むエージェントです。そして、変化するフィールドをアサートし、決して{"ok":true}をアサートしないでください。

ルール

  • Watcher自身の/healthzにソースを向けないでください — source.self-probeが拒否します。
  • ソースは反転できる何かをアサートしなければなりません。 単なる200は生存性のみです(source.bare-200)。watcher doctor --live --proveがゲートであり、--found-atは警告です(source.untraced)。
  • シークレットは設定内では環境変数名、値は.watcher/.env内のみです。 スキャン中に.envの値を読み取らず、.watcher/.envや.watcher/data/をコミットしないでください。
  • 1つの動作するチャネルは、5つの設定されたチャネルに勝ります。 watcher test-alertで証明してください。認証情報がまったくない場合? watcher add channel file --id localを追加してそれを証明します:そのファイルは実際のチャネルであり、認証情報の欠落は名前付きスキップであり、成功ではありません。
  • 証明したことを報告してください — 追加されたソース、コマンド出力、そしてすべての名前付きスキップ。エージェントが段階を完了できない場合(認証情報なし、ゾーンなし)、それを1行で理由とともに述べてください。

詳細は、ステップが必要な場合:watcher skills discover(完全なシグナルカタログとサイレンスチェックリスト)、watcher skills sources(すべての種類、フラグ、例)、watcher skills channels、watcher skills hosting、watcher skills cloudflare、watcher skills netdata、watcher skills operate(MCPツールとインシデントトリアージ)。

関連スキル