- mods/WatchTogether/ убран (git rm), секция WatchTogether и плагин watchtogether.js убраны из config/init.conf - README: раздел и строка таблицы модулей убраны, модуль вернулся в список «ещё можно включить» - AGENT: §13 удалён, список mods/ в §1 обновлён
17 KiB
AGENT.md — инструкции для ИИ-агентов
Работа с проектом: локальный Docker-развёртывание Lampac NextGen. Человек читает ответы только на русском.
Источники правды (порядок приоритета)
- Официальная документация — docs.lampac.dev (полный текст страниц:
https://docs.lampac.dev/llms-full.txt, индекс:llms.txt). Не гадать по памяти — проверять в доках. - Живой контейнер — состояние модулей, манифестов и конфигов брать из контейнера:
docker exec lampac sh -c 'cat /lampac/module/<Имя>/manifest.json' docker exec lampac cat /lampac/current.conf # merged-конфиг: base + init - Логи контейнера —
docker logs lampac. - Локальные файлы проекта:
docker-compose.yaml,config/init.conf,mods/.
Ключевые правила
1. Никогда не правь файлы внутри контейнера/образа
Файлы в /lampac/module/ (и любые другие в образе) сгорают при обновлении (docker compose pull && up -d). Включение встроенного модуля делается только пользовательской копией:
docker cp lampac:/lampac/module/<Имя> "mods/<Имя>"
# в mods/<Имя>/manifest.json -> "enable": true
# в docker-compose.yaml -> "- ./mods/<Имя>:/lampac/mods/<Имя>"
# docker compose up -d
См. также официальные шаги: Включить модуль, Пользовательские модули.
Сейчас в mods/: AdminPanel, Tracks, Tg-notify.bot, TelegramAuth, TelegramAuthBot. mods/Music удалён (remote-коммит remove Music): в образе у Music manifest.enable: false, поэтому модуль не грузится, /music.js → 404, секция "Music" и плагин убраны из init.conf. mods/WatchTogether тоже удалён (вернуть — той же механикой, он в списке «ещё можно включить» в README).
2. Механика загрузки модуля (4 независимых фильтра)
Модуль грузится, только если выполнены все:
| Фильтр | Где |
|---|---|
"enable": true |
manifest.json модуля (копия в mods/ для встроенных) |
Имя не в BaseModule.SkipModules |
base.conf (в образе) + config/init.conf |
Имя попадает в BaseModule.LoadModules |
если allowlist задан (у нас не задан — грузится всё остальное) |
| Runtime-флаг | секция модуля в config/init.conf, например "gst": { "enable": true } |
SkipModules имеет приоритет над LoadModules — модуль из обоих списков не грузится. Паттерны: точное имя, группа (OnlineUKR), regex (LME.*), .*.
3. config/init.conf — валидный JSON
JSON без trailing comma. Перед применением правок проверять:
python3 -m json.tool config/init.conf > /dev/null && echo OK
После правки конфига: docker compose restart (том смонтирован, up -d не нужен). После правки manifest.json в mods/ с dynamic: true — тоже restart (или ждать hot-rebuild). После изменения томов в compose — docker compose up -d.
4. Клиентские плагины Lampa
- Встроенные плагины: флаги
LampaWeb.initPlugins(tracks,dlna,catalog,sync,backup, ...). - Дополнительные:
LampaWeb.customPlugins— записи соstatus: 1добавляются как есть; поддерживается плейсхолдер{localhost}(подставляется реальный адрес сервера). - Если плагин «не виден» в веб-клиенте — сначала проверить HTTP-статус его URL на сервере (
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9118/<плагин>.js), а не лезть в клиент.
4.1 Каталог плагинов (store) /extensions
- Раздел «Плагины» веб-клиента грузит каталог с
/extensions(приLampaWeb.initPlugins.pirate_store: true). - Источник:
/lampac/module/LampaWeb/plugins/extensions.json— переопределён mount из./plugins/extensions.json. Править хост-файл, в контейнер не залезать. {localhost}в ссылках store сервер заменяет своим адресом при выдаче.- Статика:
/lampac/plugins/не раздаётся (проверено: файл → 404), кореньwwwroot— раздаётся. Все плагины каталога — локальный mirror в./plugins/, смонтирован одним directory-mount в/lampac/wwwroot/plugins/→ ссылки store{localhost}/plugins/<имя>.js. Не монтировать каталог целиком в кореньwwwroot— скроется веб-клиентlampa-main. - Обновление плагина: исходный URL — в
plugins/sources.json; скачать, перезаписать файл, перезапуск не нужен (статика). - При проверке скачанного плагина отличать: (а) реальный код, (б) лоадер
putScriptAsync(абсолютные URL — безопасен локально; host от currentScript — требуется патч, см. showy.js), (в) пустой stub/placeholder (мёртвый плагин, из каталога удалять). - Кеш-ловушка: ответ
/extensions(и других LampaWeb-маршрутов) кешируется на диск в/lampac/cache/static/<bucket>/<id>.json(named volumelampac_cache); кеш переживаетdocker compose restart. После правки store:docker exec lampac rm -rf /lampac/cache/static/59(bucket/extensions), перезапуск не нужен. ЗаголовокX-StatiCache-Status: HIT/MISSпоказывает состояние.
5. AdminPanel API из скриптов (root-авторизация)
- Root-пароль = содержимое
config/passwd. Механизм: cookieaccspasswd=<пароль>(таков штатный сценарий: страница входаauth.htmlсама кладёт пароль в эту cookie). Заголовокlcrqpasswd— для внутренних вызовов, на/adminpanel/api/*с ним уходит 302 на/adminpanel/auth. - Не передавать root-пароль в query string (предупреждение доков).
- Сервер может отвечать 404 вместо 401/403, чтобы не раскрывать админский endpoint.
- Основные маршруты:
GET /adminpanel/api/init(чтение),POST /adminpanel/api/init(полная запись),POST /adminpanel/api/init/section/{key}(секция),GET /adminpanel/api/current(merged-конфиг),GET /adminpanel/api/users-json. - Правка секций через API пишется в
init.conf— watcher подхватит без рестарта (runtime-параметры).customPlugins— runtime-параметр: плагин появляется в/lampainit.jsчерез ~1 с.
6. Диагностика «модуль не найден»
Чек-лист (в этом порядке):
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9118/<маршрут>— 404 подтверждает, что модуль не загружен.docker logs lampac | grep -E "compilation|loaded module" | grep <Имя>— скомпилирован ли и загружен ли.- Манифест:
enable: true? (вmods/для встроенных) - Фильтры
SkipModules/LoadModulesвconfig/init.conf. - Runtime-секция модуля в
config/init.conf. - В логе после старта ожидаются строки
compilation <Имя>,configure module: <Имя>(если есть конфиг-секция),loaded module: <Имя>.
7. Команды эксплуатации
docker compose up -d # запуск / пересоздание (при изменении compose)
docker compose restart # после правки init.conf / mods
docker compose logs -f # логи
docker compose pull && docker compose up -d # обновление (сначала поменять тег в compose)
docker exec lampac sh -c '...' # осмотр состояния в контейнере
container_name: lampac — контейнер один; одновременный запуск нескольких compose-файлов с одним именем невозможен. docker-compose.override.yml (gitignore) живёт только на сервере Proxmox и не коммитится.
8. Чего не трогать
config/passwd,dlna/— в .gitignore, не коммитить.cache/database— named Docker volumes (lampac_cache,lampac_database), в git не попадают. Ловушка.gitignore: паттерны без якоря (cache/) матчат каталоги на любой глубине и без учёта регистра — из-за этогоmods/Music/Services/Cache/не попадал в git и ломала Roslyn-компицию на сервере (CS0103, crash-loop). Новые данные/каталоги проверять черезgit status/git check-ignore -v.- В named volume данные принадлежат тому, кто их туда положил: после миграции/копии
chown -R 1000:1000(процесс в контейнере —lampac:1000), иначе SQLite «attempt to write a readonly database». Исключение:cache/static/(в volumelampac_cache) — одноразовый диск-кеш ответов LampaWeb; очистка (docker exec lampac rm -rf /lampac/cache/static/<bucket>) — штатное действие после правки store/статических маршрутов (см. 4.1). - Тег образа в
docker-compose.yamlзакреплён точным digest (1.68.0@sha256:752dafd8…): тег 1.68.0 на ghcr mutable, его переиздавали, и новая сборка ломает Roslyn-компиляцию наших копийmods/(пример:Music→CS0103 MusicMetadataCacheService, crash-loop). Обновление образа = новый digest + пересборка копийmods/из нового образа. Не делать «просто»docker compose pullбез фиксации digest. LampaWeb.autoupdate— веб-клиент Lampa сам обновляется из git (yumata/lampa),wwwroot/lampa-mainв контейнере перезаписывается — туда не править.
9. После изменений в проекте
Обновлять README.md и AGENT.md в той же ревизии: структура, включённые модули, секции конфига, новые правила.
10. Безопасность (не публиковать)
config/passwd, cookie accspasswd, заголовок lcrqpasswd, bot_token в TelegramBot, bot_token в TelegramAuthBot, mutations_api_secret. Маршруты /adminpanel, /weblog, Tracks, Catalog, DLNA, proxy-модули — только для доверенной сети без WAF не открывать.
Секреты в git не попадают: в закоммиченном config/init.conf токены и секрет должны быть пустыми (так делает и remote — коммит remove), реальные значения живут только в рабочем файле на сервере (копия до мержа — /root/init.conf.local). Перед git add config/init.conf: git diff config/init.conf | grep -E ":[0-9]{8,}:AA|\"mutations_api_secret\": \"[a-f0-9]{16}" → должно быть пусто.
11. Tg-notify.bot (Telegram-бот)
- Механика: long polling по
TelegramBot.bot_token; если токен пуст — polling не стартует (в логе[TelegramBot] Установите bot_token…, сервер работает). После правки секции:docker compose restart lampac. - Токен только локально: в git поле пустое (правило 10). На сервере в
init.confвставлен@KlinkerZabbixBot— послеgit pull/переписывания конфига проверять, что polling снова стартовал ([TelegramBot] @KlinkerZabbixBot запущен!). Второй экземпляр на том же токене даётConflict: terminated by other getUpdates request. - Три подсистемы: трекер серий (Trakt→TMDB), трекер озвучек (параллельно Mirage/Collaps/VideoHub через
lampac_host:/lite/mirage,/lite/collaps,/lite/cdnvideohub), клиентский плагинtg-notify.js(вкладка «TG Подписки», перехват 🔔). Полный разбор — в README.md. - Данные подписок:
database/tgnotify/{users.json,subscriptions.json}(том./database/, в .gitignore). Не «чинить» вручную — это живые данные бота. - Диагностика:
GET /tg-notify.js(200 без авторизации),GET /api/tg/voices(200),/api/tg/*остальной — требуетuser_uid. Озвучки могут не работать, если балансеры недоступны (проверитьGET /lite/mirage— телоdisable/ошибка,/lite/collaps— 503); тогда уведомления приходят только о выходе серий. kp_api_keyопционален: без него VideoHub резолвитkinopoisk_idтолько через мост/externalids(покрытие ~40%), иначе — молча пропускается, Mirage/Collaps работают.
12. TelegramAuth / TelegramAuthBot (вход через Telegram)
- Не путать с Tg-notify.bot (уведомления): эта пара — аутентификация (вход в Lampa через Telegram вместо пароля), группа Community. Копии в
mods/TelegramAuth/иmods/TelegramAuthBot/, манифестыenable: true, изSkipModulesубраны (у насSkipModules: []). - Сейчас: API-режим.
TelegramAuth.enable: false→accsdbне поднимается, гейт неактивен, доступ не режется; работают привязки,/tg/auth/*, админ-API.TelegramAuthBot— бот@GatusMonBot, long polling идёт (Telegram API OK). - Гейт (
LampaWeb.telegramAuthGate) активен только приaccsdb.enable: true+telegramAuthGate.enabled: true+ непустомbotUsername, иначе тихий откат наdeny.js. Включать только вместе сaccsdb, и сначала связать свои устройства через бота — иначе текущие UID получат отказ. mutations_api_secretодинаковый в обоих модулях, ненулевой;bot_token— вinit.conf, не коммитить (правило 10): в git оба поля пустые.owner_telegram_ids: [143672]→ владелец создаётся какadminпри старте.auto_provision_users: true+auto_provision_activate_immediately: false→ новые привязки ждут одобрения (/usersв боте, кнопки Принять/Отклонить).- Данные:
database/tgauth/{users.json,admins.json,user_langs.json}(томlampac_database, владелец1000:1000). Живые данные — не «чинить» руками. - Проверка:
GET /tg/auth/status?uid=x→ 200;GET /tg/auth/admin/users→ 401 без заголовка, 200 сX-TelegramAuth-Mutations-Secret.