No description
  • JavaScript 75.7%
  • Shell 13.7%
  • CSS 7.8%
  • HTML 2.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-26 09:59:02 +00:00
deploy Add idempotent install.sh for one-command deployment 2026-09-26 14:56:59 +05:00
docs docs: add label set reference synced with keba-hhs 2026-09-26 13:51:08 +05:00
public feat(ui): agent hub stage B - registry, connect modal with healthcheck, base URL switching 2026-09-26 14:45:35 +05:00
src feat(api): add GET /api/health endpoint and opt-in CORS for API 2026-09-26 14:17:44 +05:00
test feat(api): add GET /api/health endpoint and opt-in CORS for API 2026-09-26 14:17:44 +05:00
.gitignore feat: session JSONL parser with metrics aggregation + fixtures/tests 2026-09-26 12:25:38 +05:00
package.json fix: npm test invocation (node --test without path arg) 2026-09-26 12:29:52 +05:00
README.md Add idempotent install.sh for one-command deployment 2026-09-26 14:56:59 +05:00
web-monitor-prompt.md feat: session JSONL parser with metrics aggregation + fixtures/tests 2026-09-26 12:25:38 +05:00

watcherenish

Web-интерфейс для мониторинга coding-агента pi на этой машине: сессии, статистика (токены, стоимость, время tool-вызовов), полный транскрипт любой сессии и хвост gate.log. Только чтение — сервис ничего не пишет ни в ~/.pi/agent, ни в логи.

Возможности (этап 1, MVP)

  • Дашборд: всего сессий / активных сейчас (mtime < TTL) / за сегодня, токены и стоимость за сегодня, последняя активность.
  • Список сессий: поиск (имя / путь / модель / id), пагинация, сортировка по mtime.
  • Детали сессии: транскрипт — user/assistant текстом, thinking свёрнут, каждый tool-вызов — сворачиваемый блок (имя, длительность, аргументы, результат, ошибки подсвечены красным); панель метрик (токены, cost, модели, длительность, ошибки, compactions). Для обрезанных toolResult с fullOutputPath подгружается полный вывод.
  • Лог gate: хвост gate.log (N строк), поиск по подстроке, обновление кнопкой. Если файла нет — интерфейс сообщает об этом и не падает.

Сессии читаются из ~/.pi/agent/sessions/--<encoded-cwd>--/<timestamp>_<uuid>.jsonl (формат v3). Битые/незавершённые строки JSONL пропускаются с warning — агент может писать файл прямо сейчас.

Установка

Требуется Linux с systemd; Node.js ≥ 20 установщик поставит сам, если его нет. Зависимостей нет — только стандартная библиотека.

Одна команда — скачивание и установка (идемпотентно: повторный запуск обновляет код и рестартует сервис):

curl -fsSL http://10.10.1.7:3000/forgejo-admin/watcherenish/raw/branch/main/deploy/install.sh | sudo bash

Скрипт deploy/install.sh проверяет окружение, при необходимости ставит Node.js ≥ 20, клонирует/обновляет код в /opt/watcherenish, гоняет npm test, генерирует systemd-юнит и конфиг /etc/default/pi-web-monitor (при первой установке создаёт AUTH_TOKEN и печатает его в итоговом статусе), запускает сервис и ждёт GET /api/health. В конце — статус об успешной/неуспешной установке. Конфиг при повторных установках не перетирается — ручные правки и токен сохраняются. Все пути и параметры переопределяются переменными окружения (INSTALL_DIR, INSTALL_USER, PORT, BIND, SESSIONS_DIR, GATE_LOG и др. — см. шапку deploy/install.sh).

Вручную (если хочется контролировать каждый шаг):

# на Linux-машине
git clone http://10.10.1.7:3000/forgejo-admin/watcherenish.git /opt/watcherenish
cd /opt/watcherenish
npm test                             # 33 теста: парсер, конфиг, API, logtail
npm start                            # запустить вручную: http://127.0.0.1:8787

