---
name: prtv-agent-rules
description: Дисциплина ИИ-агента в браузере (Claude в Chrome, computer use, Playwright, Codex, Cursor), который собирает меню-борды или слайд-шоу в конструкторе вывесок PRTV (prtv.pro) — без циклов скриншотов (лимит 2000 px), чтение DOM вместо этого, вычисление координат клика, что сохраняется (правки только через интерфейс), проверка перезагрузкой и предпросмотром, очистка вывода с адресами, ловушки изолированного мира и вкладок у JavaScript-инструментов, элементы только при наведении, активация слайда, тайминг создания элементов, дубли постоянных элементов, адреса виджетов вручную, темп длинной сессии. Загружать в начале любой автоматизированной сессии в prtv.pro, до первого клика. Triggers (EN) browser agent, PRTV automation, AI builds slideshow.
license: CC-BY-4.0
metadata:
  author: PRTV (prtv.pro)
  product: Конструктор цифровых вывесок PRTV (prtv.pro)
  version: "1.1"
  date: "2026-09-26"
  language: ru
  scope: интерфейс редактора + чтение состояния страницы из DOM; без вызовов внутреннего API
---

# Правила браузерного агента в конструкторе PRTV

За эти правила заплачено сорванными сессиями. Они относятся к любому агенту, который управляет редактором через браузер — Claude in Chrome, агенты на Playwright и подобные. Карта редактора — в prtv-editor-overview; остальные скиллы prtv-* описывают объекты. Этот — о том, как себя вести.

## 1. Ноль скриншотов

**Правило ноль: без скриншотов за прогон.** API изображений у агентов отвергают запрос, когда в контексте много картинок и хотя бы одна крупнее **2000 px по стороне**; полностраничный скриншот высокого редактора всегда крупнее. Прогоны с более чем пятью скриншотами зависают или обрываются.

Заменять скриншоты:

- **Чтением страницы** (интерактивные элементы или весь DOM текстом).
- **Инспекцией через JavaScript** — `document.querySelectorAll`, `getBoundingClientRect`, `getComputedStyle`, id элементов и слайдов, локальное хранилище только для чтения (prtv-editor-overview §4).
- **Сообщениями консоли** — чтобы прочитать результат скрипта.

Если картинка неизбежна: только видимая область, никогда не вся страница; не больше примерно десяти за сессию, по одной в конце логического блока (слайд готов, правка принята), а не после каждого клика; высокую страницу — двумя-тремя кадрами вьюпорта; окно браузера держать 1920×1080 или меньше, чтобы кадры укладывались в лимит. Отчитываться текстом — таблицами правок, статусами, измерениями — а картинки оставлять для финального результата.

Скриншот всё равно не показывает движение. Анимация и ротация проверяются в предпросмотре или перемоткой `getAnimations()` (prtv-html-block-animation).

## 2. Координаты считаются, а не смотрятся

Сосуществуют три масштаба: внутреннее пространство слайда 1920×1080, CSS-пиксели страницы и пиксели скриншота. Координата клика, снятая на глаз со скриншота, попадает не туда, и промах выглядит как «редактор не реагирует».

- Слайд → страница: масштаб и смещение снять с любого абсолютного элемента холста (prtv-editor-overview §3): `страница = смещение + масштаб × слайд`. Линейно — посчитать один раз, переиспользовать, пересчитывать после любого изменения размера окна.
- Страница → инструмент: если инструмент кликает в пикселях скриншота, коэффициент — `ширина_скриншота / window.innerWidth`; измерить один раз, а не предполагать.
- Кнопки тулбара и панели: их координаты брать из `getBoundingClientRect()` кнопки, а не с картинки. Внутри одного элемента они стабильны, между элементами сдвигаются.
- Левая панель высотой около 1500 px — поля могут быть ниже окна; прокрутить её (`document.querySelector('.lefmenu').scrollTop = 1e6`), прежде чем искать поле.

## 3. Читать всё, писать только через интерфейс

Редактор хранит состояние в собственной клиентской модели и перерисовывает страницу из неё. **Изменение, записанное скриптом прямо в DOM, выглядит применённым и исчезает при следующей перерисовке или перезагрузке.** На одной живой сессии это стоило двух полных проходов по шрифтам меню.

