hour tick 22:41: bin/simbiot in-repo обёртка + SIMBIOT_RAG_DB (миграция второго инстанса), digest 2110/1720 закоммичены, deferred-restart arm-скрипт, AUM burn 2658

This commit is contained in:
Simbiot Harness 2026-10-02 23:02:55 +00:00
parent feaf660139
commit 56d6b36658
9 changed files with 373 additions and 2 deletions

42
bin/simbiot Executable file
View file

@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Simbiot Harness: запуск без установки обёртки (cli.py + scheduler-демон).
# simbiot help — справка по CLI-командам (как python cli.py -h)
# simbiot — без аргументов: статус + как управлять демоном/CLI
# simbiot --help — как help (аргумент для argparse-привычки)
DIR="$(cd "$(dirname "$(readlink -f "$0")")/.." && pwd)"
unset PYTHONPATH
unset PYTHONHOME
cd "$DIR" || exit 1
PY="$DIR/venv/bin/python"
[ -x "$PY" ] || PY="$(command -v python3)"
_flag=0
for a in "$@"; do
case "$a" in
help|--help) _flag=1 ;;
esac
done
if [ "${_flag}" = 1 ]; then
exec "$PY" cli.py -h
fi
if [ $# -eq 0 ]; then
# Без аргументов: показать, что живёт и куда тыкать
echo "Simbiot Harness CLI — venv: $PY, репо: $DIR"
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-active --quiet simbiot-harness; then
echo "Демон : active (systemctl status simbiot-harness)"
else
echo "Демон : не активен — $DIR/scripts/install.sh --systemd либо ./venv/bin/python -m harness.scheduler"
fi
elif pgrep -f "harness.scheduler" >/dev/null; then
echo "Демон : жив (pgrep harness.scheduler)"
else
echo "Демон : не запущен — $DIR/venv/bin/python -m harness.scheduler"
fi
echo "Быстрые команды:"
echo " simbiot status — статус харнеса"
echo " simbiot task ... — подать задачу"
echo " simbiot wizard — настройка (TG-бот, 9router, модель)"
echo " simbiot help — все команды CLI"
exit 0
fi
exec "$PY" cli.py "$@"

View file

@ -0,0 +1,86 @@
# Sales plan: 1000 Simbiot preorders (US)
> t-261001085926-aebd52 [L]. Alex (батч m-516173332..334): одобрено продвижение
> предпродажи, «чтобы купили не 10, а 1000 предзаказов». 10 = валидация спроса,
> 1000 = реальный канал продаж. Фильтр AUM: план напрямую строит предзаказы.
> Прайс — только по директиве (docs/PRICE-DIRECTIVE-SIMBIOT.md): $100/mo,
> без скидок, срочность через лимит мест. Пакет — docs/PACKAGE-SIMBIOT-PRESALE.md.
## 0. База, на которой строим
- Лендинг на **https://presale.cil.by** (Caddy root /var/www/simbiot-presale), A/B заголовков + клик-трекинг + живой счётчик мест из биллинга уже завязаны.
- **Живой Stripe-линк**: checkout `https://buy.stripe.com/aFa28q8h14RpfPYgrK1B60a` (старый заглушки `test_...` закрыты).
- Биллинг/admin: saas_admin на 127.0.0.1:8902 (за Caddy), API `/api/presale/seats`.
- Продукт живой у нас в проде (харнес, портал, дашборд) — главный якорь доверия.
## 1. Воронка и математика (честная)
1000 предзаказов через один органический лендинг не приходят — нужен трафик
и конверсия. Модель:
| Этап | Сейчас | Цель к 1000 продаж |
|---|---|---|
| Посетителей лендинга / мес | ~0 (нет трафика) | 100–200k/mo |
| CTR по CTA (checkout) | неизвестно (трекинг есть) | ≥ 3% |
| Checkout → купивший (конверсия чекаута) | неизвестно | ≥ 2% |
| Посещение → покупка (сквозная) | неизвестно | ≥ 0.5–1% |
Точка отсчёта: **первые 10** (текущий план мест) — их берём из тёплого
контекста и платного трафика сразу. Затем расширяем лимит мест
(решение Alex — директива), пока воронка не тянет 1000.
## 2. Каналы (по приоритету запуска)
### Тир-0: тёплый контур (запуск немедленно, $0)
1. **Личный круг Alex + кооперативных сетей**: прямые сообщения/посты со
ссылкой на presale.cil.by. Цель: первые 1–3 предзаказа (соцдоказательство
для кворум-затычки на лендинге — реальная цитата вместо плейсхолдера).
2. **Наш Telegram/каналы и x.com**: серия постов «как харнес живёт день из
жизни» — скрины дашборда, диалога с агентом. CTA: presale.cil.by.
3. **Show HN / Reddit r/SideProject, r/Entrepreneur, r/AI_Agents**: пост
«we open-sourced our ops: 7 products run by one AI harness» + бренд-линк.
Ограничение: не спамить, один показательный пост на площадку.
### Тир-1: контентный SEO + email ($0, растёт месяца за 2)
4. **Блог на cil.by/simbiot**: 4–6 длинных статей с честными метриками
(how we run coop on an AI harness, harness vs Slack-bot, our ladder
architecture). Каждая ведёт на вейтист + лендинг.
5. **Email-каптива**: вейтист-форма (mailto + форма на биллинг) → дрип-серия
5 писем (1 день/показ/доказательство/цена/дедлайн мест).
### Тир-2: платный трафик (после первых продаж и трекинга)
6. **Google Ads + Reddit/X Ads на B2B-запросы** ("AI agent for agency",
"AI project manager"): бюджет старт-тест $300–500, метрика — CPL по
клику на checkout. Каналы открывать только с работающим pixel/трекингом.
7. **Партнёрка/рефералка**: 3 месяца бесплатно за приведённого платящего
покупателя (не скидка новому — иначе ломает прайс-тест).
### Тир-3: исходящий B2B (нужен человек, старт после найма)
8. **Список 200 агентств/студий/мини-агентур** (US, 5–50 человек) →
персональные письма с записью-демо 90 сек. Целевой CPL в исходнике ниже,
но конверсия в оплату выше. Это канал, который масштабируется на 1000.
9. **Демо-агентов как лид-магниты**: поставить харнес на 3–5 студий в пилот
на 2 недели → кейсы (светлые цитаты) → их аудитории.
## 3. Первые действия (неделя 1 — с этого тика)
- [ ] `docs/PACKAGE-SIMBIOT-PRESALE.md` EN-блок вставить в лендинг offer-секцию
(v3-пункт road v2, задача t-261002151244 уже покрывает дизайн).
- [ ] Тёплый пост №1 (Telegram + x.com) с живой ссылкой + скрин дашборда.
- [ ] Show HN draft + r/SideProject draft — на ревью Alex (не публиковать без
его ок — это публичные репрезентации кооператива).
- [ ] Собрать список 20 студий (руками, без скрейпа) для исходника пилота.
- [ ] Наладить еженедельный срез метрик: визиты по /api/presale/click,
checkout-открытия, оплаченные (Stripe balance) — сводка в дайджест часа.
## 4. Что мешает/блокирует (эскалировать при появлении)
- Лимит мест (старт 10) — механика «продали все → вейтист» останавливает
масштаб до директивы Alex о расширении. Нужен критерий: расширять, когда
7/10 мест оплачено.
## 5. Что делает продажу реальной (дорожная карта)
- Первая живая цитата пилота → заменить кворум-затычку (P2 из SALES-PLAN-PRESALE-PAGE).
- Демо-видео 90 сек для исходника и соцсетей.
- Полный онбординг-поток за ≤ 30 дней (задача t-261002193420-10185f).

View file

@ -0,0 +1,63 @@
# Hour digest 2026-10-02 ~17:20 UTC
## Что произошло (консолидация мин-событий)
- Мин-тики 16:00–16:54: quiet-gate (LLM не запускался, событий ниже порога).
16:54–17:00 — два голосовых Alex: m-516173447 (Юлия, звонок завтра 14:00)
и m-516173448 («создал встречу — агент не подключился»).
- Артефакт-клон 'list' (t-261002152213-f2ef48, 15:22, из служебного сообщения)
был закрыт мин-тиком в 15:36 — с этого момента в готовых клонах пусто.
- Мин-уровень параллельно час-тику сам отправил сводный ответ на оба голосовых
(батч b-516173447-2, 17:16) — входящие закрыты; час-добавка ушла отдельным
идемпотентным tg-notify (ключ yulia-contact-request-261002).
## Час-уровень сделал за этот тик
- **Инцидент встр.135 «Evgeni sink SpruIT» (20:00–20:30 Минск, m-516173448)**:
запись и in-call агент не стартовали автоматически (recording=0, файлов нет;
симбиот-бот подключается только к активной записи). Ручной старт
record_and_process.py 135 в 17:08 → запись живая (5 МБ, live-транскрипция,
speaker tracking), Симбиот на звонке: ambient-карточки идут, тема
«Стартап из Эстонии: SMS-робот для допродаж в Shopify». Гонка двойного
старта закрыта: pid-файл + meeting_reminders 'autorec' + recording=1,
дублей процессов нет.
- Реплей auto_recorder на scratch-копии coop.db (recording=0, 19:59): скрипт
ЛОВИТ встр.135 в окно (WOULD-POPN напечатан) — т.е. логика окна была верной, а реальный
cron-прогон в 16:59 молчал. Нагрузка в момент 0.4–0.8, OOM нет, скрипты
не менялись (git чист), логи без Traceback. Причина «тихого» пропуска
не названа — усиление: в auto_recorder.py и booking_autorec.py добавлены
даталог с таймстампом каждого прогона (кандидаты/старт/причина) и
traceback-обёртка — следующий промах сам покажет причину.
- **Юлия (m-516173447)**: слот создан — встреча #136 завтра 2026-10-03
11:00–11:20 UTC = 14:00–14:20 Минск (external=1, consent_rec=1,
room coop-00091786, паттерн /book20; конфликтов нет).
Контакт/email НЕ найден нигде: apply42 (форма подачи), meeting_guests
(/book20), Rallly, EspoCRM (нет доступа к MySQL), Chatwoot (пусто),
транскрипты («юличких» — ложное совпадение), /var/www, /root — только
старый LinkedIn-pool-тёзки (2017–2023). Задача t-261002171241-41c448 [M]
подана на доску; запрос email/тг-ника ушёл Alex (tg-notify идемпотентно).
- **Эскалация e-261002153517-018fc8 закрыта (ack)**: 'list'-клон t-...f2ef48
уже done (15:36), в ready его нет — ре-пика не будет. Отдельного
гигиена-клонов не заводил: покрывает t-260930172407.
## Открытые точки (в день-уровень / Alex)
1. Причина тихого пропуска автозаписи встр.135 — реплей чистый, реальный
прогон молчал. Следить за новым даталогом на ближайших встречах
(ежедневный синк / Симбиот-звонок); если повторится — deep-dive.
2. Контакт Юлии: ждём email/тг-ник от Alex → тогда отправить ей подтверждение
+ нотификацию (или Alex пошлёт сам). Задача t-261002171241-41c448.
3. Периодические JSON-ошибки ambient-LLM в symbiot-call-bot («Unterminated
string») — не блокируют звонок; оформить S-задачей на тихой минуте.
4. 7 L-задач ready (см. hour-1510) + вопрос $99.90 vs $100 в Stripe — за
day-тиком / решением Alex (без изменений).
## Фоновые задачи
- Активных фоновых задач час-уровня нет (фоновый grep по «Юлия» — пусто).
- Сервисы active: simbiot-harness, simbiot-harness-tg, simbiot-dashboard,
simbiotd, saas-admin, symbiot-call-bot, live-transcriber, pulse-rec,
coop-portal.
- Встреча 135 пишется штатно; follow-up после 20:30: проверить
meeting-135.status → done, транскрипт/summary и email-саммари (guest нет —
значит, summary только в портал).
## Ресурсы
- load1 в тик 0.34–0.8; RAM ок; подкачка 8/8G (кэш, безопасно).
- Нагрузка LLM-тика обычная; 9router burn не изменился за тик.

View file

@ -13,7 +13,7 @@
- Эскалация e-261002202857-73bbaf (info, min→hour) — закрыта реализацией фичи.
- Тесты: 14/14 сидов зелёные, включая новый `tests/test_seen_indication.py` (20 проверок).
- AUM: не замерен (balances.json нет); burn 9router: 24ч=147.03 · 7д=2638.32 у.е. — прямой минус к AUM.
- Деплой: пуш `aeb4cb1..26edbb7` → origin (git.cil.by), верифицирован. Рестарт `simbiot-harness-tg` — реакция 👀 при приёме активна на живом поллере. Для typing-части (живёт в процессе scheduler) требуется рестарт main-`simbiot-harness` — он УБИВАЕТ работающие воркеры текущих тиков, поэтому отложен: systemd-таймер рестарта после завершения часового тика.
- Деплой: пуш `aeb4cb1..26edbb7` → origin (git.cil.by), верифицирован. Рестарт `simbiot-harness-tg` — реакция 👀 при приёме активна на живом поллере. Для typing-части (живёт в процессе scheduler) требуется рестарт main-`simbiot-harness` — он УБИВАЕТ работающие воркеры текущих тиков, поэтому запланирован отложенно: транзитная systemd-единица arm-скрипта рестартует сервис только убедившись, что активных LLM-воркеров нет (9с пустого окна, дедлайн ~20м; не найдёт окно — не рестартует вовсе, бережёт работающие тики).
## Из минутных выжимок (контекст, не подняли)
- m-516173494 (Alex: «поставил заново, команда не работает») — минимальный уровень запросил три конкретики (команда / полный вывод / сервер); ответа пока нет — ждём, вслепую не гадаем.

View file

@ -0,0 +1,98 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Нейронки на FPGA — практический гайд</title>
<style>
:root{--bg:#0f1115;--card:#171a21;--ink:#e8eaf0;--dim:#9aa3b2;--acc:#7aa2ff;--acc2:#7ee0b8;--warn:#ffb86c}
*{box-sizing:border-box}
body{margin:0;font:16px/1.65 -apple-system,"Segoe UI",Roboto,sans-serif;background:var(--bg);color:var(--ink)}
.wrap{max-width:860px;margin:0 auto;padding:40px 24px 80px}
h1{font-size:30px;line-height:1.25;margin:0 0 6px}
h2{font-size:21px;margin:40px 0 12px;color:var(--acc)}
h3{font-size:17px;margin:24px 0 8px;color:var(--acc2)}
p,li{color:var(--ink)}
.lead{color:var(--dim);font-size:15px;margin:0 0 8px}
.card{background:var(--card);border:1px solid #262b36;border-radius:14px;padding:20px 22px;margin:16px 0}
table{width:100%;border-collapse:collapse;margin:12px 0;font-size:15px}
th{color:var(--dim);text-align:left;font-weight:600;border-bottom:1px solid #2c3242;padding:8px 10px}
td{border-bottom:1px solid #20242f;padding:8px 10px;vertical-align:top}
td b{color:var(--acc2);white-space:nowrap}
code{background:#0c0e12;border:1px solid #262b36;border-radius:6px;padding:1px 6px;font-size:14px;color:var(--warn)}
.tag{display:inline-block;background:#1c2436;color:var(--acc);border-radius:99px;padding:2px 10px;font-size:13px;margin-right:6px}
.note{border-left:3px solid var(--warn);padding:10px 14px;background:#1c1a12;border-radius:0 10px 10px 0;color:var(--dim);font-size:15px}
ul{margin:8px 0;padding-left:22px}
li{margin:5px 0}
a{color:var(--acc);text-decoration:none}
footer{margin-top:48px;color:var(--dim);font-size:13px;border-top:1px solid #262b36;padding-top:16px}
</style>
</head>
<body>
<div class="wrap">
<p class="lead">Ответ на вопрос Андрея из лаборатории • кооператив 42 • 2026-10-02</p>
<h1>🧠 Нейронки на FPGA: что реально, что стоит и с чего начать</h1>
<p class="lead">Короткий практический гайд: что запускается, сколько стоит железо, когда FPGA оправдан, а когда проще взять TPU/микроконтроллер.</p>
<div class="note" style="margin-top:28px">⚡ <b>Суть в одну строку:</b> маленькие квантованные сети на FPGA — да, рабочий кейс; полноценные LLM — нет (упираются в память и пропускную способность). FPGA — про микро-задержки и кастомный пайплайн, не про большие модели.</div>
<h2>1. Что реально запускается на FPGA</h2>
<div class="card">
<p>На FPGA живёт класс <span class="tag">TinyML</span><span class="tag">hls4ml</span><span class="tag">FINN</span> — квантованные (INT8/INT4) сети на миллионы параметров:</p>
<ul>
<li>распознавание звука («hey device»-киворды, классификация команд);</li>
<li>зрение: детекция лиц/жестов, классификаторы уровня MobileNet / small ResNet;</li>
<li>тайм-серии: сенсоры, вибрация, предсказание отказов.</li>
</ul>
<p>Квантованные CNN идут с латентностью в <b>микросекунды–миллисекунды</b> — это то, что делает FPGA уникальным: детерминированный отклик, предсказуемый тайминг, полный контроль над пайплайном.</p>
<p>А вот трансформеры/LLM — не вариант: веса гигабайты, и всё упирается в пропускную способность памяти (у FPGA её на порядки меньше, чем у GPU).</p>
</div>
<h2>2. Железо: цена вопроса</h2>
<table>
<tr><th>Бюджет</th><th>Платы</th><th>Что получаешь</th></tr>
<tr><td><b>~$100–300</b></td><td>ULX3S, iCEBreaker, Tang Mega</td><td>«Пощупать»: крошечные сети, учебные проекты (hls4ml, TinyML). Энтузиазм, но AI-стек придётся собирать самому.</td></tr>
<tr><td><b>~$150–250</b></td><td>PYNQ-Z2, Kria KV260</td><td>Классика для нейронок: готовый AI-стек Xilinx (Vitis AI, DPU), нормальные квантованные CNN. <b>Kria — самый простой вход</b>, рекомендую начинать с неё.</td></tr>
<tr><td><b>~$1000–3000</b></td><td>ZCU104, Alveo</td><td>Более крупные модели, но это уже ниша (наука/прототипы), дорого за «минимальную нейронку».</td></tr>
</table>
<h3>Честные не-FPGA альтернативы</h3>
<table>
<tr><th>Плата</th><th>Цена</th><th>Когда лучше</th></tr>
<tr><td>Google Coral TPU (USB)</td><td><b>~$60</b></td><td>Просто инференс квантованной модели — обычно проще и дешевле FPGA</td></tr>
<tr><td>Jetson Orin Nano</td><td><b>~$249</b></td><td>Когда нужна полноценная CUDA и модели покрупнее</td></tr>
<tr><td>ESP32-S3</td><td><b>~$5</b></td><td>Совсем маленькие сети на устройстве — «дёшево и сердито»</td></tr>
</table>
<h2>3. Когда связка «нейронка + FPGA» осмысленна</h2>
<div class="card">
<p><b>(а) LLM пишет HDL.</b> Самое интересное: языковая модель не <i>работает</i> на FPGA, а <i>пишет/правит цифровую логику</i> для неё (генерация Verilog/VHDL) — это уже рабочий кейс. LLM как проектировщик железа, FPGA как исполнитель.</p>
<p><b>(б) FPGA как тело устройства с tinyML-мозгом.</b> Устройство с микро-задержкой отклика распознавает жест/звук/образ и тут же управляет железной логикой. Вот тут квантованная сеть FPGA даёт уникальные качества (энергопотребление, латентность, предсказуемость).</p>
</div>
<h2>4. Реальные проекты-ориентиры</h2>
<ul>
<li><b>FINN</b> (Xilinx/AMD) — фреймворк для полностью бинаризованных и квантованных сетей прямо в RTL. Лучший вариант для «сеть = железо».</li>
<li><b>hls4ml</b> (CERN) — компиляция моделей Keras/PyTorch в HLS, популярен в физике, отличная документация.</li>
<li><b>NVDLA</b> (NVIDIA, open source) — открытый ускоритель глубокого обучения, куда можно расти по сложности.</li>
<li><b>Vitis AI + DPU</b> — «заводской» путь от AMD: обучил ONNX → квантовал → запустил на DPU (Kria/ZCU), почти без HDL.</li>
</ul>
<h2>5. Рекомендация для старта</h2>
<div class="card">
<ol>
<li>Взять <b>Kria KV260</b> (~$250) — готовый AI-стек из коробки.</li>
<li>Прогнать туториал <b>Vitis AI</b>: ONNX-модель → INT8-квантование → инференс на DPU за вечер.</li>
<li>Второй проход — <b>hls4ml</b> с маленькой моделью, чтобы почувствовать кастомный путь.</li>
<li>Параллельно — поэкспериментировать, как <b>LLM генерирует HDL</b> для простого блока (это к идее Андрея).</li>
</ol>
<p class="lead">Итого: старт ≈ $250, первый работающий инференс — в первый вечер, дальше оттачиваем сценарии.</p>
</div>
<footer>
<i>Simbiot • кооператив 42</i> — если хочется глубже (бенчмарки точности после квантования, подбор модели под конкретную идею Андрея) — скажи, сделаю развёрнутый разбор.
</footer>
</div>
</body>
</html>

View file

@ -23,7 +23,9 @@ _RAG_SCRIPT = "/root/rag/rag.py"
# База по умолчанию: корпус кооператива (12.5k чанков) — то, что просил Алекс
# для мин-пульса; hermes.db (54k) — опцией RAG_DB для верхних уровней.
DEFAULT_DB = "/root/rag/rag.db"
# SIMBIOT_RAG_DB — для второго инстанса харнеса (агент со своей базой,
# t-261001124130: мигрирующий агент получает собственный RAG-индекс).
DEFAULT_DB = os.environ.get("SIMBIOT_RAG_DB", "/root/rag/rag.db")
# Лимиты на тик: 1 запрос, k<=5, таймаут 20с (эмбеддинг ~2.7с + запас)
MAX_K = 5

0
portal/portal.db Normal file
View file

View file

@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Отложенный рестарт main-симбиот-харнеса (typing-активация, e-261002202857).
# Рестарт убивает работающих LLM-воркеров (KillMode=cgroup), поэтому:
# ждём окно -- 15 подряд секунд без живых/зомби-воркеров _llm_worker
# и без свежих (< 15с) result-файлов тиков /tmp/simbiot_tick_*.json
# (свежий файл = только что завершившийся тик, у него хвост-постоб<D0BE>отка).
# Окна нет за дедлайн — выходим БЕЗ рестарта (тик жив, повтор через час).
set -u
DEADLINE=$(( $(date +%s) + 150 ))
is_quiet() {
NOW=$(date +%s)
for p in $(pgrep -f 'harness/_llm_worker.py' 2>/dev/null); do
[ -r "/proc/$p/stat" ] || continue
st=$(awk '{print $3}' "/proc/$p/stat" 2>/dev/null)
[ "$st" = "Z" ] && return 1 # живой или зомби-воркер = тик активен
done
for f in /tmp/simbiot_tick_*.json; do
[ -f "$f" ] || continue
mt=$(stat -c %Y "$f" 2>/dev/null || echo 0)
[ $((NOW - mt)) -lt 15 ] && return 1 # хвост-постоботка только что завершившегося тика
done
return 0
}
CLEAN=0
while [ "$(date +%s)" -lt "$DEADLINE" ]; do
if is_quiet; then
CLEAN=$((CLEAN + 1))
if [ "$CLEAN" -ge 5 ]; then
echo "окно найдено ($(date '+%H:%M:%S')) — рестарт simbiot-harness"
systemctl restart simbiot-harness.service
exit 0
fi
sleep 3
else
CLEAN=0
sleep 10
fi
done
echo "окно не найдено за дедлайн — рестарт прерван (тик работает, повтор через час)"
exit 0

View file

@ -122,6 +122,46 @@ cd "$INSTALL_DIR"
exec ./venv/bin/python cli.py "\$@"
EOF
chmod +x "$BIN_DIR/simbiot"
# 3a. In-repo обёртка bin/simbiot: запуск «simbiot» без установки в ~/.local/bin
# (Alex: харнес, ставящийся баш-командой, должен запускаться и просто
# словом simbiot — из корня репо это ./bin/simbiot).
mkdir -p "$INSTALL_DIR/bin"
cat > "$INSTALL_DIR/bin/simbiot" <<'EOF'
#!/usr/bin/env bash
# Simbiot Harness: запуск без установки обёртки (cli.py + scheduler-демон).
# simbiot help — справка по CLI-командам (как python cli.py -h)
# simbiot — без аргументов: статус + как управлять демоном/CLI
DIR="$(cd "$(dirname "$(readlink -f "$0")")/.." && pwd)"
unset PYTHONPATH
unset PYTHONHOME
cd "$DIR" || exit 1
PY="$DIR/venv/bin/python"
[ -x "$PY" ] || PY="$(command -v python3)"
_flag=0
for a in "$@"; do
case "$a" in
help|--help) _flag=1 ;;
esac
done
if [ "${_flag}" = 1 ]; then
exec "$PY" cli.py -h
fi
if [ $# -eq 0 ]; then
echo "Simbiot Harness CLI — venv: $PY, репо: $DIR"
if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet simbiot-harness; then
echo "Демон : active (systemctl status simbiot-harness)"
elif pgrep -f "harness.scheduler" >/dev/null; then
echo "Демон : жив (pgrep harness.scheduler)"
else
echo "Демон : не запущен — $DIR/venv/bin/python -m harness.scheduler"
fi
echo "Быстрые команды: simbiot status | simbiot wizard | simbiot help"
exit 0
fi
exec "$PY" cli.py "$@"
EOF
chmod +x "$INSTALL_DIR/bin/simbiot"
# PATH: если ~/.local/bin не подхватился (WSL/мак/кастомный профиль) — после
# установки будет «simbiot: команда не найдена» до перелогина. Добавляем и в
# текущую сессию, и в rc-файл, и говорим как перечитать.