Metadata-Version: 2.5
Name: answer42
Version: 0.8.0
Summary: Answer42 — The Answer to Life, Universe, and 1C — UI Driver. MCP-powered 1C:Enterprise UI automation: click, fill, navigate, test, and introspect managed forms through the test-client API
Author: Marvin (AI Assistant), 42Clouds, and contributors
Author-email: "Kosolapov Stanislav (proDOOMman)" <prodoomman@gmail.com>
License: MIT
License-File: LICENSE
Keywords: 1c,1c-enterprise,mcp,test-client,ui-automation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.11
Requires-Dist: cryptography>=42.0
Requires-Dist: mcp<3,>=2.0.0
Requires-Dist: pydantic>=2.0
Requires-Dist: requests>=2.31
Requires-Dist: tzdata; sys_platform == 'win32'
Requires-Dist: websockets>=12.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Provides-Extra: docs
Requires-Dist: furo>=2024.8; extra == 'docs'
Requires-Dist: myst-parser<6,>=3; extra == 'docs'
Requires-Dist: sphinx<10,>=7.3; extra == 'docs'
Requires-Dist: sphinxcontrib-mermaid<3,>=1; extra == 'docs'
Provides-Extra: linux-window-control
Requires-Dist: python-xlib>=0.33; extra == 'linux-window-control'
Provides-Extra: screenshot
Requires-Dist: mss>=9.0.0; extra == 'screenshot'
Provides-Extra: window-control
Requires-Dist: python-xlib>=0.33; extra == 'window-control'
Provides-Extra: windows-window-control
Requires-Dist: pywin32>=306; extra == 'windows-window-control'
Description-Content-Type: text/markdown

# Answer42

