---
name: zemlya-cli
description: >
  Быстрая read-only диагностика недвижки (zemlya-bot + zemlya-web, zbrcheck.ru)
  через единый CLI `zemlya` на mac mini — вместо ad-hoc `python -c`/грепов по SSH.
  Брать когда: «проверь недвижку/бот земли», «живы ли сервисы zemlya», «работает ли
  LLM-каскад / капча rosreestr_lk», «что с Avito/CIAN/Yandex (403/фолбэки)», «жив ли
  НСПД / забанен ли IP», «покажи статистику/оплаты/счётчики недвижки», «грепни лог бота
  земли». НЕ для мутаций (прогон отчёта, деплой), не для других проектов
  (avtero→avtero-tecdoc, Делор→delor-sport-cli, КодИнвест→investpilot-cli),
  не для e2e-прогона отчёта (→ zemlya-report-e2e).
---

# zemlya-cli — read-only диагностика недвижки

CLI-обёртка над уже существующим кодом/БД/логами zemlya-bot (метод «CLI вместо MCP»,
как [[avtero_tecdoc_skill]] / [[delor_sport_cli_skill]] / [[investpilot_cli]]).
Ничего не дублирует, **ничего не мутирует** — только читает.

## Где живёт
- Скрипт на mini: `~/Services/zemlya-bot/tools/zemlya_cli.py` (запуск через venv бота).
- Копия для редеплоя: `tools/zemlya_cli.py` рядом с этим SKILL.md.
- Доступ к mini: `ssh -i ~/.ssh/id_ed25519 -p 2222 cebers_mini@100.84.177.25`.

## Запуск (одной строкой по SSH)
```bash
ssh -i ~/.ssh/id_ed25519 -p 2222 cebers_mini@100.84.177.25 \
  'cd ~/Services/zemlya-bot && ./venv/bin/python tools/zemlya_cli.py <cmd> [args]'
```
Хвост `2>&1 | grep -vE "Asyncio patch"` убирает шумную стартовую строку бота.
**Важно (zsh):** не класть `./venv/bin/python tools/...` в переменную и звать `$P` —
zsh не разобьёт на слова. Писать команду целиком.

## Команды
| Команда | Что показывает |
|---|---|
| `health` | Состояния всех сервисов недвижки (launchctl: up/down/idle + PID) + HTTP-хелсчеки backend :20140 и nspd-fast :20155 |
| `llm` | Живой пинг LLM-каскада: `gemini-slot` (Mistral) и `gpt-slot` (glm/groq) → OK/None. Ловит мёртвый провайдер OmniRoute |
| `sources [--min N]` | Avito/CIAN/Yandex за N мин (деф. 30): curl_ok / 403 / fallback + статус NSPD-sidecar (детект BlockedIP) |
| `nspd <КН>` | Прямой запрос NSPD-sidecar по кадастровому номеру: OK+geometry или `BlockedIP` (бан WAF KillBot) |
| `captcha [--min N]` | rosreestr_lk: SUCCESS / timed out / не успел grace / Mistral-PRIMARY / NIM best-vote / Mistral-404 |
| `stats` | Агрегаты day/week/all: заходившие(делавшие проверку)/новые/проверки[free,pro,ai]/оплаты/выручка (raw SQL, боевые платежи) |
| `db` | Счётчики users / reports[по режимам] / payments completed + выручка |
| `logs <фильтр> [-n N]` | Греп по логу бота (`~/Services/shared/logs/zemlya-bot.log`), последние N (деф. 40) |

## Заметки по интерпретации
- `health`: cron/one-shot джобы показываются `idle` (pid `-`, exit 0) — это норма. `exit=-15` при живом PID = был SIGTERM+рестарт, ок. Реальная тревога — `down` с ненулевым exit у постоянного сервиса.
- `sources`: пустые нули за окно = просто не было проверок в этот период (не поломка). Тревога — высокий `403`/`fallback`. NSPD `BlockedIP` = WAF НСПД (KillBot) забанил IP мини; лечится ожиданием/резидентным RU-прокси, не сменой на VPS (датацентр банится сразу).
- `captcha`: капча решается (SUCCESS>0) даже при больших timeout — узкое место не распознавание, а сам сервер ЛК Росреестра (30с таймаут).
- `stats`/`db`: `amount` в БД — копейки, CLI уже делит на 100; выручка = только боевые (`is_test=0`) completed-платежи.

## Редеплой / правка
Править локальную копию `tools/zemlya_cli.py`, затем:
```bash
scp -i ~/.ssh/id_ed25519 -P 2222 <path>/tools/zemlya_cli.py \
  cebers_mini@100.84.177.25:/Users/cebers_mini/Services/zemlya-bot/tools/zemlya_cli.py
```
Схема БД (сверялось): `reports(user_id,report_mode,is_paid,created_at,...)`,
`payments(amount[копейки],status,is_test,completed_at,...)`, `users(created_at,...)`.
DB: `~/Services/zemlya-bot/data/db/zemlya_bot.db` (общая с ботом; открывается `mode=ro`).