Конфигурация (переменные окружения)

Переменная По умолчанию Описание
PORT 8787 порт HTTP
BIND 127.0.0.1 адрес; 0.0.0.0/:: требует AUTH_TOKEN, иначе сервер откажется стартовать
AUTH_TOKEN — если задан — все /api/* требуют Authorization: Bearer <token> (страницы UI отдаются без токена, токен вводится в UI)
SESSIONS_DIR ~/.pi/agent/sessions каталог сессий
GATE_LOG /var/log/pi-agent/gate.log лог gate-проверок
GATE_LINE_REGEX — регэксп для разбора строк лога (этап 3)
ACTIVE_SESSION_TTL_MIN 15 окно «активна сейчас» по mtime, минуты
ALLOWED_ORIGINS — список origin через запятую, которым разрешён CORS-доступ к /api/* (например http://win-pc:5173,https://hub.local); не задан — same-origin режим, CORS-заголовки не отдаются

systemd

deploy/install.sh делает всё нижеперечисленное автоматически: юнит генерируется из deploy/pi-web-monitor.service (подставляются User=, WorkingDirectory=, путь к node), а все переменные окружения выносятся в EnvironmentFile=/etc/default/pi-web-monitor.

Вручную:

sudo cp deploy/pi-web-monitor.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now pi-web-monitor
systemctl status pi-web-monitor

Проверка живости (например, из мониторинга или UI-хаба):

curl -s -H "Authorization: Bearer $AUTH_TOKEN" http://127.0.0.1:8787/api/health
# {"status":"ok","sessionsDir":"/home/pi/.pi/agent/sessions","sessionsDirExists":true,"uptimeMs":...}

Юнит запускает сервис от пользователя pi (поправьте User=/WorkingDirectory= под себя) с hardening: ProtectSystem=strict, ProtectHome=read-only — сервис физически не может писать в ~/.pi.

API

  • GET /api/health — healthcheck (та же Bearer-авторизация): 200 { status: ok|degraded, sessionsDir, sessionsDirExists, uptimeMs }; нужен для подключения удалённых агентов из UI-хаба.
  • GET /api/summary — счётчики, токены/cost за сегодня, последняя активность.
  • GET /api/sessions?limit=&offset=&search= — список с метриками, mtime desc.
  • GET /api/sessions/:id — метаданные + все entries (id, parentId, type, timestamp, role, превью) — дерево в порядке следования.
  • GET /api/sessions/:id/messages — линейный транскрипт для рендера (tool-вызовы связаны по toolCallId с длительностью и аргументами).
  • GET /api/logs/gate?tail=500 — строки лога (отдаёт exists:false + ошибку, если файл недоступен).

Безопасность

  • По умолчанию слушает только 127.0.0.1; доступ снаружи — через SSH-туннель (ssh -L 8787:127.0.0.1:8787 user@host) или Tailscale.
  • BIND=0.0.0.0 без AUTH_TOKEN — ошибка запуска.
  • Транскрипты содержат содержимое файлов и вывод команд — не публикуйте UI в интернет.
  • В файловую систему pi сервис не пишет (проверено hardening'ом юнита и кодом: только fs.readFile/createReadStream).

Структура

src/
  server.js     HTTP-сервер, роуты, статика (node:http, без зависимостей)
  parser.js     парсер JSONL-сессий, агрегация метрик, кэш по mtime
  config.js     env + дефолты + валидация
  logtail.js    хвост лог-файла (чтение с конца)
public/         UI: vanilla JS + CSS, без сборки и CDN
test/           фикстуры + node --test (parser, config, api, logtail)
deploy/         systemd unit + install.sh (идемпотентный установщик «одной командой»)

Дорожная карта (этапы 2–4 из web-monitor-prompt.md)

Этап 2 — live-обновления (fs.watch + SSE), этап 3 — метрики gate-проверок по GATE_LINE_REGEX, этап 4 — RPC-мост/collector. Реализуются по отдельному указанию.