diff --git a/family/how-to/tv-lampac-plugin.md b/family/how-to/tv-lampac-plugin.md
index bf72fdc4..05fd2ef5 100644
--- a/family/how-to/tv-lampac-plugin.md
+++ b/family/how-to/tv-lampac-plugin.md
@@ -47,21 +47,102 @@ Lampa в webOS использует `localStorage`, который Chromium хр
2. Записать значение в localStorage
3. Запустить приложение
-## 🔴 НЕ СУЩЕСТВУЕТ пункта «Настройки → Источник» (проверено 2026-09-22)
+## 🔴 Пункта «Настройки → Источник» НЕ СУЩЕСТВУЕТ (проверено 2026-09-22)
**Не повторять эту ошибку — Alex дважды сказал, что пункта нет.**
+Я его выдумал, отвечая «как увидеть списки». Правильный путь ниже — **и он не сработает,
+пока не исправлен баг `plugin.js`** (см. следующий раздел).
В Lampa **нет** отдельного пункта меню для выбора источника каталога. Источник переключается
**прямо из меню каталогов на главной**:
1. Открыть Lampa на главной странице
2. Встать на любой ряд каталога и нажать **влево** на пульте
-3. Слева выедет **панель со списком источников** (Rezka, Kinobase, FilmixApp, VoKino,
- Eneyida, KinoUkr, «Мой список», …)
+3. Слева выедет **панель со списком источников**
4. Выбрать **«Мой список»** и нажать OK
5. Каталог перестроится на watchlist
-Скриншота/подтверждения от Alex ещё нет — он не дошёл до этого шага.
+🔴 **НО:** UI Lampa строит этот список через `Object.keys(Lampa.Api.sources)`.
+Плагин Lampac регистрирует источник **не-enumerable** → в панели его **нет**.
+Alex именно это и увидел: «Ни на главной ни в Фильмах нет».
+
+## 🔴 БАГ: источник не виден в панели (`enumerable: false`)
+
+**Найдено 2026-09-22** диагностикой через Chrome DevTools ТВ (см. раздел ниже).
+
+Факты с живого ТВ:
+
+| Замер | Значение | Смысл |
+|---|---|---|
+| `Lampa.Storage.field('source')` | `'Мой список'` | источник **уже выбран** |
+| `Object.keys(Lampa.Api.sources)` | `'tmdb|cub'` | ❌ источника нет в перечислении |
+| `Lampa.Api.sources['Мой список'].getCatalog()` | `search, movie, cartoons, anime, menu, main` | ✅ каталог доступен напрямую |
+| `Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')` | `{"enumerable":false,"configurable":false}` | ← **корень** |
+
+Причина в `/lampac/module/Catalog/plugin.js`, строка 59 (`loadCatalogs()`, **два вхождения**):
+
+```js
+// БЫЛО (баг)
+Object.defineProperty(Lampa.Api.sources, key, { get: function(){ return Api; } });
+
+// НАДО
+Object.defineProperty(Lampa.Api.sources, key,
+ { get: function(){ return Api; }, enumerable: true, configurable: true });
+```
+
+**`plugin.js` живёт в ОБРАЗЕ, не на HDD** (`docker inspect` показывает монтирования только
+на `catalog/sites` и `catalog/override`). Правка через `docker exec` исчезнет при обновлении.
+
+Фикс — смонтировать поправленный файл через compose:
+`./catalog/plugin.js:/lampac/module/Catalog/plugin.js:ro`.
+Полные команды и откат — [[personal/plans/lampac-watchlist-plugin]], раздел «ГЛАВНЫЙ ПИТФОЛЛ».
+
+**Статус: фикс НЕ применён, ждёт апрува Alex (2026-09-22).**
+
+## 🛠 Диагностика ТВ через Chrome DevTools (главный инструмент, найден 2026-09-22)
+
+**Ключевое открытие: webOS отдаёт Chrome DevTools Protocol на порту 9998.**
+У процессов `WebAppMgr` в аргументах есть `--remote-debugging-port=9998`.
+Это даёт **чтение состояния живой Lampa** — то, чего не дают ни логи, ни tcpdump.
+
+```bash
+# 1. Список отлаживаемых страниц + URL приложения
+curl -s --max-time 8 "http://192.168.1.70:9998/json" | /usr/bin/jq -r '.[] | "\(.type): \(.url)"'
+
+# 2. Проверка сети до Lampac (на ТВ!)
+ssh root@192.168.1.70 'curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" \
+ --max-time 8 http://192.168.1.14:9118/catalog'
+
+# 3. Живые соединения с Lampac (смотреть на ТВ, НЕ на сервере)
+ssh root@192.168.1.70 'netstat -tn 2>/dev/null | grep 9118'
+
+# 4. Что запущено сейчас
+ssh root@192.168.1.70 'script -q -c "luna-send -n 1 -f \
+ luna://com.webos.applicationManager/getForegroundAppInfo {}" /dev/null'
+
+# 5. Перезапустить приложение (JSON экранирован И обёрнут в двойные кавычки!)
+ssh root@192.168.1.70 'script -q -c "luna-send -n 1 -f \
+ luna://com.webos.applicationManager/launch \"{\\\"id\\\":\\\"com.lampac.tv\\\"}\"" /dev/null'
+```
+
+Чтение переменных Lampa — через `websocket-client` + `Runtime.evaluate`:
+готовые скрипты `/tmp/lampa_probe.py` и `/tmp/lampa_probe3.py` (см. план).
+
+### Ловушки диагностики (проверено на живом ТВ)
+
+⚠️ **Момент замера.** `sudo ss -tn | grep :9118` на Кра́кене сразу после старта дал **0 соединений** —
+я сделал ложный вывод «ТВ не ходит на сервер». Через 30 с на ТВ:
+**1 ESTABLISHED + 6 TIME_WAIT** — всё работает. Смотреть соединения **на ТВ**, не на сервере.
+
+⚠️ **`launch` через luna требует экранированного JSON в кавычках.** Без кавычек —
+`errorCode: 2, invalid parameters` (молча падает). `getForegroundAppInfo {}` работает без кавычек.
+
+⚠️ **`tcpdump` на Кра́кене НЕТ.** Не ставили — DevTools-подход дал больше (состояние JS, а не пакеты).
+
+⚠️ **`luna://com.webos.service.capture/takeScreenShot` не существует** на этом ТВ
+(`Unknown method "takeScreenShot"`). Скриншот так не снять.
+
+⚠️ **Логи HTTP Lampac не ведёт** — `docker logs` не покажет запросы ТВ. Не искать там.
## Как плагин `catalog.js` регистрирует источник (механика)
@@ -74,7 +155,9 @@ Lampa.Utils.account(Manifest.api_host + '/catalog', function(json){
Manifest.catalogs = json; // все каталоги с сервера
keys.forEach(function(key){
Lampa.Params.values.source[key] = key; // регистрирует источник
- Lampa.Api.sources[key] = Api; // подменяет API
+ Object.defineProperty(Lampa.Api.sources, key, { // ← ЗДЕСЬ БАГ
+ get: function(){ return Api; } // нет enumerable:true
+ });
if (Manifest.catalogs[key].search)
Lampa.Search.addSource(Api.discovery(key)); // добавляет в поиск
});
@@ -83,6 +166,9 @@ Lampa.Utils.account(Manifest.api_host + '/catalog', function(json){
Lampa.Listener.follow('menu', ...)
```
+⚠️ Свойство ставится через `defineProperty` **без `enumerable: true`** → `Object.keys()` его
+не видит → источник не появляется в панели выбора (разбор бага — выше).
+
Отсюда следует:
- Отдельного переключателя в настройках нет **by design** — источник выбирается панелью слева.
- Плагин **подтягивает каталоги только при старте приложения**. Если добавить плагин и не
@@ -136,10 +222,19 @@ var plugins_add = [
(монтируется в `/lampac/init.conf:ro`). Искать там, а не по `lampac/init.conf`
— иначе получишь ложный «файл пропал».
-5. **После добавления плагина обязательно полный перезапуск Lampa** — иначе `/catalog`
- не запрашивается, и источник не появляется (соединений с `:9118` будет **ноль**).
+5. **После добавления плагина обязательно полный перезапуск Lampa** — каталоги регистрируются
+ только на старте. ⚠️ Но **не делай из «нуля соединений» вывод о поломке**: сразу после старта
+ соединений действительно 0, через ~30 с появляются. Смотреть **с ТВ** (`netstat -tn | grep 9118`).
-6. **Проще всего — через UI самого пульта**, если он доступен:
+6. **`plugin.js` лежит в ОБРАЗЕ, а не на HDD.** Монтируются только `catalog/sites` и
+ `catalog/override`. Правки `/lampac/module/Catalog/plugin.js` через `docker exec` **теряются
+ при обновлении образа** — нужен bind-mount через compose.
+
+7. **Не верить `Object.keys()` на слово — проверять `getOwnPropertyDescriptor`.** Свойство может
+ существовать (доступно напрямую) и при этом не быть enumerable. `Object.keys` вернёт список
+ без него, и это выглядит как «источника нет», хотя он есть.
+
+8. **Проще всего — через UI самого пульта**, если он доступен:
Lampa → Настройки → Плагины → добавить URL. Скрипт нужен, когда пульта нет.
## Что должно быть прописано для Lampac
@@ -158,8 +253,21 @@ var plugins_add = [
## Статус
-⚠️ **На 2026-09-22 не проверялось на живом ТВ.** Подключение каталога сделано через UI
-(или требуется сделать). Скрипт-автоматизация — заготовка на будущее.
+**Проверено на живом ТВ 2026-09-22** (диагностика через DevTools, порт 9998).
-Если понадобится — подход: `closeByAppId com.lampac.tv` → запись ключа в localStorage →
-`launch com.lampac.tv`. Учесть питфоллы 1–3.
+**Что установлено точно:**
+- ТВ достаёт Кра́кен (`/catalog` 200 за 0.26 с), Lampa ходит на сервер (ESTABLISHED).
+- Плагин `catalog.js` **добавлен**, `window.plugin_catalog = true`, `appready = true`.
+- `Storage.field('source')` = `'Мой список'` — источник **выбран**.
+- `Lampa.Api.sources['Мой список']` **существует** и отдаёт каталог
+ (`search, movie, cartoons, anime, menu, main`) — **пользоваться каталогом можно**.
+- ❌ В панели выбора источника его **нет** — `plugin.js` регистрирует свойство
+ без `enumerable: true`. **Баг в Lampac, не в нашей настройке.**
+
+**Осталось:** смонтировать поправленный `plugin.js` через compose (ждёт апрува Alex).
+Полный разбор — [[personal/plans/lampac-watchlist-plugin]], раздел «ГЛАВНЫЙ ПИТФОЛЛ».
+
+**Скрипт-автоматизация по-прежнему не создана.** Прямая запись в localStorage **не нужна**:
+проблема оказалась не в настройках Lampa, а в коде плагина. Если автоматизация понадобится —
+подход: `closeByAppId com.lampac.tv` → запись ключа в localStorage → `launch com.lampac.tv`
+(учесть питфоллы 1–3). Но сначала — фикс `plugin.js`.
diff --git a/personal/plans/lampac-watchlist-plugin.md b/personal/plans/lampac-watchlist-plugin.md
index a3ac4ee1..194239de 100644
--- a/personal/plans/lampac-watchlist-plugin.md
+++ b/personal/plans/lampac-watchlist-plugin.md
@@ -28,8 +28,10 @@ updated: '2026-09-22'
>
> **Итог одной строкой:** Lampac отдаёт `movies-watchlist.md` как каталог Lampa
> через модуль `Catalog` → 4 категории (360/33/3/7 позиций), автообновление кроном 02:30.
-> Работает на стороне сервера; на ТВ остаётся добавить плагин
-> `http://192.168.1.14:9118/catalog.js` и выбрать источник (см. «Что осталось на Alex»).
+> Серверная часть полностью рабочая. **Осталось одно:** в `plugin.js` Lampac баг
+> (`defineProperty` без `enumerable:true`) — из-за него источник «Мой список» не виден
+> в списке выбора Lampa на ТВ. Фикс готов, ждёт апрува Alex (2026-09-22).
+> См. «🔴 ГЛАВНЫЙ ПИТФОЛЛ».
## Задача
@@ -165,21 +167,35 @@ Cron: `30 2 * * *` → лог `~/logs/watchlist-catalog.log`.
Причина: `nightly` — рабочий боевой скрипт, его падение остановило бы весь пайплайн списка.
Отдельный cron падает изолированно.
-## Что осталось на Alex (единственное незакрытое)
+## Что осталось (единственное незакрытое)
-Добавить плагин на ТВ — **пультом**, 1 минута:
+**Не шаг Alex, а правка сервера.** Плагин на ТВ уже добавлен и **источник уже выбран**
+(`Storage.field('source') = 'Мой список'`). Проблема — баг в `plugin.js` Lampac
+(см. «🔴 ГЛАВНЫЙ ПИТФОЛЛ»): источник не виден в UI из-за `enumerable: false`.
-1. Lampa → **Настройки → Плагины** → добавить URL `http://192.168.1.14:9118/catalog.js`
-2. **Полностью перезапустить Lampa** (не сворачивать) — каталоги регистрируются только при старте
-3. На главной встать на ряд каталога и нажать **влево** → в выехавшей панели выбрать **«Мой список»**
+**Ждёт апрува Alex** (2026-09-22): смонтировать поправленный `plugin.js` через compose.
-🔴 **Пункта «Настройки → Источник» в Lampa НЕ СУЩЕСТВУЕТ** — я его выдумал, Alex дважды указал на ошибку.
-Источник переключается панелью слева в меню каталогов. Подробно: [[family/how-to/tv-lampac-plugin]].
+Путь на ТВ, который раньше писался («влево → панель → выбрать источник») — **не сработает**,
+пока баг не исправлен: в панели источника просто нет.
Приёмка = категории видны в UI Lampa, названия совпадают с `movies-watchlist.md`.
-Автоматизация этого шага по SSH **не проверялась** — см. [[family/how-to/tv-lampac-plugin]]
-(там заготовка подхода и питфоллы localStorage).
+## Диагностический скрипт для ТВ (`/tmp/lampa_probe.py`)
+
+Правки в UI Lampa по SSH напрямую не сделать, но **состояние читается** через DevTools:
+
+```python
+pages = json.load(urllib.request.urlopen("http://192.168.1.70:9998/json", timeout=8))
+target = next(p for p in pages if "com.lampac.tv" in p.get("url",""))
+ws = websocket.create_connection(target["webSocketDebuggerUrl"], timeout=10)
+# Runtime.evaluate:
+# Lampa.Storage.field('source')
+# Object.keys(Lampa.Api.sources).join('|')
+# Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')
+# Lampa.Api.sources['Мой список'].getCatalog()
+```
+
+Требует `pip3 install websocket-client` (стоит). См. [[family/how-to/tv-lampac-plugin]].
## Известные ограничения
@@ -207,13 +223,117 @@ Cron: `30 2 * * *` → лог `~/logs/watchlist-catalog.log`.
**НЕ проверено:**
-- ❌ **UI Lampa на ТВ** — Alex добавил плагин, но каталог в UI не увидел.
- Соединений ТВ → `:9118` на момент диагностики — **ноль**. Гипотеза: не сделан полный
- перезапуск Lampa (каталоги регистрируются только при старте) либо не выбран источник
- в панели слева. **Требуется подтверждение от Alex.**
+- ✅ **UI Lampa на ТВ — ПРИЧИНА НАЙДЕНА 2026-09-22** (см. ниже «🔴 ГЛАВНЫЙ ПИТФОЛЛ»).
+ Диагностика через Chrome DevTools ТВ (`http://192.168.1.70:9998/json`):
+ - ТВ **физически достаёт** Кра́кен — `curl` с ТВ отдаёт `/catalog` 200 за 0.26 с.
+ - Lampa **работает и ходит на сервер** — соединение `192.168.1.70 → 192.168.1.14:9118` ESTABLISHED.
+ - `Storage.field('source')` = **`'Мой список'`** — источник уже выбран!
+ - `Lampa.Api.sources['Мой список']` **существует** и отдаёт каталог
+ (`getCatalog()` → `search, search_lazy, movie, cartoons, anime, menu, main`).
+ - ❌ НО: `Object.keys(Lampa.Api.sources)` = `'tmdb|cub'` — **источника нет в перечислении**.
+ - Причина: `defineProperty(..., {get: ..., enumerable:false, configurable:false})`.
+ - **Диагноз: баг в `plugin.js` самого Lampac, а не в нашей настройке.** UI Lampa строит
+ список источников через `Object.keys()` — «Мой список» из него выпадает, поэтому в UI
+ источник не видно и выбрать его нельзя.
- ❌ Боевой прогон крона в 02:30 (скрипт отработал вручную успешно).
- ❌ Карточка/постеры в UI.
+## 🔴 ГЛАВНЫЙ ПИТФОЛЛ: источник не виден в UI Lampa (`enumerable: false`)
+
+**Симптом.** Alex: «Ни на главной ни в Фильмах нет! Там только Сейчас смотрят, рекомендуем итд».
+Плагин добавлен, серверная часть отдаёт всё корректно, а в UI источника нет.
+
+**Диагностика (по возрастанию точности):**
+
+1. `ssh kraken 'sudo ss -tn | grep ":9118"'` — сначала показал **0 соединений** (ложный вывод:
+ замер сделан в момент старта Lampa). Через 30 с на ТВ:
+ `netstat -tn | grep 9118` → **1 ESTABLISHED + 6 TIME_WAIT** — Lampa скачала все файлы.
+2. Foreground-приложение: `luna-send -n 1 -f luna://com.webos.applicationManager/getForegroundAppInfo {}`
+ → `com.lampac.tv`. Запускать надо `launch` с **экранированным JSON в кавычках**,
+ иначе `errorCode: 2 invalid parameters`.
+3. Доступ к отладчику ТВ: **`curl http://192.168.1.70:9998/json`** — webOS отдаёт Chrome
+ DevTools Protocol на порту 9998 (у `WebAppMgr` в аргументах `--remote-debugging-port=9998`).
+ Через `websocket` + `Runtime.evaluate` читаются переменные живой Lampa.
+4. Ключевой замер: `JSON.stringify(Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список'))`
+ → `{"enumerable":false,"configurable":false}`.
+
+**Корень.** В `/lampac/module/Catalog/plugin.js` (строка 59, `loadCatalogs()`, **два вхождения**):
+
+```js
+Object.defineProperty(Lampa.Api.sources, key, { get: function(){ return Api; } });
+```
+
+Свойство создаётся не-enumerable → `Object.keys()` его не видит → Lampa не рисует источник
+в панели выбора. При этом `Api.sources['Мой список']` доступен напрямую и каталог отдаёт.
+
+**Фикс** (одна правка, два вхождения):
+
+```js
+Object.defineProperty(Lampa.Api.sources, key,
+ { get: function(){ return Api; }, enumerable: true, configurable: true });
+```
+
+**Как применять — `plugin.js` живёт в образе, не на HDD!** (проверено:
+`docker inspect` не показывает монтирования на `module/Catalog`, монтируются только
+`catalog/sites` и `catalog/override`). Правка через `docker exec` **исчезнет при обновлении образа**.
+
+Предложенный путь (на апруве у Alex, 2026-09-22):
+
+```yaml
+# docker-compose.yml
+volumes:
+ - ./catalog/plugin.js:/lampac/module/Catalog/plugin.js:ro
+```
+
+```bash
+# 1. забрать, поправить локально (sed/grep по файлу не применять — только patch)
+ssh kraken 'docker exec lampac cat /lampac/module/Catalog/plugin.js' > /tmp/catalog-plugin.js
+# 2. бэкап
+cp /tmp/catalog-plugin.js /tmp/catalog-plugin.js.bak-$(date +%Y%m%d-%H%M%S)
+# 3. правка двух вхождений defineProperty → +enumerable:true,configurable:true
+# 4. проверка синтаксиса ПЕРЕД заливкой
+node --check /tmp/catalog-plugin.js
+# 5. на HDD, добавить volume, пересоздать
+scp /tmp/catalog-plugin.js kraken:/srv/.../lampac/catalog/plugin.js
+ssh kraken 'cd /srv/.../lampac && docker compose up -d'
+# 6. проверка на ТВ: Object.keys(Lampa.Api.sources) должен стать 'tmdb|cub|Мой список'
+```
+
+**Откат:** убрать строку volume из compose → `docker compose up -d`. Плюс бэкап файла в `/tmp`.
+
+**Статус: правка НЕ применена** — ждёт апрува Alex (2026-09-22).
+
+## Готовые команды диагностики ТВ (переиспользовать)
+
+```bash
+# 1. Что запущено на ТВ (luna-send пишет в tty → нужен script -q -c)
+ssh root@192.168.1.70 'script -q -c "luna-send -n 1 -f \
+ luna://com.webos.applicationManager/getForegroundAppInfo {}" /dev/null'
+
+# 2. Запустить приложение (JSON экранирован И обёрнут в кавычки)
+ssh root@192.168.1.70 'script -q -c "luna-send -n 1 -f \
+ luna://com.webos.applicationManager/launch \"{\\\"id\\\":\\\"com.lampac.tv\\\"}\"" /dev/null'
+
+# 3. Достаёт ли ТВ Кра́кен
+ssh root@192.168.1.70 'curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" \
+ --max-time 8 http://192.168.1.14:9118/catalog'
+
+# 4. Живые соединения с Lampac (на ТВ, не на сервере!)
+ssh root@192.168.1.70 'netstat -tn 2>/dev/null | grep 9118'
+
+# 5. DevTools-цель Lampa на ТВ
+curl -s --max-time 8 "http://192.168.1.70:9998/json" | /usr/bin/jq -r '.[] | "\(.type): \(.url)"'
+```
+
+Скрипты-пробы DevTools: `/tmp/lampa_probe.py` (состояние источника),
+`/tmp/lampa_probe3.py` (асинхронный вызов `menu()` каталога).
+
+⚠️ `tcpdump` на Кра́кене **нет** — для съёма трафика ставить не стали, использован
+DevTools-подход (дал больше: видно состояние JS, а не только пакеты).
+
+⚠️ `luna://com.webos.service.capture/takeScreenShot` на этом ТВ **не существует**
+(`Unknown method`) — скриншот так не снять.
+
## Файлы реализации (на HDD Кра́кена)
Корень: `/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/lampac/`
diff --git a/personal/tech/lampac-deployment.md b/personal/tech/lampac-deployment.md
index b641427a..77da9e62 100644
--- a/personal/tech/lampac-deployment.md
+++ b/personal/tech/lampac-deployment.md
@@ -359,6 +359,94 @@ ssh root@TV 'script -q -c "luna-send -n 1 -f luna://service/method {json}" /tmp/
Каталог watchlist работает через **модуль `Catalog`**, не через эту строку.
Не искать причину поломки в `plugins_add`.
+### 🔴 БАГ Lampac: источник не виден в панели (`enumerable: false`)
+
+**Найдено 2026-09-22** диагностикой через Chrome DevTools ТВ. Симптом Alex:
+«Ни на главной ни в Фильмах нет! Там только Сейчас смотрят, рекомендуем итд».
+
+**Факты с живого ТВ:**
+
+| Замер | Значение |
+|---|---|
+| `Lampa.Storage.field('source')` | `'Мой список'` — источник **уже выбран** |
+| `Object.keys(Lampa.Api.sources)` | `'tmdb|cub'` — ❌ источника нет в перечислении |
+| `Lampa.Api.sources['Мой список'].getCatalog()` | `search, movie, cartoons, anime, menu, main` — ✅ работает |
+| `Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')` | `{"enumerable":false,"configurable":false}` ← корень |
+
+**Корень — в `/lampac/module/Catalog/plugin.js`** (строка 59, `loadCatalogs()`, **два вхождения**):
+
+```js
+// БЫЛО (баг)
+Object.defineProperty(Lampa.Api.sources, key, { get: function(){ return Api; } });
+// НАДО
+Object.defineProperty(Lampa.Api.sources, key,
+ { get: function(){ return Api; }, enumerable: true, configurable: true });
+```
+
+Не-enumerable свойство не попадает в `Object.keys()` → Lampa не рисует источник в панели
+выбора. **Баг Lampac, не нашей настройки.**
+
+🔴 **`plugin.js` живёт в ОБРАЗЕ, не на HDD.** `docker inspect` показывает монтирования
+только на `catalog/sites` и `catalog/override`. Правка через `docker exec` **исчезнет
+при обновлении образа** — нужен bind-mount:
+
+```yaml
+# docker-compose.yml
+- ./catalog/plugin.js:/lampac/module/Catalog/plugin.js:ro
+```
+
+```bash
+ssh kraken 'docker exec lampac cat /lampac/module/Catalog/plugin.js' > /tmp/catalog-plugin.js
+cp /tmp/catalog-plugin.js /tmp/catalog-plugin.js.bak-$(date +%Y%m%d-%H%M%S)
+# правка двух вхождений defineProperty (только через patch, не sed)
+node --check /tmp/catalog-plugin.js # проверить синтаксис ДО заливки
+scp /tmp/catalog-plugin.js kraken:/srv/.../lampac/catalog/plugin.js
+ssh kraken 'cd /srv/.../lampac && docker compose up -d'
+```
+
+**Статус: фикс НЕ применён**, ждёт апрува Alex (2026-09-22).
+Полный разбор — [[personal/plans/lampac-watchlist-plugin]], раздел «ГЛАВНЫЙ ПИТФОЛЛ».
+
+### 🛠 Диагностика ТВ через Chrome DevTools — порт 9998
+
+**Главный инструмент для отладки UI Lampa.** webOS отдаёт Chrome DevTools Protocol:
+у процессов `WebAppMgr` есть `--remote-debugging-port=9998`. Даёт **чтение состояния
+живой Lampa** — ни логи, ни tcpdump этого не дают.
+
+```bash
+# цель отладки + URL приложения
+curl -s --max-time 8 "http://192.168.1.70:9998/json" | /usr/bin/jq -r '.[] | "\(.type): \(.url)"'
+# → page: file:///media/developer/apps/usr/palm/applications/com.lampac.tv/index.html?...
+```
+
+Чтение переменных — `websocket-client` + `Runtime.evaluate`:
+
+```python
+pages = json.load(urllib.request.urlopen("http://192.168.1.70:9998/json", timeout=8))
+target = next(p for p in pages if "com.lampac.tv" in p.get("url",""))
+ws = websocket.create_connection(target["webSocketDebuggerUrl"], timeout=10)
+# Runtime.evaluate: Lampa.Storage.field('source')
+# Object.keys(Lampa.Api.sources)
+# Object.getOwnPropertyDescriptor(Lampa.Api.sources,'Мой список')
+```
+
+Готовые скрипты: `/tmp/lampa_probe.py` (состояние источника),
+`/tmp/lampa_probe3.py` (асинхронный вызов `menu()` каталога).
+
+**Ловушки:**
+
+⚠️ **Замер соединений — на ТВ, не на сервере.** `sudo ss -tn | grep :9118` на Кра́кене
+сразу после старта Lampa даёт **0** (ложный вывод «не ходит»). Через ~30 с:
+`ssh root@192.168.1.70 'netstat -tn | grep 9118'` → **1 ESTABLISHED + 6 TIME_WAIT**.
+
+⚠️ **`launch` через luna требует экранированного JSON в двойных кавычках**, иначе
+`errorCode: 2, invalid parameters`. `getForegroundAppInfo {}` работает без кавычек.
+
+⚠️ **`tcpdump` на Кра́кене нет** — не ставили, DevTools дал больше.
+
+⚠️ **`luna://com.webos.service.capture/takeScreenShot` не существует** на этом ТВ
+(`Unknown method`) — скриншот так не снять.
+
### Диагностика «каталога нет в UI»
| Проверка | Команда | Норма |
@@ -366,13 +454,15 @@ ssh root@TV 'script -q -c "luna-send -n 1 -f luna://service/method {json}" /tmp/
| Плагин отдаётся | `curl -sI http://192.168.1.14:9118/catalog.js` | 200, ~32 КБ |
| Каталоги зарегистрированы | `curl -s http://192.168.1.14:9118/catalog \| jq 'keys'` | 7 ключей, «Мой список» есть |
| Данные отдаются | `curl -s "…/catalog/list?plugin=watchlist&cat=films" \| jq .total_pages` | 1 |
-| ТВ реально ходит | `ssh kraken 'sudo ss -tnp \| grep :9118'` | есть ESTABLISHED
**ноль = Lampa не запускалась заново** |
+| ТВ достаёт сервер | `ssh root@192.168.1.70 'curl -s -o /dev/null -w "%{http_code}" http://192.168.1.14:9118/catalog'` | 200 |
+| ТВ реально ходит | `ssh root@192.168.1.70 'netstat -tn \| grep 9118'` | ESTABLISHED
ноль = Lampa не стартовала |
+| Источник в списке | DevTools: `Object.keys(Lampa.Api.sources)` | **все** каталоги, вкл. «Мой список» |
-Порядок разбора: сначала `ss` (ходит ли ТВ вообще), потом `/catalog` (что отдаёт сервер),
-потом UI. Если ноль соединений — проблема не в сервере.
+Порядок разбора: сначала сеть с ТВ → потом `netstat` на ТВ → потом `/catalog` на сервере →
+потом DevTools (состояние JS). **Если источник есть в `Api.sources` напрямую, но нет в
+`Object.keys()` — это баг `enumerable` в `plugin.js`, а не проблема настроек.**
⚠️ `docker logs lampac` **HTTP-запросы не пишет** — по логам факт обращения ТВ не проверить.
-Использовать `ss`, а не логи.
## Внутреннее устройство Lampac (разведка 2026-09-22)