Что сохраняется: реальный ввод мышью и клавиатурой, команды тулбара и значение, записанное в поле панели через нативный сеттер поля с последующими событиями `input` и `change` (поле должно быть настоящим полем интерфейса — фрагмент в prtv-html-block-animation). Отправка `change` или `blur` на поле формы не сохраняет — набрать значение, затем Tab или клик мимо (реальная потеря фокуса).

Внутренние методы, которыми редактор общается со своим сервером, в этот набор скиллов не входят и не вызываются; попытки возвращают «access denied» и в любом случае обходили бы защиту интерфейса. Всё делается так, как сделал бы человек.

**Проверять перезагрузкой.** Сохранено то, что пережило перезагрузку страницы; больше ничего. Undo живёт только в пределах сессии страницы; истории версий нет.

## 4. Ловушки JavaScript-инструментов

- **Изолированный контекст.** Скрипты инструмента выполняются в изолированном мире: глобальные объекты страницы доступны как `window.<имя>`; голое имя может быть `undefined` на полностью загруженной странице. Часть вспомогательных полей коллекций страницы (`_docs._map`) оттуда может быть не видна — использовать `.find().fetch()` у коллекции.
- **Промисы не ожидаются.** Асинхронный скрипт возвращает `{}`. Приём: запустить работу и сложить результат в `window.__r`, затем прочитать `JSON.stringify(window.__r)` вторым, синхронным вызовом.
- **`window.__*` — у каждой вкладки свой.** Значение, собранное в одной вкладке (конструктор информера), не существует в другой (редактор). Iframe, собранный из неопределённой переменной, получает `src="undefined"`, браузер разрешает его относительно prtv.pro, и на холсте появляется плашка «404 слайд-шоу не найдено». Собирать URL и HTML в той же вкладке, где создаётся элемент, или вставлять литералами; после установки HTML проверять на `src="undefined"`.
- **Санитизация вывода.** Инструмент может отказаться вернуть строку с URL, содержащими query-параметры, или с data-URL, сообщив «cookie / query string data» — ложное срабатывание. Не выгружать HTML или текст элемента целиком. Возвращать метаданные (длину, наличие подстроки, число узлов), резать URL по `?` или оборачивать результат в `JSON.stringify`. Убирать URL из любого текста, который возвращается человеку.
- **Проверка через fetch.** Собранную вручную ссылку информера проверять `fetch(url).then(r => r.ok)` до вставки в блок.

## 5. Привычки интерфейса, ломающие автоматизацию

- **Кнопки только по наведению.** Четыре кнопки миниатюры слайда и кнопки «Выбрать» у полей картинок появляются только при **реальном наведении курсора**; отправленный `mouseenter` ничего не даёт. Физически подвести указатель, затем кликнуть.
- **Полоса слайдов — опасная зона.** Не кликать рядом с ней без цели — там кнопка удаления слайда, удаляющая без подтверждения. Не начинать драг по миниатюре, если не переставляете; незавершённый драг оставляет миниатюру сдвинутой (восстановление: `document.querySelectorAll('[data-slide-id]').forEach(el => el.style.transform = '')`).
- **Снять выделение** — кликом по пустой области холста слева от слайда. Escape ненадёжен.
- **«Назад» в панели элемента** выводит из редактора в список слайд-шоу — это не «шаг назад». Из настроек слайда возвращает к списку элементов.
- **Вход в правку текста** занимает 2–5 попыток (клик, двойной клик); после каждой проверять `[contenteditable="true"]` и никогда не давать серии двойных кликов вслепую — лишний клик становится драгом и уносит элемент за пределы слайда. См. prtv-text-element.
- **Дубли элементов создаются легко**: кнопка левой панели добавляет элемент мгновенно, без диалога. Считать `[id^="slide-element-"]` до и после клика.
- **Правый клик по холсту** открывает умолчания слайд-шоу, а не настройки активного слайда.

## 6. Активация слайда и тайминг элементов

