尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證A home server that diagnoses its own outages: Uptime Kuma alert → read-only evidence → redaction → LLM diagnosis (no tools) → incident page + one notification. Never executes fixes.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗When a service on my Raspberry Pi 5 home server goes down, this agent collects evidence, has an AI explain what happened, writes an incident page and sends one phone notification with the likely cause and the commands to fix it. It never runs anything itself: it only diagnoses, and a human decides.
It has run on the Pi since October 2026, watching about 30 services (Docker containers, systemd services, DNS, backups, disks, a Cloudflare tunnel).
http, dig, cert, backup_status) and lists
container/unit names, which are checked against a strict pattern. A config file can never add a command.rm -r, prune, fsck, mkfs, dd, umount, reading .env files, ...) are dropped
before anyone sees them.key=value secrets, notification topic
URLs, URL query strings, e-mail addresses, long hex strings and base64-like blobs.--max-budget-usd) and optionally per
month through a shared budget module. Plus: one diagnosis per monitor per 30 minutes, 10 per day.ProtectSystem=strict, so the whole filesystem is read-only for the
agent except its state and the incident pages.Real false alarms that changed the code:
ProtectSystem=strict sandbox every path
looks read-only. The collector now reads the host's mount table (findmnt --task 1, marked
"host view"), and the prompt only allows calling a disk read-only if those options start with ro,.known-issues.txt gives the model the server's history (e.g. "the HDD used to drop on the old power
supply", "get_throttled=0x80000 is a past soft temperature limit, not a power problem"), which made the
diagnoses noticeably more specific.jobwatch/ closes a gap Uptime Kuma has: is every scheduled job still running?
jobrun NAME MAXAGE command... wraps each cron job and records its last success in ~/.jobs/.jobwatch.py (cron, every 5 min) pushes up/down to a Kuma push monitor "Scheduled jobs", naming every
job whose last success is older than its MAXAGE and every watched systemd timer whose last run failed for
20+ minutes. If jobwatch itself stops, the push monitor goes down on its own.*/30 * * * * jobrun my-sync 7200 /usr/bin/python3 /opt/my-sync/sync.py
*/5 * * * * /usr/bin/python3 /usr/local/bin/jobwatch.py
When you remove a cron job, also delete its ~/.jobs/<name>.ok file, or jobwatch keeps reporting it as late.
Requirements: Python 3.11+ (standard library only), systemd, Docker (for container checks), Uptime Kuma with a status page that lists the monitors (the agent reads its public JSON API), and at least one of:
gemini-ask: any command that takes the system prompt as its last argument and the input on stdin,
accepts --tag, --timeout, --effort and --schema, and prints the JSON answer (mine runs the
Gemini CLI as a locked-down user), orclaude -p works for that user).sudo install -m 755 diag-agent.py /usr/local/bin/diag-agent.py
sudo mkdir -p /etc/diag /var/lib/diag /var/www/incidents
sudo cp examples/monitors.json examples/known-issues.txt /etc/diag/ # then edit both
sudo cp systemd/diag-watch.* /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now diag-watch.timer
sudo diag-agent.py list # monitors from the config
sudo diag-agent.py collect "Paperless" # print the redacted evidence, no AI
sudo diag-agent.py test "Paperless" # evidence + AI diagnosis, printed, no notification
python -m unittest discover -s tests -v # standard library only; runs in CI on Python 3.11 – 3.13
They cover the parts that keep the agent safe: redaction of secrets, the JSON-schema validation and the command blocklist, config values that try to inject commands, HTML escaping and pruning of incident pages, and jobwatch.
Monitor names in monitors.json must match the monitor names in Kuma. A monitor that is not in the config
still gets the generic evidence.
| Variable | Default | |
|---|---|---|
KUMA_URL | http://127.0.0.1:3001 | Uptime Kuma |
KUMA_STATUS_PAGE | home | slug of the status page with the monitors |
DIAG_CONFIG / DIAG_KNOWN | /etc/diag/monitors.json / known-issues.txt | |
DIAG_SITE | /var/www/incidents | where incident pages are written (kept 90 days) |
DIAG_PUBLIC_URL | http://localhost/incidents | link in the notification |
DIAG_NOTIFY | /usr/local/bin/notify | notify <channel> <prio> <title> <msg> <tags> <url>, e.g. an ntfy wrapper |
DIAG_ENGINE / DIAG_FALLBACK | gemini / claude | claude / none |
DIAG_GEMINI_ASK | /usr/local/bin/gemini-ask | |
DIAG_CLAUDE_USER / DIAG_CLAUDE_BIN | claude-runner / ~/.local/bin/claude | |
DIAG_MODEL | sonnet | Claude model for the fallback |
DIAG_MONTHLY_USD | 3 | monthly cap if ai_budget.py is present in /usr/local/lib |
DIAG_BACKUP_STATUS | /var/backups/STATUS | file read by the backup_status check |
MIT