![Answer42 logo](https://gitlab.com/platform42/answer42-mcp/-/raw/v0.2.4/docs/assets/answer42-logo.png)

**Answer42** — MCP-инструмент для интерактивного управления UI **1С:Предприятия** через клиент тестирования. Он позволяет AI-агенту открывать формы 1С, нажимать кнопки, заполнять поля, выбирать ссылки из форм выбора, работать с таблицами, динамическими списками и табличными документами.

> **The Answer to Life, Universe, and 1C — UI Driver**

Проект даёт AI-агенту четыре способности:

1. **Интерактивное управление UI 1С** — открыть форму, кликнуть кнопку, активировать поле, заполнить значение, выбрать строку, провести сценарий через `/TESTMANAGER` + `/TESTCLIENT`.
2. **Живые веб-страницы в HTML-полях** — читать и менять DOM страниц, которые рисуются скриптами (чаты, SPA), и видеть ошибки их консоли, на Windows- и Linux-клиентах 1С.
3. **Доказательная запись клиентского тестирования** — записывать аннотированные PDF-слайды с MCP method/request/response и скриншотами окна 1С.
4. **RAG-индекс метаданных** — локальный SQLite/FTS индекс конфигураций 1С (EDT, XML-выгрузка Конфигуратора, base + extensions), включая подсказки для `ui_tree` и dynamic-list settings.

## Быстрый старт

```bash
# Рекомендуется для обычной установки из PyPI
pipx install 'answer42[screenshot,linux-window-control]'

# Альтернатива без pipx
python3 -m venv .venv
. .venv/bin/activate
pip install 'answer42[screenshot,linux-window-control]'

# Разработка из git checkout
pip install -e '.[screenshot,dev,linux-window-control]'

# Windows: запускать из интерактивной пользовательской сессии, не как service
# pipx install "answer42[screenshot,windows-window-control]"
# pip install "answer42[screenshot,windows-window-control]"

# Запуск MCP-сервера (transport: stdio)
answer42 --ws-host 127.0.0.1 --ws-port 8765
```

Запуск сессии и подключение тестируемой базы выполняются одним MCP-вызовом:

```text
start_session(
  session_id="my-session",
  base_url="<TARGET_INFOBASE_URL>",
  idle_timeout_minutes=60,
  execute="/path/to/external.epf",  # опционально: /Execute
  command_parameter="InitScenario" # опционально: /C
)
```

`start_session` определяет версию 1С по `base_url`, поднимает инфраструктуру Answer42 (на Linux — Xvfb, если нужен headless; на Windows — интерактивная desktop-сессия), свободные порты, WebSocket bridge, файловую базу менеджера и test-manager. Если доступны серверные компоненты 1С (`ibsrv`), менеджер и встроенная тестовая база публикуются через автономный сервер; если доступен только тонкий клиент и `ibcmd`, Answer42 автоматически использует fallback `file-direct` (`/F`) для файловых баз менеджера и клиента. После `idle_timeout_minutes` минут неактивности сессия автоматически завершается; значение по умолчанию — 60 минут. Для запуска клиента можно передать `extra_args`, `execute` (параметр командной строки `/Execute`) и `command_parameter` (параметр `/C`); если `/C` уже указан в `extra_args`, значения склеиваются через `;`.

Логин/пароль рекомендуется **не передавать явно**: `start_session` умеет брать их из локального credentials-файла по `base_url`. Параметры `username`/`password` остаются в API для разовых сценариев и обратной совместимости, но при передаче в MCP-вызове они видны вызывающему агенту в аргументах tool-call.

## Профили и форматы `ui_tree`

`ui_tree` оптимизирован для диагностики структуры формы. Профиль по умолчанию `profile="navigation"` возвращает компактное дерево видимых элементов без представлений данных, обогащения из RAG и поддеревьев командных панелей. Глубина дерева не ограничивается.

Полезные режимы:

- `ui_tree(parent_name=...)` сериализует только поддерево известного родительского элемента — удобно для больших и сложных форм.
- `ui_tree(name=.../title=.../type=...)` возвращает плоский список `objects` вместо дерева; на актуальных менеджерах фильтрация выполняется на стороне 1С, а простые точные запросы по `name`/`type` могут идти быстрым путём платформы до перехода к плоскому обходу.
- `profile="diagnostic"` включает командные панели без дорогого чтения данных.
- `profile="data"` включает представления данных узлов; если данные нужны не для многих узлов, лучше точечные `field_info`, `table_rows`, `tabular_documents(name=...)` или `tabular_document_save`.
- `profile="full"` даёт результат, ближайший к прежнему подробному.
- `fields="minimal|navigation|diagnostic|data|full"` (или свой список полей через запятую) управляет содержимым узлов без обрезки дерева.
- `command_panels="include|exclude|only"` явно управляет сериализацией командных панелей; `only` возвращает плоский список без повторов.
- `group_mode="include|flatten|flatten_layout|exclude|exclude_empty|pages_only"` определяет, сохраняются ли узлы групп, поднимаются ли их элементы на уровень выше или группы опускаются.
- `format="json|outline|yaml|yml"`: JSON остаётся структурированным форматом по умолчанию, остальные — читаемые текстовые представления. Неверные значения профиля, группировки, командных панелей и формата отклоняются; каждый результат содержит `metrics` с замерами времени и размера, а `tree_summary.types_count` — число узлов по семействам (`buttons`, `fields`, `tables`, `groups` и т. д.) и по точному типу клиента тестирования 1С.

### Большие снимки `ui_tree` как ресурсы

По умолчанию `delivery="auto"` возвращает небольшие результаты прямо в ответе, а большие автоматически сохраняет как ресурс, когда оценка числа токенов превышает `ONEC_MCP_UI_TREE_RESOURCE_AUTO_THRESHOLD_TOKENS` (по умолчанию 50 тысяч).
`delivery="inline"` принудительно возвращает выбранный JSON/outline/yaml в ответе, `delivery="resource"` — принудительно сохраняет большую диагностику в ресурс:

```text
r = ui_tree(profile="full", include_hidden=true, delivery="resource")
```

Когда `auto` переключается на ресурс или `delivery="resource"` задан явно, ответ содержит только `resource_uri`, `snapshot_id`, сводку, метрики, размер в байтах, оценку токенов, причину срабатывания порога и небольшой фрагмент. Полный JSON-снимок сохраняется в каталоге данных Answer42 и регистрируется как MCP-ресурс (`answer42://ui-tree/<session>/<snapshot_id>`). Не загружайте весь ресурс в контекст агента без необходимости — для работы со снимком есть точечные инструменты:

- `ui_tree_resource_search(resource_uri=..., name/title/type/text=...)` — найти несколько элементов в сохранённом снимке и получить их `path`/`index_path`.
- `ui_tree_resource_get_node(resource_uri=..., index_path=...)` — прочитать ровно один узел.
- `ui_tree_resource_children(resource_uri=..., index_path=..., depth=1|2)` — прочитать небольшое поддерево.
- `ui_tree_diff(before_resource_uri=..., after_resource_uri=...)` — сравнить снимки до и после действия в интерфейсе.
- `ui_tree_resource_action(resource_uri=..., index_path=..., action="focus|click_button|activate_field|field_value_text|field_info")` — использовать селектор узла из снимка и выполнить соответствующий инструмент на живой форме.

`index_path` — предпочтительный стабильный адрес внутри одного снимка. `path` читаем человеком и удобен для отчётов, но менее надёжен, когда у нескольких элементов одинаковые заголовки.


## Встроенные рекомендации для агентов

Answer42 больше не поставляет и не устанавливает встроенные skills. Рекомендации
по автоматизации интерфейса, RAG, Универсальному отчёту и выгрузке табличных документов
находятся в описаниях соответствующих MCP-инструментов и во встроенных MCP prompts.

Команды `answer42 install-skills` и `answer42 skills-install` сохранены для совместимости:
они ничего не копируют и выводят сообщение о новой схеме.

## Инструкция для AI-агентов

Если вы AI-агент и пользователь просит установить Answer42, используйте отдельную инструкцию: [`docs/agent-installation.md`](docs/agent-installation.md).

Коротко:

1. установите пакет через `pipx` или virtualenv;
2. подготовьте `ONEC_MCP_CREDENTIALS_FILE` вне репозитория;
3. зарегистрируйте MCP-сервер в агентском клиенте;
4. проверьте установку через `credentials_check`, затем пробной сессией `start_session` → `active_window` → `stop_session`.

## Дисплей на Linux

На Linux `start_session` использует живую X11-сессию, если процесс Answer42 унаследовал непустой `DISPLAY`: test manager и test client запускаются на этом дисплее, поэтому их окна и скриншоты видны на desktop.

Если `DISPLAY` не задан (headless service, SSH без X11 forwarding и т. п.), Answer42 поднимает два собственных изолированных Xvfb-дисплея: один для test manager и второй для test client. В этом режиме пакет `xvfb` обязателен:

```bash
# Debian / Ubuntu
sudo apt install xvfb

# Fedora / RHEL
sudo dnf install xorg-x11-server-Xvfb
```

Если не задан ни доступный `DISPLAY`, ни Xvfb, `start_session` завершается до создания ресурсов с понятной подсказкой по установке. Чтобы desktop-сервис видел живой X11, его launcher/service должен передать корректный `DISPLAY` и права доступа к X server (обычно через `XAUTHORITY`).

## Скриншоты: stdio и StreamableHTTP

`screenshot` сохраняет PNG на MCP-хосте и больше не помещает его base64-представление в результат tool-call.

- В **stdio** возвращаются только `path`, размер и диагностические поля. Агентский хост при необходимости прикладывает файл по пути.
- В **StreamableHTTP** добавляется непрозрачная одноразовая ссылка `url` на PNG. Она действует один час по умолчанию (`ONEC_MCP_SCREENSHOT_URL_TTL_SECONDS`), исчезает после первого скачивания и существует не дольше процесса сервера. Для внешнего reverse proxy укажите публичный base URL через `ONEC_MCP_SCREENSHOT_URL_BASE`.

## Транспорты: stdio и StreamableHTTP

По умолчанию Answer42 использует транспорт MCP stdio (MCP-хост запускает его как дочерний процесс). Для удалённого развёртывания есть режим **StreamableHTTP** с авторизацией MCP:

```bash
answer42 --http --http-host 0.0.0.0 --http-port 8080 \
  --http-token "static-secret-token" \
  --http-account-id "tenant-42"
```

Переменные окружения:

```bash
export ONEC_MCP_HTTP=1
export ONEC_MCP_HTTP_HOST=0.0.0.0
export ONEC_MCP_HTTP_PORT=8080
export ONEC_MCP_HTTP_TOKEN="static-secret-token"
export ONEC_MCP_ACCOUNT_ID="tenant-42"
answer42
```

- Каждый MCP-запрос должен содержать заголовок `Authorization: Bearer <token>`.
- `account_id` определяет namespace для credentials. Если не задан, вычисляется как стабильный хеш токена (`token-<16hex>`).
- Режим по умолчанию **stateless** (`ONEC_MCP_HTTP_STATELESS` default `1`). `--http-stateful` (или `ONEC_MCP_HTTP_STATELESS=0`) включает сессии MCP (`Mcp-Session-Id`): тогда сервер помнит включённые клиентом группы инструментов и присылает ему `tools/list_changed`.
- Один HTTP-сервер обслуживает всех клиентов, поэтому неявной сессии по умолчанию нет: `start_session` без `session_id` создаёт сессию с уникальным id и возвращает его, а инструменты, работающие с сессией, без явного `session_id` возвращают ошибку. Список сессий — `sessions_list`.

## Группы инструментов

Клиент по умолчанию видит только группу `core` (~36 инструментов: сессии, окна, навигация, кнопки, поля, основные операции с таблицами и отчётами). Остальные группы подключаются, когда нужны:

| Группа | Что внутри |
|---|---|
| `forms` | фокус и обход элементов, ожидания, группы и страницы, декорации, HTML-поля через API тест-клиента, диалог выбора файла, пакетный ввод полей |
| `tables` | перемещение по таблице, ячейки, выделение, копирование и пометка удаления, режим редактирования |
| `lists` | настройки динамических списков: отборы, сортировка, поиск, вывод списка |
| `commands` | командный интерфейс, командные панели и контекстные меню |
| `ui_snapshots` | работа с сохранённым большим `ui_tree` (включается сама, когда `ui_tree` сохранил результат в ресурс) |
| `metadata` | метаданные конфигурации из живого интерфейса |
| `rag` | RAG по исходникам конфигурации — **только пока RAG активен** (`start_session(rag_enabled=true)`) |
| `html` | живые веб-страницы в HTML-полях: текст, поиск элементов, клик, ввод, ожидание, ошибки консоли (включается сама после `start_session`); произвольный JavaScript `html_eval` — только с `--dev-tools` |
| `recording` | запись доказательств (скриншоты, слайды, PDF) |
| `credentials` | сохранённые учётные данные баз |

Как подключить группы:

- **на ходу** — инструментом `tool_groups(action="enable", groups="lists,commands")`; клиент получает `tools/list_changed` и перечитывает список. Выбор запоминается за клиентом: в stdio — за процессом, в stateful HTTP — за `Mcp-Session-Id`, у клиентов без сессии (протокол MCP 2026-07-28, stateless HTTP) — за `?client=<имя>` / `X-Answer42-Client`, а если его нет — за учётной записью токена;
- **для клиента HTTP-сервера** — параметром адреса: `http://127.0.0.1:8742/mcp?tools=lists,commands` (или заголовком `X-Answer42-Tools`);
- **для сервера целиком** — `--tool-profile` / `ONEC_MCP_TOOL_PROFILE` (например `core,lists` или `full`). Старые имена профилей (`ui`, `dynamic`, `tabular`, `sessions`, `windows`) продолжают работать.

**Старый режим (статический список).** `--tool-groups off` или `ONEC_MCP_TOOL_GROUPS=off` выключает группы: клиент сразу видит весь список профиля (по умолчанию `full`), инструмента `tool_groups` нет, RAG-инструменты не скрываются. Отдельному клиенту полный список можно дать и без выключения групп — `?tools=full`.

## HTML-поля и живые веб-страницы

Поле HTML-документа 1С может показывать как статический HTML, так и полноценное веб-приложение (чат, SPA), которое рисует себя скриптами.

**Статический HTML** — инструменты группы `forms` через API клиента тестирования: `html_field_content` (HTML поля в том виде, в каком страница загрузилась, и её видимый текст), `html_field_click_link`, `html_field_input`.

**Живые страницы** — группа `html`. Способ доступа к встроенному WebKit клиента выбирает параметр `start_session(html_mode=...)` (значение по умолчанию можно задать переменной `ONEC_MCP_HTML_MODE`):

| `html_mode` | Где | Как |
|---|---|---|
| `auto` (по умолчанию) | везде | Linux — `remote`; Windows — `patched`, если в Web Inspector платформы установлен актуальный мост, иначе `console` |
| `console` | Windows | горячая клавиша инспектора и короткий загрузчик, введённый в его консоль |
| `patched` | Windows, Linux | мост, встроенный в интерфейс инспектора: на Windows — в Web Inspector платформы (сначала `answer42 webkit-inspector install`, см. ниже), на Linux — подставляется для сессии, ничего устанавливать не нужно |
| `remote` | Linux | удалённый отладчик WebKitGTK (`WEBKIT_INSPECTOR_SERVER`) |
| `disabled` | везде | мост не запускается, инструменты `html_*` недоступны |

Явно выбранный режим не подменяется другим: если он недоступен (`patched` без моста в платформе, режим другой ОС), `start_session` сразу возвращает ошибку с подсказкой. Мост ничего не делает, пока не вызван инструмент `html_*`: на Windows инспектор открывается только при первом вызове, на Linux клиент запускается со встроенным сервером отладки.

| Инструмент | Что делает |
|---|---|
| `html_pages` | список живых страниц HTML-полей; подключает новые |
| `html_text` | текст страницы или элементов по CSS-селектору |
| `html_query` | элементы по селектору или тексту: тег, id, класс, value, атрибуты, видимость |
| `html_click` | нажать элемент |
| `html_type` | ввести значение в поле (`submit=true` — отправить Enter) |
| `html_wait` | дождаться появления или исчезновения текста / элемента |
| `html_eval` | выполнить произвольный JavaScript в странице — **только с `--dev-tools`** (см. ниже) |
| `html_console` | ошибки и предупреждения консоли страницы и скрипты, которые эта сборка WebKit не разбирает (например `?.`) |
| `html_download` | скачать файл по ссылке страницы изнутри страницы (с её cookie и сеансом) и сохранить в каталог сессии: путь, размер, тип, HTTP-статус |
| `html_inspector_patch` | Windows: встроить мост в Web Inspector установленных платформ 1С или убрать его (необязательно, см. ниже) |

Если живых страниц несколько, нужная выбирается параметром `page` (id из `html_pages` или часть URL / заголовка).

**Произвольный код.** Инструменты, которые выполняют произвольный код, по умолчанию не регистрируются: `html_eval` (JavaScript в странице HTML-поля) и `dev_eval` (выражение BSL в менеджере тестирования). Их включают флагом `answer42 --dev-tools` или переменной `ONEC_MCP_DEV_TOOLS=1`; тогда `html_eval` видна вместе с группой `html`. Остальные инструменты `html_*` выполняют в странице только фиксированные операции Answer42.

Как это устроено:

- **Windows.** Встроенный WebKit клиента 1С не имеет сервера удалённой отладки, но его Web Inspector открывается по Ctrl+Alt+Shift+F12. При первом вызове `html_*` Answer42 открывает инспектор поля (он встраивается в нижнюю часть формы), переключает его на вкладку Console и вводит в консоль короткий загрузчик. Загрузчик подключается к локальному WebSocket Answer42 по одноразовому токену, получает мост и выполняет операции в странице. Подключение к странице занимает около 2–3 секунд. После перезагрузки страницы загрузчик вводится заново. Платформа используется как установлена.
- **Windows, мост в инспекторе платформы (`html_mode=patched`).** `answer42 webkit-inspector install` (или инструмент `html_inspector_patch(action="install")`) встраивает мост в Web Inspector установленной платформы: `bin\WebKit.resources\WebInspectorUI\Main.html` подключает `Answer42Bridge.js`. Каталог платформы доступен на запись только администратору, поэтому команда сама запрашивает права через UAC — одно подтверждение на все выбранные платформы — и разрешает текущему пользователю менять файл с портом сессии; сессиям права администратора больше не нужны. Если процесс Answer42 запущен из среды, которая не может показать запрос UAC (например, из песочницы агента), через 90 секунд команда вернёт ошибку с готовой командой для PowerShell, запущенного от имени администратора. После этого интерфейс инспектора подключается к Answer42 сам: в консоль ничего не вводится, мост переживает перезагрузку страницы, а `html_console` видит сообщения с момента её загрузки. Если инспектор открывает человек, мост ничего не делает. `answer42 webkit-inspector status` показывает состояние платформ, `uninstall` возвращает исходные файлы. После обновления Answer42 или платформы мост нужно поставить заново: `html_mode=patched` с устаревшим мостом не запускается. Ключ `--version` выбирает платформу, без него — все установленные.
- **Linux, `remote` (по умолчанию).** HTML-поля рисует системный WebKitGTK. Answer42 запускает тест-клиент с `WEBKIT_INSPECTOR_SERVER=127.0.0.1:<порт>` и подключается к удалённому отладчику WebKitGTK напрямую: окна инспектора и ввода с клавиатуры нет.
- **Linux, `patched`.** Инспектор WebKitGTK в 1С открывается той же клавишей Ctrl+Alt+Shift+F12 и встраивается в форму. Интерфейс инспектора вшит в системную `libwebkit2gtk`, поэтому Answer42 его не меняет: переменная GLib `G_RESOURCE_OVERLAYS` подставляет тест-клиенту из каталога сессии один файл инспектора (`localizedStrings.js`) с мостом. Answer42 ставит фокус в HTML-поле средствами клиента тестирования и отправляет клавишу через `xdotool`, после чего интерфейс инспектора подключается сам (около 1 с). Нужен `xdotool`; на живом дисплее горячая клавиша уходит в окно 1С.
- **Linux, `console`** не поддерживается: встроенный инспектор WebKitGTK не отдельное окно X11, поэтому клавиши уходят в элемент с фокусом — в саму страницу. В проверке набранный загрузчик попал в поле ввода чата и был отправлен как сообщение.

**Внешний браузер на Linux.** Ссылки и файлы, которые 1С открывает «снаружи» (например, «Скачать» в HTML-поле или `ЗапуститьПриложение`), платформа открывает через `xdg-open` и ждёт его завершения, а `xdg-open` ждёт браузер, который ему пришлось запустить. Без Answer42 клиент 1С висел, пока не закроют Chrome, а с ним вставали мост тест-клиента и инструменты `html_*`. Поэтому тест-клиент получает в `PATH` обёртку `xdg-open` от Answer42: она записывает адрес и сразу возвращает управление, а на настоящем дисплее открывает адрес в браузере отдельно от клиента. Записанные адреса видны в `external_opens` ответов `html_field_click_link` и `session_status`; файл по такому адресу скачивает `html_download`. `ONEC_MCP_EXTERNAL_OPEN`: `auto` (по умолчанию: на собственном Xvfb Answer42 только записывать, на настоящем дисплее ещё и открывать), `open`, `record`, `off` (без обёртки).

Ограничения: на Windows инспектор остаётся встроенным в форму и попадает на скриншоты. `html_console` на Linux и с мостом в инспекторе платформы отдаёт сообщения с момента загрузки страницы, а с загрузчиком в консоли — с момента подключения (`collected_since`); неподдержанный синтаксис в скриптах страницы находит проверка скриптов (`check_scripts`). Встроенный WebKit Windows-клиента 1С не поддерживает часть современного JavaScript (например `?.`), а WebKitGTK на Linux — поддерживает: одна и та же страница может работать в одном клиенте и ломаться в другом.

## Безопасное хранение логинов и паролей

Чтобы креды были доступны MCP-серверу, но не попадали в чат и аргументы tool-call, храните их в локальном файле за пределами репозитория и передайте путь в окружение процесса Answer42:

```bash
export ONEC_MCP_CREDENTIALS_FILE=/secure/path/credentials.json
```

Если переменная окружения не задана, MCP-сервер читает файл по умолчанию:

```text
~/.answer42-credentials.json
```

Формат файла v2 (аккаунт-bound):

```json
{
  "version": 2,
  "accounts": {
    "tenant-42": {
      "entries": [
        {
          "url": "https://example.invalid/infobase",
          "username": "<USERNAME>",
          "password": "<PASSWORD>",
          "title": "dev-example",
          "aliases": ["dev42"]
        },
        {
          "url": "https://*.example.invalid/*",
          "username": "<WILDCARD_USERNAME>",
          "password": "<WILDCARD_PASSWORD>",
          "title": "wildcard-example",
          "aliases": ["we"]
        }
      ]
    }
  }
}
```

Устаревший формат v1 (плоский список `entries`) автоматически загружается в аккаунт `legacy` и переводится в v2 при следующем сохранении. Рекомендуется явно задать `account_id` (через claim авторизации HTTP или `ONEC_MCP_ACCOUNT_ID` в stdio) и перенести записи в нужный аккаунт.

Рекомендуемые права на файл: `0600`.

Правила матчинга внутри аккаунта: сначала точное совпадение `url`, затем wildcard (`*`, `?`) через `fnmatch`; первое совпадение побеждает. Пароли не логируются и не возвращаются наружу.

Без агента запись добавляется из командной строки. Пароль запрашивается интерактивно (или читается из первой строки stdin с `--password-stdin`) и в аргументы команды не попадает:

```bash
answer42 credentials add --url "<TARGET_INFOBASE_URL>" --username "<USERNAME>" [--title dev-01] [--alias dev01]
answer42 credentials list
answer42 credentials remove --url "<TARGET_INFOBASE_URL>"
```

Аккаунт по умолчанию — `ONEC_MCP_ACCOUNT_ID` или `default`; для HTTP-режима без явного `account_id` передайте `--token <Bearer-токен>` (аккаунт вычисляется так же, как на сервере) или `--account`. Файл — `ONEC_MCP_CREDENTIALS_FILE` или `--file`. Запущенный сервер перечитывает файл при следующем обращении к кредам, если файл изменился, перезапуск не нужен.

Для сохранения или обновления записи можно использовать MCP-tool:

```text
credentials_save(
  url="<TARGET_INFOBASE_URL>",
  username="<USERNAME>",
  password="<PASSWORD>"
)
```

Для удаления записи:

```text
credentials_remove(url="<TARGET_INFOBASE_URL>")
```

Для проверки, что для адреса есть сохранённые креды, используйте MCP-tool:

```text
credentials_check(base_url="<TARGET_INFOBASE_URL>")
```

Ответы этих tools содержат только факт наличия/изменения/удаления записи и URL; логины и пароли не возвращаются. `credentials_list()` дополнительно показывает статус проверки (`verified` / `verification_status`): новые или изменённые записи сохраняются как `unverified`, после успешного `start_session` с этой учёткой помечаются как `verified`, а `unverified` запись удаляется при ошибке авторизации. Tool `credentials_list()` оставлен в коде для локальной диагностики, но в OpenClaw-конфигурации его рекомендуется скрывать через `toolFilter.exclude`, чтобы агент не мог получить список URL-шаблонов.

Остановка сессии:

```text
stop_session(session_id="my-session", clean_data=False)
```

Данные сессии лежат в `<временная папка>/answer42/sessions/<session_id>` (переопределяется `ONEC_MCP_DATA_DIR`). При остановке без `clean_data` сохраняется только служебная база менеджера (для быстрого повторного старта), а кэши автономного сервера (`ibsrv-data*/session-data`, `temp`, `perf-data`, ~640 МБ на сессию) удаляются. Сервер раз в час убирает папки, которые не использует ни одна живая сессия: не менявшиеся дольше `ONEC_MCP_SESSION_DATA_TTL_HOURS` часов (по умолчанию 24) удаляются целиком, у остальных удаляются кэши; `0` отключает удаление папок целиком.

## Требования

- Python 3.11+
- 1С:Предприятие **8.3.27+ или 8.5+**
- Пакеты Python: `mcp`, `websockets`, `pydantic`; для скриншотов — `mss`
- Linux/X11: `python-xlib`/`wmctrl`/`xdotool`, GUI/Xvfb для headless-сервера; OS-слой допускается для подготовки геометрии окна (resize/maximize), но не для ввода/кликов/автоматизации 1С
- Windows: интерактивная пользовательская desktop-сессия; window-control и screenshots работают через WinAPI/`mss`, ввод/клики/автоматизация 1С выполняются только через API клиента тестирования

Проверяйте наличие платформы 1С в стандартных каталогах: Linux `/opt/1cv8/x86_64/<version>/` и `/opt/1cv8/i386/<version>/`; Windows `C:\Program Files\1cv8\<version>\bin\` и `C:\Program Files (x86)\1cv8\<version>\bin\`; macOS `/Applications/1cv8/<version>/` или `/opt/1cv8/<version>/`. Для штатной работы нужны `1cv8c` и `ibcmd`; `ibsrv` желателен, но при его отсутствии Answer42 может использовать fallback `/F`. Если автоопределение ошиблось, задайте `ONEC_PLATFORM_DIR`. Для очень медленного старта web-клиента можно увеличить `ONEC_MCP_TEST_CLIENT_READY_TIMEOUT` и timeout MCP-клиента; по умолчанию Answer42 ждёт открытия `-TPort` 55 секунд и затем отдаёт явную ошибку с логами клиента.

## Безопасность стендов и учётных данных

В репозитории не должно быть реальных URL стендов, логинов или паролей. Для штатного запуска передавайте только `base_url`, а логин/пароль храните в локальном credentials-файле, доступном процессу Answer42 через `ONEC_MCP_CREDENTIALS_FILE`.

`start_session` всё ещё принимает `username` и `password` напрямую для разовых сценариев и обратной совместимости. Используйте это только когда осознанно готовы раскрыть значения вызывающему агенту: параметры MCP-вызова могут попасть в историю чата, логи клиента или отладочный вывод. Если вместо реального пароля передан редактированный плейсхолдер из звёздочек (`***`, `********` и т.п.), Answer42 остановит запуск с явной ошибкой: нужно указать настоящий пароль или сохранить корректные креды через `credentials_save()`.

Примеры в документации используют только плейсхолдеры (`<TARGET_INFOBASE_URL>`, `<USERNAME>`, `<PASSWORD>`). Перед публикацией артефактов проверяйте, что параметры вызовов заредактированы: recorder маскирует ключи вроде `password`, но URL и логин тоже не должны попадать в публичные материалы.

## Архитектура

Поток выполнения:

1. MCP-клиент вызывает tools через stdio MCP.
2. Answer42 принимает MCP-вызовы и передаёт команды в WebSocket bridge.
3. 1С test manager подключается к bridge и выполняет BSL-dispatch.
4. Test manager управляет 1С test client через API `ТестируемоеПриложение`.
5. Test client выполняет интерактивные операции в целевой информационной базе.

Подробнее: [`docs/architecture.md`](docs/architecture.md).

## Сборка конфигураций 1С

Конфигурация менеджера тестирования собирается из XML-исходников `src/cf/` через временную файловую ИБ: `ibcmd infobase config import` и затем `ibcmd config save` (приоритетный способ). Такой путь создаёт переносимый `.cf` с режимом совместимости XML-исходников; если `ibcmd` нет, используется Конфигуратор (DESIGNER):

```bash
python scripts/build_cf.py src/cf build/MCPTestManager.cf
```

PowerShell:

```powershell
python scripts/build_cf.py src/cf build/MCPTestManager.cf
```

Тестовая конфигурация для E2E собирается из XML-исходников `src/client_cf/`:

```bash
python scripts/build_cf.py src/client_cf build/MCPTestClient.cf
```

PowerShell:

```powershell
python scripts/build_cf.py src/client_cf build/MCPTestClient.cf
```

В Git хранятся только XML-исходники; CF — генерируемые артефакты. `start_session` использует `build/MCPTestManager.cf` только при точном совпадении content fingerprint с `src/cf/`; иначе автоматически пересобирает его локальной выбранной платформой. Встроенный demo-клиент аналогично работает с `build/MCPTestClient.cf` и `src/client_cf/`. Релизный wheel получает оба CF из GitLab CI, где они собираются закреплённой платформой 1С 8.3.27.2342.

E2E можно запускать целиком или по независимым сценариям:

```bash
python3 scripts/e2e_stable.py                         # full
E2E_SCENARIO=smoke python3 scripts/e2e_stable.py       # быстрый smoke
E2E_SCENARIO=dynamic python3 scripts/e2e_stable.py     # legacy: таблицы/dynamic-list/отчёт
E2E_SCENARIO=dynamic-tables python3 scripts/e2e_stable.py
E2E_SCENARIO=dynamic-lists python3 scripts/e2e_stable.py
E2E_SCENARIO=dynamic-reports python3 scripts/e2e_stable.py
E2E_SCENARIO=coverage python3 scripts/e2e_stable.py    # diagnostic/negative tools
```

Для реального распараллеливания сценарий умеет сам запустить пять разные сессий (`smoke`, `dynamic-tables`, `dynamic-lists`, `dynamic-reports`, `coverage`), а не копии одного и того же теста. Встроенная тестовая файловая база публикуется через один общий `ibsrv`, когда серверные компоненты доступны; без `ibsrv` demo-клиент запускается через `file-direct` (`/F`):

```bash
E2E_PARALLEL=1 E2E_SESSION_ID=e2e-split python3 scripts/e2e_stable.py
```

`start_session` также переиспользует общий автономный сервер для одинаковой файловой базы. Последний `stop_session` освобождает refcount и завершает shared `ibsrv`.

## Ограничения

- Форма пользовательской настройки **«Изменить форму»** частично недоступна для надёжной автоматизации через API клиента тестирования. В частности, команда **«Добавить поля»** в верхней панели формы настройки может быть видна на скриншоте и в диагностическом тексте, но не нажиматься как обычная `ТестируемаяКнопкаФормы`: `click_button` может не находить её, а `focus_object` может вернуть успешную фокусировку без открытия диалога добавления полей.

## Лицензия

MIT

## Copyright

Copyright (c) 2026 Kosolapov Stanislav aka proDOOMman <prodoomman@gmail.com>, Marvin (AI Assistant), 42Clouds, and contributors.

Распространяется по лицензии MIT.