- **Активировать слайд** = наведение + клик по его миниатюре. Смена URL или истории браузера не переключает модель, в которую пишут кнопки левой панели; элемент может уйти на прежний активный слайд. После переключения подтвердить по DOM, какой узел слайда на холсте; в сомнении добавить пробный элемент, посмотреть, в миниатюре какого слайда он появился, и удалить.
- **Холст может показывать элементы соседних слайдов** — артефакт превью, не данные. Принадлежность элемента слайду подтверждать по миниатюрам (те же id) или по хранилищу.
- **Новый элемент меняет id.** Сразу после клика элемент существует под временным id; через несколько секунд его заменяет серверный. Сначала создать все нужные пустые элементы, подождать 10–15 с, затем найти их заново по геометрии по умолчанию (новый текст стоит в 0,0 с размером 500×120) и только потом править.
- **Дублирование слайда копирует и постоянные элементы**, поэтому дубль слайда несёт вторые логотип, часы или видео с пометкой «на всех слайдах» — задвоенные на каждом слайде. Для чистого нового слайда использовать кнопку **добавить слайд** у полосы; постоянные элементы появятся на нём сами. Если дубли уже созданы — удалить лишние элементы или продублированный слайд.
- В блоке «Общие настройки» панели элемента два связанных контрола — «Постоянный элемент» (Нет/Да) и тумблер «На всех слайдах» — плюс «Позиция» (селект; «Под всеми» = нижний слой) и «Глубина» (число). Читать их из панели, а не из предположений.

## 7. Информеры из конструкторов

Публичные конструкторы на s.prtv.su часто не читают значения, вписанные в их поля скриптом — сгенерированный код выходит с умолчаниями (кроме прозрачности). Собирать ссылку информера **вручную** по справочнику параметров prtv-widgets-catalog, цвета кодировать как `%23…`, текст — через `encodeURIComponent`, проверять `fetch`, оборачивать в стандартный `<iframe>` и вставлять в HTML-блок во вкладке редактора. Результат проверять на публичной странице ТВ, а не в миниатюрах.

## 8. Приёмка

1. **Предпросмотр** (кнопка «глаз») — эталон. Ждать не меньше полной длительности каждого слайда.
2. **Публичная страница** `https://prtv.pro/<номер ТВ>` (`?tv=true` показывает её как телевизор) — вторичная проверка. В момент перехода `body.innerText` ненадолго пуст — опрашивать несколько раз. Тяжёлые встраивания (видеоплееры, iframe информеров) могут монтироваться с задержкой — артефакт вьюера; проверять вживую на весь экран. Десктопный вьюер может надолго стоять на первом слайде при правильных данных.
3. **Перезагрузить редактор** и перечитать элемент.
4. **Водяной знак**: `img[alt="watermark"]` на публичной странице означает, что к слайд-шоу не привязан ТВ-слот.
5. Раскладка принимается глазами, а не отсутствием ошибок: переносы, обрезки, пропавшие фоны и незагруженные шрифты находятся взглядом (prtv-element-layout §7).

## 9. Темп сессии

- Дробить длинные задачи: после примерно 100–150 шагов или при заметном замедлении инструмента завершить блок, отчитаться текстом и продолжить в новой сессии с коротким контекстом.
- Один логический блок — один отчёт: что изменено, где, как проверено.
- Никогда не «докручивать» зависшую сессию — начинать новую.
- Вести список созданных id, чтобы новая сессия их нашла.

## Чего не делать

- Не снимать скриншоты, чтобы понять, куда кликать.
- Не править DOM и не считать это сохранённым.
- Не вызывать внутренние методы редактора.
- Не отправлять синтетические hover, change и blur в расчёте на реакцию интерфейса.
- Не собирать ссылку информера в одной вкладке, чтобы использовать в другой.
- Не дублировать слайд, на котором есть постоянные элементы.
- Не доверять id нового элемента первые пятнадцать секунд.
- Не кликать вокруг полосы слайдов.
- Не выгружать HTML элементов в вывод инструмента.
- Не тянуть сессию дальше момента, когда инструмент начал тормозить.

## Связанные скиллы

prtv-editor-overview · prtv-slide-settings · prtv-element-layout · prtv-text-element · prtv-html-block-animation · prtv-video · prtv-widgets · prtv-widgets-catalog
