Files
skills/skills/browser-operator/SKILL.md

10 KiB
Raw Blame History

name, author, version, description
name author version description
browser-operator ours 0.1.0 Работа в браузере ОПЕРАТОРА — его Chrome, его профиль, его живые логины: личные кабинеты поставщиков (ЧипДип, ДКО, Промэлектроника, ТМ), Avito, порталы под антиботом. Trigger: «зайди в личный кабинет», «открой ЛК», «собери заказы», «посмотри в браузере», «нужна его сессия», «ЧипДип/Ozon/Avito», «browser». НЕ для публичных страниц (там сначала обычный fetch/curl) и НЕ для анонимных прогонов (там скил browser-cdp).

Browser operator — браузер оператора

Браузер оператора — разделяемый ресурс с его живыми сессиями. Работай через готовый канал своего харнесса и только под арендой «один водитель за раз». Не вытаскивай его куки, не логинься сам, не поднимай свой Chrome.

Когда браузер действительно нужен

Сначала спроси себя, нужен ли браузер вообще:

  • Нет — публичная страница, API, доки: обычный fetch/curl/поиск. Браузер тут лишний.
  • Да — страница требует взаимодействия (клик/форма/навигация), JS-рендер, его логин (личный кабинет, Avito), либо портал режет не-браузерный трафик.

Канал по харнессу (не изобретай свой)

Харнесс Чем работать Аренда
Hermes тул browser_exec (демон browser-use, тот же профиль оператора) автоматически: shell-хук pre_tool_call берёт аренду и блокирует вызов при чужой
pi тул browser: open / read / js / click / screenshot / lease автоматически внутри тула; lease покажет, кто держит
Claude Code MCP chrome-devtools (list_pages, navigate_page, take_snapshot, evaluate_script, click, fill, take_screenshot) автоматически: обёртка берёт аренду перед стартом сервера

Никогда: curl с куками из его профиля, browser_cookie3-выгрузка куки, свой chrome --remote-debugging-port с пустым профилем (там нет его логинов), pip install-стек ради одного кабинета.

Аренда: «один водитель в браузере за раз»

Браузер один. Если его держит другой харнесс — не ломиться, сказать «занято, держит X» и вернуться позже (или попросить оператора освободить).

Идёшь в браузер в обход тула (например, скриптом или browser-use из терминала) — бери аренду сам:

BL="$HOME/.config/browser-harness/bin/browser-lease.sh"
HOLD="manual:$$"                                        # метка держателя
MYPID="$(cat /proc/$$/winpid 2>/dev/null || echo 0)"     # НАСТОЯЩИЙ windows-PID
bash "$BL" acquire --holder "$HOLD" --ttl 900 --pid "$MYPID" --tool browser   # 0 = взял, 3 = занято, 2 = ошибка
# … работа …
bash "$BL" release --holder "$HOLD"

PID — только настоящий. MSYS $$ это НЕ windows-PID: по нему живость аренды врёт (мёртвый держатель выглядит живым, живой — мёртвым). В bash бери /proc/$$/winpid, в pi/Node — process.pid; не знаешь — передай 0 («неизвестен», живость решит TTL).

driver.lock руками не трогай (в том числе пустой или «битый» — это окно чужой записи): отбор мёртвой аренды делает CLI по ts/TTL/мёртвому PID. Чужую аренду не снимай.

Контракт аренды (формат файла, TTL, кого связывать): вики mappa concepts/browser-lease-contract.

Как работать в страницах (рецепты)

  • Первым делом — своя вкладка. ensure_real_tab() / new_tab(url); не полагайся на активную вкладку оператора: тяжёлая или аудио-страница подвешивает демон (все вызовы падают в таймаут, хотя browser-use --doctor говорит «alive»).
  • Тяжёлые страницы — читать изнутри, а не обходом. Если у сайта есть внутренний JSON-эндпоинт, зови его fetch(path, {credentials:'include'}) из уже открытой страницы: это быстрее и надёжнее десятков навигаций.
  • По одной штуке за раз, с паузами. Паузы — в Python/процессе, не в JS await (иначе Runtime.evaluate timed out). Ориентир оператора: 1 запрос, пауза 713 с, перекур каждые ~40, стоп после 3 ошибок подряд.
  • Клики: сначала дерево доступности (Accessibility.getFullAXTree) или querySelector → центр элемента (getBoundingClientRect) → click_at_xyпроверь результат отдельным js(...)/page_info(). Не кликай «на глаз» по скриншоту.
  • Прогресс — сразу на диск (jsonl/atomic), а не в конце прогона: длинные обходы обрываются.
  • Долгие обходы — в фоновый процесс, а не в цикл интерактивных вызовов.

Границы: где человек, а где агент

  • Пароли и второй фактор — никогда. Не вводим и не просим в аргументах командной строки. Уже залогиненная сессия оператора — вот твой доступ.
  • Попап «Разрешить удалённую отладку?» — это человеческое подтверждение: агент его не жмёт, а просит оператора нажать «Разрешить» и повторяет попытку.
  • Деньги/платежи/отправка форм с персональными данными — только с явным подтверждением оператора.
  • Секреты и содержимое залогиненных страниц не пишем в логи, файлы репозитория и вики: в mappa — только агрегаты и идентификаторы.

Проверенные адреса и факты

  • ЧипДип, кабинет заказов: https://www.chipdip.ru/order/list (⚠️ /cabinet и /orders отдают 404 — не перебирай наугад, ссылка есть в шапке).
  • Залогиненность видна в шапке кабинета (имя оператора); если видишь форму логина — сессия потеряна: стоп и скажи оператору, не логинься сам.
  • about:blank-вкладка с титулом-лошадкой в document.title = страницу ведёт агент.

Так делать НЕ надо

Соблазн Почему нет
«Вытащу куки из Chrome и пойду curl'ом» мимо канала и мимо аренды; пароль/2FA оказываются рядом; ломается при смене защиты
«Подниму свой Chrome с отладкой» там нет его логинов → выкинет на логин/капчу, плюс это второй водитель
«Введу логин/пароль через read -s» пароли и 2FA не вводим никогда
«Проверю ещё пяток URL кабинета» адрес подтверждай по ссылке в интерфейсе, а не перебором
«Налью 20 запросов параллельно, быстрее» антибот + оператор останавливает такие прогоны; один водитель, одна очередь

Основание: базовый прогон без скила (2026-09-11) ушёл именно в «куки + curl + пароль» мимо канала; скил закрывает этот путь.

Красные флаги (стоп и перечитай)

  • Собираешься вытащить куки / поднять свой браузер / ввести пароль или код.
  • Работаешь с браузером без аренды (или ломишься, когда «занято»).
  • Полливаешь запросами без паузы или ждёшь паузу в JS.
  • Пишешь содержимое залогиненных страниц/секреты в файл, лог или вики.

Вне скоупа

  • Анонимные/антидетект-прогоны, свой профиль, mode: fresh — скил browser-cdp.
  • Облачные браузеры (Browser Use Cloud и прочие) — не берём.
  • Свой stdio-MCP-сервер поверх общего демона — отдельная тема.