From a7494caba3bbe07299f94605b9b6a652ef8bc560 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Sun, 26 Apr 2026 23:14:00 +0000 Subject: [PATCH] chore(i18n): refresh uk translations --- docs/uk/automation/hooks.md | 166 +++---- docs/uk/ci.md | 176 ++++---- docs/uk/gateway/bonjour.md | 186 ++++---- docs/uk/gateway/discovery.md | 126 +++--- docs/uk/help/testing.md | 849 ++++++++++++++++++----------------- docs/uk/reference/test.md | 107 ++--- 6 files changed, 798 insertions(+), 812 deletions(-) diff --git a/docs/uk/automation/hooks.md b/docs/uk/automation/hooks.md index 0986c2214..3fadaef97 100644 --- a/docs/uk/automation/hooks.md +++ b/docs/uk/automation/hooks.md @@ -1,66 +1,66 @@ --- read_when: - Ви хочете автоматизацію на основі подій для `/new`, `/reset`, `/stop` і подій життєвого циклу агента - - Ви хочете створити, встановити або налагодити хуки + - Ви хочете створювати, встановлювати або налагоджувати хуки summary: 'Хуки: автоматизація на основі подій для команд і подій життєвого циклу' title: Хуки x-i18n: - generated_at: "2026-04-26T00:29:08Z" + generated_at: "2026-04-26T23:10:41Z" model: gpt-5.4 provider: openai - source_hash: cf40a64449347ef750b4b0e0a83b80e2e8fdef87d92daa71f028d2bf6a3d3d22 + source_hash: f1f9b1dc0c470502f782758e1542435f1e593750ff69a39f7f966c7d42e29c1e source_path: automation/hooks.md workflow: 15 --- -Хуки — це невеликі скрипти, які запускаються, коли щось відбувається всередині Gateway. Їх можна виявляти з каталогів і переглядати через `openclaw hooks`. Gateway завантажує внутрішні хуки лише після того, як ви ввімкнете хуки або налаштуєте принаймні один запис хука, пак хука, застарілий обробник чи додатковий каталог хуків. +Хуки — це невеликі скрипти, які запускаються, коли щось відбувається всередині Gateway. Їх можна виявляти з директорій та переглядати за допомогою `openclaw hooks`. Gateway завантажує внутрішні хуки лише після того, як ви ввімкнете хуки або налаштуєте принаймні один запис хука, пакет хуків, застарілий обробник або додаткову директорію хуків. В OpenClaw є два типи хуків: -- **Внутрішні хуки** (ця сторінка): запускаються всередині Gateway, коли спрацьовують події агента, як-от `/new`, `/reset`, `/stop` або події життєвого циклу. -- **Webhooks**: зовнішні HTTP-ендпоїнти, які дозволяють іншим системам запускати роботу в OpenClaw. Див. [Webhooks](/uk/automation/cron-jobs#webhooks). +- **Внутрішні хуки** (ця сторінка): виконуються всередині Gateway, коли спрацьовують події агента, як-от `/new`, `/reset`, `/stop` або події життєвого циклу. +- **Webhooks**: зовнішні HTTP-ендпойнти, які дозволяють іншим системам запускати роботу в OpenClaw. Див. [Webhooks](/uk/automation/cron-jobs#webhooks). -Хуки також можуть постачатися всередині плагінів. `openclaw hooks list` показує як окремі хуки, так і хуки, якими керують плагіни. +Хуки також можуть постачатися всередині плагінів. `openclaw hooks list` показує як окремі хуки, так і хуки, керовані плагінами. ## Швидкий старт ```bash -# Перелічити доступні хуки +# Показати доступні хуки openclaw hooks list # Увімкнути хук openclaw hooks enable session-memory -# Перевірити статус хуків +# Перевірити стан хуків openclaw hooks check -# Отримати докладну інформацію +# Отримати детальну інформацію openclaw hooks info session-memory ``` ## Типи подій -| Подія | Коли спрацьовує | -| ------------------------ | -------------------------------------------- | -| `command:new` | Надіслано команду `/new` | -| `command:reset` | Надіслано команду `/reset` | -| `command:stop` | Надіслано команду `/stop` | -| `command` | Будь-яка подія команди (загальний слухач) | -| `session:compact:before` | Перед тим, як Compaction підсумує історію | -| `session:compact:after` | Після завершення Compaction | -| `session:patch` | Коли властивості сесії змінюються | -| `agent:bootstrap` | Перед вставленням bootstrap-файлів робочої області | -| `gateway:startup` | Після запуску каналів і завантаження хуків | -| `message:received` | Вхідне повідомлення з будь-якого каналу | -| `message:transcribed` | Після завершення транскрибування аудіо | -| `message:preprocessed` | Після завершення обробки всіх медіа й посилань | -| `message:sent` | Вихідне повідомлення доставлено | +| Подія | Коли спрацьовує | +| ------------------------ | ----------------------------------------------- | +| `command:new` | Надіслано команду `/new` | +| `command:reset` | Надіслано команду `/reset` | +| `command:stop` | Надіслано команду `/stop` | +| `command` | Будь-яка подія команди (загальний слухач) | +| `session:compact:before` | Перед тим, як Compaction підсумує історію | +| `session:compact:after` | Після завершення Compaction | +| `session:patch` | Коли змінюються властивості сесії | +| `agent:bootstrap` | Перед додаванням bootstrap-файлів робочої папки | +| `gateway:startup` | Після запуску каналів і завантаження хуків | +| `message:received` | Вхідне повідомлення з будь-якого каналу | +| `message:transcribed` | Після завершення транскрибування аудіо | +| `message:preprocessed` | Після завершення обробки медіа та посилань | +| `message:sent` | Вихідне повідомлення доставлено | ## Написання хуків ### Структура хука -Кожен хук — це каталог, що містить два файли: +Кожен хук — це директорія, що містить два файли: ``` my-hook/ @@ -80,20 +80,20 @@ metadata: # My Hook -Тут розміщується докладна документація. +Тут розміщується детальна документація. ``` **Поля метаданих** (`metadata.openclaw`): -| Поле | Опис | -| --------- | ---------------------------------------------------- | -| `emoji` | Емодзі для відображення в CLI | -| `events` | Масив подій, які потрібно слухати | -| `export` | Іменований експорт для використання (типово `"default"`) | -| `os` | Обов’язкові платформи (наприклад, `["darwin", "linux"]`) | -| `requires` | Обов’язкові `bins`, `anyBins`, `env` або шляхи `config` | -| `always` | Обійти перевірки придатності (boolean) | -| `install` | Методи встановлення | +| Поле | Опис | +| --------- | --------------------------------------------------------- | +| `emoji` | Емодзі для відображення в CLI | +| `events` | Масив подій, які потрібно відстежувати | +| `export` | Іменований експорт для використання (типово `"default"`) | +| `os` | Потрібні платформи (наприклад, `["darwin", "linux"]`) | +| `requires` | Потрібні шляхи `bins`, `anyBins`, `env` або `config` | +| `always` | Обійти перевірки відповідності (boolean) | +| `install` | Методи встановлення | ### Реалізація обробника @@ -113,7 +113,7 @@ const handler = async (event) => { export default handler; ``` -Кожна подія містить: `type`, `action`, `sessionKey`, `timestamp`, `messages` (додавайте через push, щоб надіслати користувачу), і `context` (специфічні для події дані). Контексти хуків агентів і інструментальних плагінів також можуть містити `trace` — лише для читання W3C-сумісний діагностичний контекст трасування, який плагіни можуть передавати до структурованих логів для кореляції OTEL. +Кожна подія містить: `type`, `action`, `sessionKey`, `timestamp`, `messages` (додавайте сюди, щоб надіслати користувачу), і `context` (специфічні для події дані). Контексти хуків агентів і плагінів інструментів також можуть містити `trace` — лише для читання, сумісний із W3C діагностичний контекст трасування, який плагіни можуть передавати в структуровані логи для кореляції OTEL. ### Основні моменти контексту подій @@ -125,49 +125,49 @@ export default handler; **Події повідомлень** (`message:transcribed`): `context.transcript`, `context.from`, `context.channelId`, `context.mediaPath`. -**Події повідомлень** (`message:preprocessed`): `context.bodyForAgent` (остаточний збагачений вміст), `context.from`, `context.channelId`. +**Події повідомлень** (`message:preprocessed`): `context.bodyForAgent` (остаточне збагачене тіло), `context.from`, `context.channelId`. -**Події Bootstrap** (`agent:bootstrap`): `context.bootstrapFiles` (змінюваний масив), `context.agentId`. +**Події bootstrap** (`agent:bootstrap`): `context.bootstrapFiles` (змінюваний масив), `context.agentId`. -**Події patch сесії** (`session:patch`): `context.sessionEntry`, `context.patch` (лише змінені поля), `context.cfg`. Лише привілейовані клієнти можуть ініціювати події patch. +**Події patch сесії** (`session:patch`): `context.sessionEntry`, `context.patch` (лише змінені поля), `context.cfg`. Лише привілейовані клієнти можуть запускати події patch. -**Події Compaction**: `session:compact:before` включає `messageCount`, `tokenCount`. `session:compact:after` додатково містить `compactedCount`, `summaryLength`, `tokensBefore`, `tokensAfter`. +**Події Compaction**: `session:compact:before` містить `messageCount`, `tokenCount`. `session:compact:after` додатково містить `compactedCount`, `summaryLength`, `tokensBefore`, `tokensAfter`. -`command:stop` спостерігає за тим, як користувач надсилає `/stop`; це стосується скасування/життєвого циклу команди, а не завершення роботи агента. Плагіни, яким потрібно перевірити природну фінальну відповідь і попросити агента зробити ще один прохід, мають використовувати типізований хук плагіна `before_agent_finalize`. Див. [Plugin hooks](/uk/plugins/hooks). +`command:stop` фіксує, коли користувач надсилає `/stop`; це життєвий цикл скасування/команди, а не бар’єр фіналізації агента. Плагіни, яким потрібно перевірити природну фінальну відповідь і попросити агента зробити ще один прохід, повинні використовувати типізований хук плагіна `before_agent_finalize`. Див. [Plugin hooks](/uk/plugins/hooks). ## Виявлення хуків -Хуки виявляються з цих каталогів у порядку зростання пріоритету перевизначення: +Хуки виявляються з таких директорій у порядку зростання пріоритету перевизначення: -1. **Вбудовані хуки**: постачаються з OpenClaw -2. **Хуки плагінів**: хуки, вбудовані у встановлені плагіни -3. **Керовані хуки**: `~/.openclaw/hooks/` (встановлені користувачем, спільні для всіх робочих областей). Додаткові каталоги з `hooks.internal.load.extraDirs` мають той самий пріоритет. -4. **Хуки робочої області**: `/hooks/` (для окремого агента, типово вимкнені, доки їх явно не ввімкнути) +1. **Вбудовані хуки**: постачаються разом з OpenClaw +2. **Хуки плагінів**: постачаються всередині встановлених плагінів +3. **Керовані хуки**: `~/.openclaw/hooks/` (встановлені користувачем, спільні для всіх робочих папок). Додаткові директорії з `hooks.internal.load.extraDirs` мають такий самий пріоритет. +4. **Хуки робочої папки**: `/hooks/` (для кожного агента окремо, типово вимкнені, доки їх явно не ввімкнути) -Хуки робочої області можуть додавати нові назви хуків, але не можуть перевизначати вбудовані, керовані або надані плагінами хуки з тією самою назвою. +Хуки робочої папки можуть додавати нові назви хуків, але не можуть перевизначати вбудовані, керовані або надані плагінами хуки з тією самою назвою. -Gateway пропускає виявлення внутрішніх хуків під час запуску, доки внутрішні хуки не буде налаштовано. Увімкніть вбудований або керований хук через `openclaw hooks enable `, встановіть пак хуків або задайте `hooks.internal.enabled=true`, щоб явно ввімкнути цю можливість. Коли ви вмикаєте один іменований хук, Gateway завантажує лише обробник цього хука; `hooks.internal.enabled=true`, додаткові каталоги хуків і застарілі обробники вмикають широке виявлення. +Gateway пропускає виявлення внутрішніх хуків під час запуску, доки внутрішні хуки не налаштовані. Увімкніть вбудований або керований хук за допомогою `openclaw hooks enable `, встановіть пакет хуків або задайте `hooks.internal.enabled=true`, щоб дозволити їх. Коли ви вмикаєте один іменований хук, Gateway завантажує лише обробник цього хука; `hooks.internal.enabled=true`, додаткові директорії хуків і застарілі обробники вмикають широке виявлення. -### Паки хуків +### Пакети хуків -Паки хуків — це npm-пакети, які експортують хуки через `openclaw.hooks` у `package.json`. Встановлення: +Пакети хуків — це npm-пакети, які експортують хуки через `openclaw.hooks` у `package.json`. Встановлення: ```bash openclaw plugins install ``` -Npm-специфікації підтримуються лише для реєстру (назва пакета + необов’язкова точна версія або dist-tag). Git/URL/file-специфікації та semver-діапазони відхиляються. +Npm-специфікації підтримуються лише для реєстру (назва пакета + необов’язкова точна версія або dist-tag). Специфікації Git/URL/file і діапазони semver відхиляються. ## Вбудовані хуки -| Хук | Події | Що робить | -| --------------------- | ------------------------------ | ----------------------------------------------------- | -| session-memory | `command:new`, `command:reset` | Зберігає контекст сесії в `/memory/` | -| bootstrap-extra-files | `agent:bootstrap` | Вставляє додаткові bootstrap-файли за glob-шаблонами | -| command-logger | `command` | Логує всі команди в `~/.openclaw/logs/commands.log` | -| boot-md | `gateway:startup` | Виконує `BOOT.md` під час запуску gateway | +| Хук | Події | Що робить | +| -------------------- | ----------------------------- | ------------------------------------------------------ | +| session-memory | `command:new`, `command:reset` | Зберігає контекст сесії в `/memory/` | +| bootstrap-extra-files | `agent:bootstrap` | Додає додаткові bootstrap-файли за glob-шаблонами | +| command-logger | `command` | Логує всі команди в `~/.openclaw/logs/commands.log` | +| boot-md | `gateway:startup` | Запускає `BOOT.md`, коли запускається gateway | -Увімкніть будь-який вбудований хук: +Увімкнути будь-який вбудований хук: ```bash openclaw hooks enable @@ -175,9 +175,9 @@ openclaw hooks enable -### Докладно про session-memory +### Деталі session-memory -Витягує останні 15 повідомлень користувача/асистента, генерує описовий slug імені файла через LLM і зберігає його в `/memory/YYYY-MM-DD-slug.md`. Потребує налаштованого `workspace.dir`. +Витягує останні 15 повідомлень користувача/асистента, генерує описовий slug імені файла через LLM і зберігає його в `/memory/YYYY-MM-DD-slug.md`, використовуючи локальну дату хоста. Потрібно, щоб був налаштований `workspace.dir`. @@ -198,28 +198,28 @@ openclaw hooks enable } ``` -Шляхи обчислюються відносно робочої області. Завантажуються лише розпізнані базові назви bootstrap-файлів (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, `MEMORY.md`). +Шляхи обчислюються відносно робочої папки. Завантажуються лише розпізнані базові назви bootstrap-файлів (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, `MEMORY.md`). -### Докладно про command-logger +### Деталі command-logger Логує кожну slash-команду в `~/.openclaw/logs/commands.log`. -### Докладно про boot-md +### Деталі boot-md -Виконує `BOOT.md` з активної робочої області під час запуску gateway. +Запускає `BOOT.md` з активної робочої папки під час запуску gateway. ## Хуки плагінів Плагіни можуть реєструвати типізовані хуки через Plugin SDK для глибшої інтеграції: -перехоплення викликів інструментів, зміни промптів, керування потоком повідомлень тощо. +перехоплення викликів інструментів, модифікації промптів, керування потоком повідомлень тощо. Використовуйте хуки плагінів, коли вам потрібні `before_tool_call`, `before_agent_reply`, -`before_install` або інші внутрішньопроцесні хуки життєвого циклу. +`before_install` або інші in-process хуки життєвого циклу. -Повний довідник по хуках плагінів див. у [Plugin hooks](/uk/plugins/hooks). +Повний довідник із хуків плагінів див. у [Plugin hooks](/uk/plugins/hooks). ## Конфігурація @@ -237,7 +237,7 @@ openclaw hooks enable } ``` -Змінні середовища для окремих хуків: +Змінні середовища для окремого хука: ```json { @@ -254,7 +254,7 @@ openclaw hooks enable } ``` -Додаткові каталоги хуків: +Додаткові директорії хуків: ```json { @@ -269,19 +269,19 @@ openclaw hooks enable ``` -Застарілий формат конфігурації масиву `hooks.internal.handlers` усе ще підтримується для зворотної сумісності, але нові хуки мають використовувати систему на основі виявлення. +Застарілий формат конфігурації масиву `hooks.internal.handlers` усе ще підтримується для зворотної сумісності, але нові хуки повинні використовувати систему на основі виявлення. ## Довідник CLI ```bash -# Перелічити всі хуки (додайте --eligible, --verbose або --json) +# Показати всі хуки (додайте --eligible, --verbose або --json) openclaw hooks list -# Показати докладну інформацію про хук +# Показати детальну інформацію про хук openclaw hooks info -# Показати зведення придатності +# Показати зведення відповідності openclaw hooks check # Увімкнути/вимкнути @@ -291,25 +291,25 @@ openclaw hooks disable ## Найкращі практики -- **Підтримуйте швидку роботу обробників.** Хуки виконуються під час обробки команд. Для важкої роботи використовуйте fire-and-forget через `void processInBackground(event)`. -- **Коректно обробляйте помилки.** Обгортайте ризиковані операції в try/catch; не кидайте винятки, щоб інші обробники теж могли виконатися. -- **Фільтруйте події якомога раніше.** Відразу повертайтеся, якщо тип/дія події не стосується вашого випадку. +- **Робіть обробники швидкими.** Хуки виконуються під час обробки команд. Запускайте важку роботу у фоновому режимі через `void processInBackground(event)`. +- **Коректно обробляйте помилки.** Обгортайте ризиковані операції в try/catch; не кидайте винятки, щоб інші обробники могли виконатися. +- **Фільтруйте події рано.** Одразу повертайтеся, якщо тип/дія події не є релевантними. - **Використовуйте конкретні ключі подій.** Надавайте перевагу `"events": ["command:new"]` замість `"events": ["command"]`, щоб зменшити накладні витрати. -## Усунення несправностей +## Усунення проблем ### Хук не виявлено ```bash -# Перевірити структуру каталогу +# Перевірити структуру директорії ls -la ~/.openclaw/hooks/my-hook/ # Має показати: HOOK.md, handler.ts -# Перелічити всі виявлені хуки +# Показати всі виявлені хуки openclaw hooks list ``` -### Хук непридатний +### Хук не відповідає вимогам ```bash openclaw hooks info my-hook @@ -319,7 +319,7 @@ openclaw hooks info my-hook ### Хук не виконується -1. Переконайтеся, що хук увімкнено: `openclaw hooks list` +1. Переконайтеся, що хук увімкнений: `openclaw hooks list` 2. Перезапустіть процес gateway, щоб хуки перезавантажилися. 3. Перевірте логи gateway: `./scripts/clawlog.sh | grep hook` @@ -327,5 +327,5 @@ openclaw hooks info my-hook - [Довідник CLI: hooks](/uk/cli/hooks) - [Webhooks](/uk/automation/cron-jobs#webhooks) -- [Plugin hooks](/uk/plugins/hooks) — внутрішньопроцесні хуки життєвого циклу плагіна +- [Plugin hooks](/uk/plugins/hooks) — in-process хуки життєвого циклу плагінів - [Конфігурація](/uk/gateway/configuration-reference#hooks) diff --git a/docs/uk/ci.md b/docs/uk/ci.md index 943bee04d..1c35e2732 100644 --- a/docs/uk/ci.md +++ b/docs/uk/ci.md @@ -2,59 +2,42 @@ read_when: - Вам потрібно зрозуміти, чому завдання CI запустилося або не запустилося - Ви налагоджуєте збої перевірок GitHub Actions -summary: Граф завдань CI, пороги охоплення та локальні еквіваленти команд -title: Конвеєр CI +summary: Граф завдань CI, шлюзи області змін і локальні еквіваленти команд +title: пайплайн CI x-i18n: - generated_at: "2026-04-26T22:39:59Z" + generated_at: "2026-04-26T23:10:40Z" model: gpt-5.4 provider: openai - source_hash: da03ca18ec9d3cc7057ce33d22fc692a2e0735e5bc88fedec7cfc1e144d49cd6 + source_hash: b84dd1e40ca04120d8a4a9c53e1c2cca682920e89f4f6f181d6720be7a731b91 source_path: ci.md workflow: 15 --- -CI запускається для кожного push до `main` і для кожного pull request. Він використовує розумне визначення охоплення, щоб пропускати дорогі завдання, коли змінено лише не пов’язані ділянки. +CI запускається під час кожного push у `main` і для кожного pull request. Він використовує розумне визначення області змін, щоб пропускати дорогі завдання, коли змінено лише непов’язані ділянки. -QA Lab має окремі доріжки CI поза основним робочим процесом із розумним визначенням охоплення. Робочий процес -`Parity gate` запускається для PR зі відповідними змінами та через ручний запуск; він -збирає приватне середовище виконання QA і порівнює агентні набори mock GPT-5.5 і Opus 4.6. -Робочий процес `QA-Lab - All Lanes` запускається щоночі на `main` і через -ручний запуск; він розгалужує mock parity gate, live-доріжку Matrix і live-доріжку -Telegram як паралельні завдання. Live-завдання використовують середовище `qa-live-shared`, -а доріжка Telegram використовує оренди Convex. `OpenClaw Release -Checks` також запускає ті самі доріжки QA Lab перед погодженням релізу. +QA Lab має окремі лінії CI поза основним workflow з розумним визначенням області змін. Workflow `Parity gate` запускається для PR зі змінами, що відповідають умовам, і через ручний dispatch; він +збирає приватне середовище виконання QA і порівнює агентні набори mock GPT-5.5 та Opus 4.6. Workflow `QA-Lab - All Lanes` запускається щоночі на `main` і через +ручний dispatch; він розгалужує mock parity gate, live-лінію Matrix і live-лінію +Telegram у вигляді паралельних завдань. Live-завдання використовують середовище `qa-live-shared`, +а лінія Telegram використовує оренди Convex. `OpenClaw Release +Checks` також запускає ті самі лінії QA Lab перед затвердженням релізу. -Робочий процес `Duplicate PRs After Merge` — це ручний робочий процес для мейнтейнерів для -очищення дублікатів після злиття. За замовчуванням він працює в режимі dry-run і закриває лише явно -вказані PR, коли `apply=true`. Перш ніж змінювати стан у GitHub, він перевіряє, -що злитий PR справді змерджено і що кожен дублікат має або спільну згадану issue, -або перетин змінених фрагментів. +Workflow `Duplicate PRs After Merge` — це ручний workflow для супровідників для очищення дублікатів після злиття. За замовчуванням він працює в режимі dry-run і закриває лише явно вказані PR, коли `apply=true`. Перед зміною стану на GitHub він перевіряє, що злитий PR справді об’єднано, і що кожен дублікат має або спільний згаданий issue, +або перетин змінених hunk-ів. -Робочий процес `Docs Agent` — це керована подіями доріжка обслуговування Codex для підтримання -наявної документації у відповідності до нещодавно злитих змін. Він не має суто планового запуску: -його може запустити успішний неботовий запуск CI після push у `main`, а -ручний запуск може виконати його безпосередньо. Запуски через workflow-run пропускаються, -коли `main` уже просунувся вперед або коли за останню годину вже було створено -інший непропущений запуск Docs Agent. Коли він виконується, він -переглядає діапазон комітів від SHA джерела попереднього непропущеного Docs Agent до +Workflow `Docs Agent` — це керована подіями лінія обслуговування Codex для підтримки +наявної документації у відповідності до нещодавно злитих змін. Вона не має окремого запуску за розкладом: її може запустити успішний не-ботовий прогін CI після push у `main`, а ручний dispatch може +запустити її безпосередньо. Виклики через workflow_run пропускаються, якщо `main` уже просунувся далі або якщо за останню годину вже було створено інший непропущений запуск Docs Agent. Коли вона виконується, вона +переглядає діапазон комітів від source SHA попереднього непропущеного Docs Agent до поточного `main`, тож один щогодинний запуск може охопити всі зміни в main, накопичені -з моменту останнього проходу документації. +з часу останнього проходу документації. -Робочий процес `Test Performance Agent` — це керована подіями доріжка обслуговування Codex -для повільних тестів. Він не має суто планового запуску: його може запустити -успішний неботовий запуск CI після push у `main`, але він пропускається, якщо -інший запуск через workflow-run уже виконався або виконується в той UTC-день. -Ручний запуск обходить це денне обмеження активності. Доріжка збирає звіт про продуктивність -Vitest для повного набору тестів із групуванням, дозволяє Codex вносити лише невеликі -виправлення продуктивності тестів без зменшення покриття замість широких рефакторингів, потім -повторно запускає звіт для повного набору і відхиляє зміни, які зменшують -кількість тестів базової лінії, що проходять. Якщо в базовій лінії є тести, що падають, -Codex може виправляти лише очевидні збої, а звіт для повного набору після роботи агента -має пройти, перш ніж щось буде закомічено. Коли `main` просувається вперед до того, -як push бота буде злитий, доріжка перебазовує перевірений патч, повторно запускає -`pnpm check:changed` і повторює спробу push; застарілі конфліктні патчі пропускаються. -Вона використовує GitHub-hosted Ubuntu, щоб дія Codex могла -зберігати ту саму безпечну політику без `sudo`, що й docs agent. +Workflow `Test Performance Agent` — це керована подіями лінія обслуговування Codex +для повільних тестів. Вона не має окремого запуску за розкладом: її може запустити успішний не-ботовий прогін CI після push у `main`, але вона пропускається, якщо інший виклик через workflow_run уже виконався або виконується в ту саму добу UTC. Ручний dispatch обходить це денне обмеження активності. Лінія збирає повний згрупований звіт продуктивності Vitest, дозволяє Codex +вносити лише невеликі зміни продуктивності тестів без втрати покриття замість широких рефакторингів, потім повторно запускає повний звіт і відхиляє зміни, які зменшують кількість тестів, що проходять, у базовому стані. Якщо в базовому стані є тести, що падають, Codex може виправляти лише очевидні збої, а повний звіт після роботи агента має пройти, перш ніж щось буде закомічено. Коли `main` просувається далі до того, як bot push буде застосовано, лінія +робить rebase перевіреного патча, повторно запускає `pnpm check:changed` і повторює push; +застарілі патчі з конфліктами пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб дія Codex +могла зберігати ту саму безпечну політику drop-sudo, що й агент документації. ```bash gh workflow run duplicate-after-merge.yml \ @@ -65,87 +48,88 @@ gh workflow run duplicate-after-merge.yml \ ## Огляд завдань -| Завдання | Призначення | Коли запускається | -| --------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------ | -| `preflight` | Визначає зміни лише в документації, змінені області охоплення, змінені extensions і формує маніфест CI | Завжди для недрафтових push і PR | -| `security-scm-fast` | Виявлення приватних ключів і аудит робочих процесів через `zizmor` | Завжди для недрафтових push і PR | -| `security-dependency-audit` | Аудит production lockfile без залежностей щодо advisory npm | Завжди для недрафтових push і PR | -| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для недрафтових push і PR | -| `build-artifacts` | Збирає `dist/`, Control UI, перевірки зібраних артефактів і повторно використовувані downstream-артефакти | Зміни, релевантні для Node | -| `checks-fast-core` | Швидкі доріжки перевірки коректності на Linux, як-от bundled/plugin-contract/protocol checks | Зміни, релевантні для Node | -| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом | Зміни, релевантні для Node | -| `checks-node-extensions` | Повні шарди тестів bundled plugins для всього набору extensions | Зміни, релевантні для Node | -| `checks-node-core-test` | Шарди core Node тестів, окрім доріжок channel, bundled, contract і extension | Зміни, релевантні для Node | -| `extension-fast` | Цільові тести лише для змінених bundled plugins | Pull request зі змінами в extension | -| `check` | Шардований еквівалент основного локального порогу: prod types, lint, guards, test types і strict smoke | Зміни, релевантні для Node | -| `check-additional` | Шарди для архітектури, меж, захисту поверхні extension, меж пакетів і gateway-watch | Зміни, релевантні для Node | -| `build-smoke` | Smoke-тести зібраного CLI і smoke-тест пам’яті під час запуску | Зміни, релевантні для Node | -| `checks` | Верифікатор для тестів каналів на зібраних артефактах плюс сумісність Node 22 лише для push | Зміни, релевантні для Node | -| `check-docs` | Форматування документації, lint і перевірки битих посилань | Документацію змінено | -| `skills-python` | Ruff + pytest для Skills на Python | Зміни, релевантні для Python Skills | -| `checks-windows` | Специфічні для Windows доріжки тестів | Зміни, релевантні для Windows | -| `macos-node` | Доріжка тестів TypeScript на macOS із використанням спільних зібраних артефактів | Зміни, релевантні для macOS | -| `macos-swift` | Swift lint, збірка і тести для застосунку macOS | Зміни, релевантні для macOS | -| `android` | Android unit-тести для обох flavor плюс одна debug APK-збірка | Зміни, релевантні для Android | -| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успіх main CI або ручний запуск | +| Job | Призначення | Коли запускається | +| -------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------ | +| `preflight` | Виявлення змін лише в документації, змінених областей, змінених розширень і побудова CI manifest | Завжди для non-draft push і PR | +| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для non-draft push і PR | +| `security-dependency-audit` | Аудит production lockfile без залежностей щодо advisory npm | Завжди для non-draft push і PR | +| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для non-draft push і PR | +| `build-artifacts` | Збирання `dist/`, Control UI, перевірки зібраних артефактів і повторно використовувані downstream-артефакти | Зміни, пов’язані з Node | +| `checks-fast-core` | Швидкі лінії коректності Linux, такі як перевірки bundled/plugin-contract/protocol | Зміни, пов’язані з Node | +| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, пов’язані з Node | +| `checks-node-extensions` | Повні шарди тестів bundled-plugin для всього набору розширень | Зміни, пов’язані з Node | +| `checks-node-core-test` | Шарди основних тестів Node, за винятком ліній каналів, bundled, contracts і extensions | Зміни, пов’язані з Node | +| `extension-fast` | Цільові тести лише для змінених bundled plugin | Pull request зі змінами розширень | +| `check` | Шардований еквівалент основного локального шлюзу: production types, lint, guards, test types і strict smoke | Зміни, пов’язані з Node | +| `check-additional` | Шарди архітектури, меж, guards поверхні розширень, package-boundary і gateway-watch | Зміни, пов’язані з Node | +| `build-smoke` | Smoke-тести зібраного CLI і smoke-перевірка пам’яті під час запуску | Зміни, пов’язані з Node | +| `checks` | Верифікатор для built-artifact тестів каналів плюс сумісність Node 22 лише для push | Зміни, пов’язані з Node | +| `check-docs` | Перевірки форматування документації, lint і пошкоджених посилань | Документацію змінено | +| `skills-python` | Ruff + pytest для Skills на базі Python | Зміни, релевантні Python Skills | +| `checks-windows` | Специфічні для Windows тестові лінії | Зміни, релевантні Windows | +| `macos-node` | Лінія тестів TypeScript на macOS із використанням спільних зібраних артефактів | Зміни, релевантні macOS | +| `macos-swift` | Lint, збирання і тести Swift для застосунку macOS | Зміни, релевантні macOS | +| `android` | Модульні тести Android для обох flavor плюс одне збирання debug APK | Зміни, релевантні Android | +| `test-performance-agent` | Щоденна оптимізація повільних тестів через Codex після довіреної активності | Успішний main CI або ручний dispatch | ## Порядок fail-fast -Завдання впорядковані так, щоб дешеві перевірки завершувалися з помилкою раніше, ніж запускатимуться дорогі: +Завдання впорядковано так, щоб дешеві перевірки завершувалися помилкою раніше, ніж запустяться дорогі: -1. `preflight` вирішує, які доріжки взагалі існують. Логіка `docs-scope` і `changed-scope` — це кроки всередині цього завдання, а не окремі завдання. -2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` завершуються швидко з помилкою, не чекаючи важчих завдань для артефактів і платформних матриць. -3. `build-artifacts` виконується паралельно зі швидкими Linux-доріжками, щоб downstream-споживачі могли почати роботу, щойно спільна збірка буде готова. -4. Після цього розгалужуються важчі платформні та runtime-доріжки: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, PR-only `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. +1. `preflight` вирішує, які лінії взагалі існують. Логіка `docs-scope` і `changed-scope` — це кроки всередині цього завдання, а не окремі завдання. +2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко завершуються з помилкою, не очікуючи важчих матричних завдань артефактів і платформ. +3. `build-artifacts` виконується паралельно зі швидкими Linux-лініями, щоб downstream-споживачі могли почати роботу, щойно буде готове спільне збирання. +4. Після цього розгалужуються важчі платформні лінії та лінії середовища виконання: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, лише для PR `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. -Логіка визначення охоплення міститься в `scripts/ci-changed-scope.mjs` і покрита unit-тестами в `src/scripts/ci-changed-scope.test.ts`. -Редагування робочих процесів CI перевіряють граф Node CI та lint робочих процесів, але самі по собі не змушують запускати нативні збірки для Windows, Android або macOS; ці платформні доріжки, як і раніше, обмежуються змінами у вихідному коді відповідної платформи. -Редагування лише маршрутизації CI, окремі дешеві зміни фікстур core-тестів і вузькі зміни helper/test-routing для контрактів plugins використовують швидкий шлях маніфесту лише для Node: preflight, security і єдине завдання `checks-fast-core`. Цей шлях обходить build artifacts, сумісність Node 22, контракти каналів, повні шарди core, шарди bundled plugins і додаткові матриці guard, коли змінені файли обмежені поверхнями маршрутизації або helper, які швидке завдання перевіряє безпосередньо. -Перевірки Windows Node обмежуються специфічними для Windows обгортками process/path, helper для запуску npm/pnpm/UI, конфігурацією менеджера пакетів і поверхнями робочих процесів CI, які виконують цю доріжку; нерелевантні зміни у вихідному коді, plugins, install-smoke та зміни лише в тестах залишаються на Linux Node-доріжках, щоб не резервувати Windows worker із 16 vCPU для покриття, яке вже перевіряється звичайними шардами тестів. -Окремий робочий процес `install-smoke` повторно використовує той самий script для охоплення через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Pull request запускають швидкий шлях для поверхонь Docker/package, змін package/manifest bundled plugins і core-поверхонь plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke-завдання. Зміни лише у вихідному коді bundled plugins, зміни лише в тестах і зміни лише в документації не резервують Docker workers. Швидкий шлях один раз збирає образ із root Dockerfile, перевіряє CLI, запускає CLI smoke для agents delete shared-workspace, запускає container gateway-network e2e, перевіряє аргумент збірки bundled extension і запускає обмежений Docker profile bundled-plugin з агрегованим timeout команди у 240 секунд, де для кожного сценарію окремо обмежено `docker run`. Повний шлях зберігає QR package install і покриття installer Docker/update для нічних запусків за розкладом, ручних запусків, release checks через workflow-call і pull request, які справді зачіпають поверхні installer/package/Docker. Push у `main`, включно з merge-комітами, не примушують повний шлях; коли логіка changed-scope запитує повне покриття для push, робочий процес залишає швидкий Docker smoke, а повний install smoke віддає нічній або релізній валідації. Повільний smoke для Bun global install image-provider окремо керується через `run_bun_global_install_smoke`; він запускається в нічному розкладі та з робочого процесу release checks, а ручні запуски `install-smoke` можуть явно його увімкнути, але pull request і push у `main` його не запускають. Тести QR і installer Docker зберігають власні Dockerfile, орієнтовані на встановлення. Локальний `test:docker:all` попередньо збирає один спільний образ live-test, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: базовий runner Node/Git для доріжок installer/update/plugin-dependency і функціональний образ, який встановлює той самий tarball у `/app` для звичайних функціональних доріжок. Визначення Docker-доріжок містяться в `scripts/lib/docker-e2e-scenarios.mjs`, логіка планувальника — в `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний план. Планувальник вибирає образ для доріжки через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає доріжки з `OPENCLAW_SKIP_DOCKER_BUILD=1`; типову кількість слотів основного пулу 10 можна налаштувати через `OPENCLAW_DOCKER_ALL_PARALLELISM`, а кількість слотів tail-пулу 10, чутливого до provider, — через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження для важких доріжок за замовчуванням: `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб доріжки npm install і багатосервісні доріжки не перевантажували Docker, поки легші доріжки все ще заповнюють доступні слоти. Запуск доріжок за замовчуванням зсувається на 2 секунди, щоб уникнути локальних штормів створення в Docker daemon; це можна перевизначити через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний агрегований запуск попередньо перевіряє Docker, видаляє застарілі контейнери OpenClaw E2E, виводить статус активних доріжок, зберігає час виконання доріжок для впорядкування за принципом longest-first і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для перевірки планувальника. За замовчуванням він припиняє планувати нові pooled-доріжки після першої помилки, і кожна доріжка має резервний timeout 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail-доріжки використовують жорсткіші обмеження для кожної доріжки. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні доріжки планувальника, включно з доріжками лише для релізу, як-от `install-e2e`, і розділеними доріжками оновлення bundled, як-от `bundled-channel-update-acpx`, водночас пропускаючи cleanup smoke, щоб агенти могли відтворити одну зламану доріжку. Повторно використовуваний робочий процес live/E2E запитує в `scripts/test-docker-all.mjs --plan-json`, яке package, тип образу, live-образ, доріжка та покриття credentials потрібні, після чого `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і summary. Він пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, збирає та пушить один bare GHCR Docker E2E image із тегом SHA, коли план потребує доріжок install/update/plugin-dependency, і збирає один functional GHCR Docker E2E image із тегом SHA, коли план потребує функціональних доріжок із встановленим package. Docker-набір для релізного шляху запускається максимум як три chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний йому тип образу й виконував кілька доріжок через той самий зважений планувальник (`OPENCLAW_DOCKER_ALL_PROFILE=release-path`, `OPENCLAW_DOCKER_ALL_CHUNK=core|package-update|plugins-integrations`). Кожен chunk завантажує `.artifacts/docker-tests/` із логами доріжок, таймінгами, `summary.json`, таймінгами фаз, JSON-планом планувальника та командами повторного запуску для кожної доріжки. Вхід `docker_lanes` робочого процесу запускає вибрані доріжки на підготовлених образах замість трьох chunked jobs, що обмежує налагодження зламаної доріжки одним цільовим Docker job; якщо вибрана доріжка є live Docker-доріжкою, цільове завдання локально збирає live-test image для такого повторного запуску. Коли для release-path suite запитується Open WebUI, він виконується всередині chunk plugins/integrations замість резервування четвертого Docker worker; Open WebUI зберігає окреме завдання лише для dispatch, призначених тільки для openwebui. Запланований робочий процес live/E2E щодня запускає повний release-path Docker suite. Матриця bundled update розділена за ціллю оновлення, щоб повторні проходи npm update і doctor repair могли шардитися разом з іншими bundled-перевірками. +Логіка області змін живе в `scripts/ci-changed-scope.mjs` і покривається модульними тестами в `src/scripts/ci-changed-scope.test.ts`. +Зміни workflow CI перевіряють граф Node CI разом із lint-перевіркою workflow, але самі по собі не примушують запускати нативні збірки Windows, Android або macOS; ці платформні лінії й надалі обмежуються змінами у вихідному коді відповідних платформ. +Зміни лише маршрутизації CI, окремі дешеві зміни fixture для core-тестів і вузькі зміни helper/test-routing для контрактів plugin використовують швидкий шлях маніфесту лише для Node: preflight, security і одне завдання `checks-fast-core`. Цей шлях уникає build artifacts, сумісності з Node 22, контрактів каналів, повних shard core, shard bundled-plugin і додаткових матриць guard, коли змінені файли обмежені поверхнями маршрутизації або helper, які швидке завдання безпосередньо перевіряє. +Перевірки Windows Node обмежені Windows-специфічними обгортками процесів/шляхів, helper для npm/pnpm/UI runner, конфігурацією package manager і поверхнями workflow CI, які запускають цю лінію; не пов’язані зміни у вихідному коді, plugin, install-smoke і зміни лише в тестах залишаються на Linux Node-лініях, щоб не резервувати 16-vCPU Windows worker для покриття, яке вже перевіряється звичайними shard тестів. +Окремий workflow `install-smoke` повторно використовує той самий скрипт визначення області через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Для pull request запускається швидкий шлях для поверхонь Docker/package, змін package/manifest bundled plugin і поверхонь core plugin/channel/gateway/Plugin SDK, які використовують Docker smoke-завдання. Зміни лише у вихідному коді bundled plugin, зміни лише в тестах і зміни лише в документації не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає CLI smoke `agents delete shared-workspace`, запускає container gateway-network e2e, перевіряє аргумент збірки bundled extension і запускає обмежений Docker profile для bundled-plugin із загальним тайм-аутом команди 240 секунд, де кожен сценарій `docker run` має власне окреме обмеження. Повний шлях зберігає QR package install і покриття installer Docker/update для нічних запусків за розкладом, ручних dispatch, workflow-call перевірок релізу і pull request, які справді зачіпають поверхні installer/package/Docker. Push у `main`, включно з merge-комітами, не примушують повний шлях; коли логіка changed-scope запросила б повне покриття для push, workflow зберігає швидкий Docker smoke і залишає повний install smoke для нічної перевірки або валідації релізу. Повільний smoke Bun global install image-provider окремо контролюється через `run_bun_global_install_smoke`; він запускається за нічним розкладом і з workflow перевірок релізу, а ручні dispatch `install-smoke` можуть явно його ввімкнути, але pull request і push у `main` його не запускають. QR і installer Docker-тести зберігають власні Dockerfile, орієнтовані на встановлення. Локальна команда `test:docker:all` попередньо збирає один спільний live-test image, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: базовий runner Node/Git для ліній installer/update/plugin-dependency і функціональний образ, який встановлює той самий tarball у `/app` для звичайних функціональних ліній. Визначення Docker-ліній живуть у `scripts/lib/docker-e2e-scenarios.mjs`, логіка planner — у `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний план. Планувальник вибирає образ для кожної лінії через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає лінії з `OPENCLAW_SKIP_DOCKER_BUILD=1`; налаштовуйте типову кількість слотів основного пулу 10 через `OPENCLAW_DOCKER_ALL_PARALLELISM` і кількість слотів tail-пулу, чутливого до provider, 10 через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження для важких ліній за замовчуванням: `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб лінії npm install і multi-service не перевантажували Docker, тоді як легші лінії й далі заповнюють доступні слоти. Запуски ліній за замовчуванням зміщуються на 2 секунди, щоб уникати локальних штормів create в Docker daemon; перевизначайте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний агрегатний запуск попередньо перевіряє Docker, видаляє застарілі контейнери OpenClaw E2E, виводить статус активних ліній, зберігає час виконання ліній для порядку longest-first і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для перевірки планувальника. За замовчуванням він припиняє планування нових pooled-ліній після першої помилки, і кожна лінія має запасний тайм-аут 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; окремі live/tail-лінії використовують жорсткіші індивідуальні обмеження. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні лінії планувальника, включно з лініями лише для релізу, як-от `install-e2e`, і розділеними лініями оновлення bundled, як-от `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб агенти могли відтворити одну збоїлу лінію. Повторно використовуваний workflow live/E2E запитує в `scripts/test-docker-all.mjs --plan-json`, яке package, image kind, live image, lane і покриття credentials потрібні, після чого `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і summary. Він пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, перевіряє inventory tarball, збирає і публікує один Docker E2E образ bare GHCR з тегом SHA, коли плану потрібні лінії install/update/plugin-dependency, і збирає один Docker E2E образ functional GHCR з тегом SHA, коли плану потрібні лінії функціональності зі встановленим package; якщо будь-який із цих образів із тегом SHA вже існує, workflow пропускає його повторну збірку, але все одно створює свіжий tarball artifact, потрібний для цільових повторних запусків. Docker-набір для шляху релізу запускається максимум як три chunked-завдання з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний йому тип образу і виконував кілька ліній через той самий зважений планувальник (`OPENCLAW_DOCKER_ALL_PROFILE=release-path`, `OPENCLAW_DOCKER_ALL_CHUNK=core|package-update|plugins-integrations`). Кожен chunk завантажує `.artifacts/docker-tests/` із логами ліній, часами виконання, `summary.json`, `failures.json`, часами етапів, JSON плану планувальника і командами повторного запуску для кожної лінії. Вхід `docker_lanes` workflow запускає вибрані лінії проти підготовлених образів замість трьох chunked-завдань, що обмежує налагодження збоїлої лінії одним цільовим Docker-завданням і готує свіжий npm tarball для вибраного ref; якщо вибрана лінія є live Docker-лінією, цільове завдання локально збирає live-test image для цього повторного запуску. Використовуйте `pnpm test:docker:rerun `, щоб завантажити Docker artifacts із GitHub run і вивести комбіновані/поканальні команди цільового повторного запуску; використовуйте `pnpm test:docker:timings ` для підсумків повільних ліній і критичного шляху фаз. Коли для release-path suite запитується Open WebUI, він виконується всередині chunk `plugins/integrations`, а не резервує четвертий Docker worker; Open WebUI зберігає окреме standalone-завдання лише для dispatch, що стосуються тільки openwebui. Запланований workflow live/E2E щодня запускає повний release-path Docker suite. Матриця bundled update розділена за ціллю оновлення, щоб повторні проходи npm update і doctor repair могли шардитися разом з іншими bundled-перевірками. -Локальна логіка changed-lane міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний поріг суворіший щодо архітектурних меж, ніж широке CI-охоплення платформ: зміни в core production запускають typecheck core prod плюс core-тести, зміни лише в core-тестах запускають лише typecheck/tests для core-тестів, зміни в extension production запускають typecheck extension prod плюс extension-тести, а зміни лише в extension-тестах запускають лише typecheck/tests для extension-тестів. Зміни в публічному Plugin SDK або plugin-contract розширюють валідацію на extensions, оскільки extensions залежать від цих core-контрактів. Підвищення версії лише в release metadata запускають цільові перевірки version/config/root-dependency. Невідомі зміни в root/config безпечно переводять виконання на всі доріжки. +Локальна логіка changed-lane живе в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний шлюз перевірки суворіший щодо архітектурних меж, ніж широка CI-область платформ: зміни core production запускають перевірку типів core prod і core test разом із core lint/guards, зміни лише в core-тестах запускають лише перевірку типів core test і core lint, зміни extension production запускають перевірку типів extension prod і extension test разом із extension lint, а зміни лише в extension-тестах запускають перевірку типів extension test і extension lint. Зміни у публічному Plugin SDK або plugin-contract розширюють перевірку до typecheck extension, бо extensions залежать від цих core-контрактів, але повні проходи Vitest для extension — це явна тестова робота. Версійні зміни лише в метаданих релізу запускають цільові перевірки version/config/root-dependency. Невідомі зміни в root/config безпечно розширюються до всіх ліній перевірки. -Для push матриця `checks` додає доріжку `compat-node22`, що запускається лише для push. Для pull request ця доріжка пропускається, і матриця залишається зосередженою на звичайних тестових доріжках і доріжках каналів. +Під час push матриця `checks` додає лінію лише для push `compat-node22`. Для pull request ця лінія пропускається, і матриця залишається зосередженою на звичайних лініях тестів/каналів. -Найповільніші сімейства Node-тестів розділені або збалансовані так, щоб кожне завдання залишалося невеликим без надмірного резервування runner-ів: контракти каналів виконуються як три зважені шарди, тести bundled plugins балансуються між шістьма workers для extension, малі unit-доріжки core попарно поєднуються, auto-reply виконується на чотирьох збалансованих workers із розбиттям піддерева reply на шарди agent-runner, dispatch і commands/state-routing, а конфігурації agentic gateway/plugin розподіляються між наявними Node-завданнями agentic лише для source, замість очікування на build artifacts. Широкі browser-, QA-, media- і miscellaneous plugin-тести використовують свої окремі конфігурації Vitest замість спільного універсального набору для plugins. Завдання шардів extension одночасно запускають до двох груп конфігурацій plugins з одним worker Vitest на групу і більшим heap Node, щоб batch-набори plugins з важкими import не створювали додаткових завдань CI. Широка доріжка agents використовує спільний file-parallel scheduler Vitest, оскільки її визначають imports/планування, а не один повільний тестовий файл. `runtime-config` запускається разом із шардом infra core-runtime, щоб спільний runtime-shard не залишався хвостовим. Шарди за include-pattern записують таймінги з використанням назви CI-shard, тож `.artifacts/vitest-shard-timings.json` може відрізняти цілу конфігурацію від відфільтрованого shard. `check-additional` тримає разом compile/canary-роботи для package-boundary і відокремлює архітектуру runtime topology від покриття gateway watch; shard boundary guard виконує свої невеликі незалежні guard-перевірки паралельно в межах одного завдання. Gateway watch, тести каналів і shard core support-boundary виконуються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи свої попередні назви перевірок як легкі завдання-верифікатори та уникаючи двох додаткових Blacksmith workers і другої черги споживачів артефактів. -Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Flavor third-party не має окремого source set або manifest; його доріжка unit-тестів усе одно компілює цей flavor з прапорцями SMS/call-log у BuildConfig, водночас уникаючи дубльованого пакування debug APK для кожного push, релевантного для Android. -`extension-fast` є лише для PR, оскільки push-запуски вже виконують повні шарди bundled plugins. Це зберігає швидкий зворотний зв’язок для перевірки змінених plugins без резервування додаткового Blacksmith worker у `main` для покриття, яке вже присутнє в `checks-node-extensions`. +Найповільніші сімейства Node-тестів розділено або збалансовано так, щоб кожне завдання залишалося невеликим без надлишкового резервування runner-ів: контракти каналів виконуються як три зважені shard, тести bundled plugin балансуються між шістьма workers для extension, малі core unit-лінії об’єднані в пари, auto-reply виконується на чотирьох збалансованих workers із розділенням піддерева reply на shard `agent-runner`, `dispatch` і `commands/state-routing`, а конфігурації agentic gateway/plugin розподіляються по наявних Node-завданнях agentic лише для source замість очікування на built artifacts. Широкі тести browser, QA, media і miscellaneous plugin використовують власні конфігурації Vitest замість спільної універсальної конфігурації plugin. Shard-завдання extension одночасно запускають до двох груп конфігурацій plugin з одним worker Vitest на групу і збільшеною heap-пам’яттю Node, щоб batch-и plugin з важкими імпортами не створювали додаткові CI-завдання. Широка лінія agents використовує спільний file-parallel scheduler Vitest, оскільки в ній домінують імпорти/планування, а не один повільний тестовий файл. `runtime-config` запускається разом із shard `infra core-runtime`, щоб спільний runtime-shard не залишався «хвостом». Shard-и include-pattern записують значення часу з використанням назви CI-shard, тож `.artifacts/vitest-shard-timings.json` може відрізняти цілу конфігурацію від відфільтрованого shard. `check-additional` тримає разом package-boundary compile/canary-роботу і відокремлює архітектуру topology runtime від покриття gateway watch; shard boundary guard запускає свої невеликі незалежні guard-и паралельно всередині одного завдання. Gateway watch, channel-тести і shard support-boundary для core запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи свої старі назви перевірок як легкі завдання-верифікатори й уникаючи двох додаткових Blacksmith workers і другої черги споживачів artifact. +Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Flavor third-party не має окремого source set або manifest; його лінія модульних тестів однаково компілює цей flavor із прапорцями BuildConfig для SMS/call-log, уникаючи при цьому дубльованого завдання пакування debug APK при кожному Android-релевантному push. +`extension-fast` працює лише для PR, оскільки push-запуски вже виконують повні shard bundled plugin. Це зберігає швидкий зворотний зв’язок щодо змінених plugin під час review, не резервуючи додатковий Blacksmith worker у `main` для покриття, яке вже є в `checks-node-extensions`. -GitHub може позначати витіснені завдання як `cancelled`, коли новіший push потрапляє в той самий ref PR або `main`. Вважайте це шумом CI, якщо тільки найновіший запуск для того самого ref також не падає. Агреговані shard-перевірки використовують `!cancelled() && always()`, тож вони все ще повідомляють про звичайні збої shard-ів, але не стають у чергу після того, як увесь робочий процес уже було витіснено. -Ключ concurrency для CI має версіювання (`CI-v7-*`), щоб zombie-процес на боці GitHub у старій групі черги не міг безкінечно блокувати новіші запуски main. +GitHub може позначати витіснені завдання як `cancelled`, коли новіший push потрапляє в той самий PR або ref `main`. Вважайте це шумом CI, якщо лише найновіший запуск для того самого ref також не падає. Агреговані shard-перевірки використовують `!cancelled() && always()`, тож вони все одно повідомляють про звичайні збої shard, але не стають у чергу після того, як увесь workflow уже був витіснений. +Ключ конкурентності CI версіонується (`CI-v7-*`), щоб zombie-процес на боці GitHub у старій групі черги не міг безкінечно блокувати нові запуски main. ## Runner-и -| Runner | Завдання | -| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки та агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки protocol/contract/bundled, шардовані перевірки контрактів каналів, шарди `check`, крім lint, шарди й агрегати `check-additional`, агреговані верифікатори Node-тестів, перевірки docs, Python Skills, workflow-sanity, labeler, auto-response; preflight для install-smoke також використовує GitHub-hosted Ubuntu, щоб матриця Blacksmith могла ставати в чергу раніше | -| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, шарди Linux Node-тестів, шарди тестів bundled plugins, `android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який усе ще достатньо чутливий до CPU, тож 8 vCPU коштували дорожче, ніж давали вигоди; Docker-збірки install-smoke, де час очікування в черзі для 32 vCPU коштував дорожче, ніж давав вигоди | -| `blacksmith-16vcpu-windows-2025` | `checks-windows` | -| `blacksmith-6vcpu-macos-latest` | `macos-node` у `openclaw/openclaw`; для форків використовується резервний перехід на `macos-latest` | -| `blacksmith-12vcpu-macos-latest` | `macos-swift` у `openclaw/openclaw`; для форків використовується резервний перехід на `macos-latest` | +| Runner | Завдання | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки й агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки protocol/contract/bundled, шардовані перевірки контрактів каналів, шарди `check`, крім lint, шарди й агрегати `check-additional`, агрегатні верифікатори Node-тестів, перевірки документації, Python Skills, workflow-sanity, labeler, auto-response; preflight для install-smoke також використовує GitHub-hosted Ubuntu, щоб матриця Blacksmith могла стати в чергу раніше | +| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, шарди Linux Node-тестів, шарди тестів bundled plugin, `android` | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який і далі достатньо чутливий до CPU, тож 8 vCPU коштували дорожче, ніж заощаджували; Docker-збірки install-smoke, де час очікування в черзі для 32-vCPU коштував дорожче, ніж заощаджував | +| `blacksmith-16vcpu-windows-2025` | `checks-windows` | +| `blacksmith-6vcpu-macos-latest` | `macos-node` у `openclaw/openclaw`; для fork використовується fallback до `macos-latest` | +| `blacksmith-12vcpu-macos-latest` | `macos-swift` у `openclaw/openclaw`; для fork використовується fallback до `macos-latest` | ## Локальні еквіваленти ```bash pnpm changed:lanes # перевірити локальний класифікатор changed-lane для origin/main...HEAD -pnpm check:changed # розумний локальний поріг: changed typecheck/lint/tests за boundary lane -pnpm check # швидкий локальний поріг: production tsgo + шардований lint + паралельні швидкі guard-перевірки +pnpm check:changed # розумний локальний шлюз перевірок: changed typecheck/lint/guards за граничною лінією +pnpm check # швидкий локальний шлюз: production tsgo + шардований lint + паралельні швидкі guards pnpm check:test-types -pnpm check:timed # той самий поріг із таймінгами для кожного етапу +pnpm check:timed # той самий шлюз із часом виконання для кожного етапу pnpm build:strict-smoke pnpm check:architecture pnpm test:gateway:watch-regression pnpm test # тести vitest +pnpm test:changed # дешеві розумні цільові changed-запуски Vitest pnpm test:channels pnpm test:contracts:channels -pnpm check:docs # форматування docs + lint + биті посилання -pnpm build # збірка dist, коли важливі доріжки CI artifact/build-smoke +pnpm check:docs # форматування документації + lint + пошкоджені посилання +pnpm build # зібрати dist, коли важливі CI-лінії artifact/build-smoke pnpm ci:timings # підсумок останнього запуску push CI для origin/main pnpm ci:timings:recent # порівняти нещодавні успішні запуски main CI -node scripts/ci-run-timings.mjs # підсумок wall time, queue time і найповільніших завдань -node scripts/ci-run-timings.mjs --latest-main # ігнорувати шум від issue/comment і вибрати push CI для origin/main +node scripts/ci-run-timings.mjs # підсумувати wall time, queue time і найповільніші завдання +node scripts/ci-run-timings.mjs --latest-main # ігнорувати шум issue/comment і вибрати push CI для origin/main node scripts/ci-run-timings.mjs --recent 10 # порівняти нещодавні успішні запуски main CI pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json diff --git a/docs/uk/gateway/bonjour.md b/docs/uk/gateway/bonjour.md index 06372248c..0e3744078 100644 --- a/docs/uk/gateway/bonjour.md +++ b/docs/uk/gateway/bonjour.md @@ -1,42 +1,42 @@ --- read_when: - Налагодження проблем виявлення Bonjour на macOS/iOS - - Зміна типів сервісів mDNS, записів TXT або UX виявлення -summary: Виявлення та налагодження Bonjour/mDNS (маяки Gateway, клієнти та типові режими відмови) + - Зміна типів сервісів mDNS, TXT-записів або UX виявлення +summary: Виявлення та налагодження Bonjour/mDNS (маяки Gateway, клієнти та поширені режими відмов) title: Виявлення Bonjour x-i18n: - generated_at: "2026-04-26T04:59:44Z" + generated_at: "2026-04-26T23:10:40Z" model: gpt-5.4 provider: openai - source_hash: b055021bdcd92740934823dea2acf758c6ec991a15c0a315426dc359a7eea093 + source_hash: abaec96c53233e697155fd62a2fa6af972ab039cb480af8246f96359b5036e1f source_path: gateway/bonjour.md workflow: 15 --- # Виявлення Bonjour / mDNS -OpenClaw використовує Bonjour (mDNS / DNS‑SD) для виявлення активного Gateway (кінцева точка WebSocket). -Багатоадресний перегляд `local.` — це **лише зручність у межах LAN**. Вбудований Plugin -`bonjour` відповідає за рекламу в LAN і ввімкнений за замовчуванням. Для виявлення між мережами +OpenClaw використовує Bonjour (mDNS / DNS‑SD) для виявлення активного Gateway (кінцевої точки WebSocket). +Багатоадресний перегляд `local.` — це **зручність лише для LAN**. Вбудований plugin `bonjour` +відповідає за рекламу в LAN і ввімкнений за замовчуванням. Для виявлення між мережами той самий маяк також можна опублікувати через налаштований домен wide-area DNS-SD. -Виявлення все одно працює за принципом best-effort і **не** замінює підключення через SSH або Tailnet. +Виявлення все одно залишається best-effort і **не** замінює підключення через SSH або Tailnet. ## Wide-area Bonjour (Unicast DNS-SD) через Tailscale -Якщо node і gateway перебувають у різних мережах, багатоадресний mDNS не перетинатиме +Якщо node і gateway перебувають у різних мережах, багатоадресний mDNS не перетне цю межу. Ви можете зберегти той самий UX виявлення, переключившись на **unicast DNS‑SD** ("Wide‑Area Bonjour") через Tailscale. -Загальні кроки: +Кроки високого рівня: 1. Запустіть DNS-сервер на хості gateway (доступний через Tailnet). 2. Опублікуйте записи DNS‑SD для `_openclaw-gw._tcp` у виділеній зоні (приклад: `openclaw.internal.`). -3. Налаштуйте **split DNS** у Tailscale так, щоб вибраний домен резолвився через цей - DNS-сервер для клієнтів (включно з iOS). +3. Налаштуйте в Tailscale **split DNS**, щоб вибраний вами домен резолвився через цей + DNS-сервер для клієнтів (зокрема iOS). OpenClaw підтримує будь-який домен виявлення; `openclaw.internal.` — лише приклад. -iOS/Android node переглядають і `local.`, і ваш налаштований wide-area домен. +Node на iOS/Android переглядають і `local.`, і ваш налаштований wide-area домен. ### Конфігурація Gateway (рекомендовано) @@ -53,10 +53,10 @@ iOS/Android node переглядають і `local.`, і ваш налашто openclaw dns setup --apply ``` -Це встановить CoreDNS і налаштує його так, щоб він: +Це встановлює CoreDNS і налаштовує його так, щоб він: -- слухав порт 53 лише на Tailscale-інтерфейсах gateway -- обслуговував вибраний домен (приклад: `openclaw.internal.`) з `~/.openclaw/dns/.db` +- слухав порт 53 лише на інтерфейсах Tailscale gateway +- обслуговував вибраний вами домен (приклад: `openclaw.internal.`) з `~/.openclaw/dns/.db` Перевірте з машини, підключеної до tailnet: @@ -72,52 +72,52 @@ dig @ -p 53 _openclaw-gw._tcp.openclaw.internal PTR +short - Додайте nameserver, що вказує на tailnet IP gateway (UDP/TCP 53). - Додайте split DNS, щоб ваш домен виявлення використовував цей nameserver. -Після того як клієнти приймуть DNS tailnet, iOS node і CLI-виявлення зможуть переглядати +Щойно клієнти приймуть DNS tailnet, node на iOS і виявлення CLI зможуть переглядати `_openclaw-gw._tcp` у вашому домені виявлення без багатоадресності. -### Безпека listener Gateway (рекомендовано) +### Безпека слухача Gateway (рекомендовано) -Порт Gateway WS (типово `18789`) за замовчуванням прив’язується до loopback. Для доступу через LAN/tailnet -явно вкажіть bind і залиште автентифікацію ввімкненою. +Порт WS Gateway (типово `18789`) за замовчуванням прив’язується до loopback. Для доступу через LAN/tailnet +явно задайте прив’язку та залиште автентифікацію ввімкненою. Для конфігурацій лише з tailnet: - Установіть `gateway.bind: "tailnet"` у `~/.openclaw/openclaw.json`. -- Перезапустіть Gateway (або перезапустіть застосунок macOS menubar). +- Перезапустіть Gateway (або перезапустіть застосунок macOS у рядку меню). ## Що рекламується -Лише Gateway рекламує `_openclaw-gw._tcp`. Реклама через багатоадресність у LAN -забезпечується вбудованим Plugin `bonjour`; публікація wide-area DNS-SD і надалі +Лише Gateway рекламує `_openclaw-gw._tcp`. Реклама багатоадресності в LAN +забезпечується вбудованим plugin `bonjour`; публікація wide-area DNS-SD і надалі належить Gateway. ## Типи сервісів -- `_openclaw-gw._tcp` — транспортний маяк gateway (використовується macOS/iOS/Android node). +- `_openclaw-gw._tcp` — транспортний маяк gateway (використовується node на macOS/iOS/Android). -## Ключі TXT (не секретні підказки) +## Ключі TXT (несекретні підказки) -Gateway рекламує невеликі не секретні підказки, щоб зробити UI-потоки зручнішими: +Gateway рекламує невеликі несекретні підказки, щоб зробити UI-потоки зручнішими: - `role=gateway` - `displayName=<дружня назва>` - `lanHost=.local` - `gatewayPort=` (Gateway WS + HTTP) -- `gatewayTls=1` (лише коли TLS увімкнено) -- `gatewayTlsSha256=` (лише коли TLS увімкнено і відбиток доступний) -- `canvasPort=` (лише коли ввімкнено canvas host; наразі те саме, що й `gatewayPort`) +- `gatewayTls=1` (лише коли ввімкнено TLS) +- `gatewayTlsSha256=` (лише коли ввімкнено TLS і доступний відбиток) +- `canvasPort=` (лише коли ввімкнено хост canvas; наразі збігається з `gatewayPort`) - `transport=gateway` -- `tailnetDns=` (лише в повному режимі mDNS, необов’язкова підказка, коли Tailnet доступний) -- `sshPort=` (лише в повному режимі mDNS; wide-area DNS-SD може його не включати) -- `cliPath=` (лише в повному режимі mDNS; wide-area DNS-SD все одно записує його як підказку для віддаленого встановлення) +- `tailnetDns=` (лише в режимі mDNS full; необов’язкова підказка, коли доступний Tailnet) +- `sshPort=` (лише в режимі mDNS full; wide-area DNS-SD може його не включати) +- `cliPath=` (лише в режимі mDNS full; wide-area DNS-SD усе одно записує його як підказку для віддаленого встановлення) Примітки щодо безпеки: -- Записи TXT у Bonjour/mDNS **неавтентифіковані**. Клієнти не повинні вважати TXT авторитетним джерелом маршрутизації. -- Клієнти повинні маршрутизувати, використовуючи резолвлену кінцеву точку сервісу (SRV + A/AAAA). Сприймайте `lanHost`, `tailnetDns`, `gatewayPort` і `gatewayTlsSha256` лише як підказки. +- TXT-записи Bonjour/mDNS є **неавтентифікованими**. Клієнти не повинні вважати TXT авторитетним джерелом маршрутизації. +- Клієнтам слід маршрутизувати через резолвлену кінцеву точку сервісу (SRV + A/AAAA). Сприймайте `lanHost`, `tailnetDns`, `gatewayPort` і `gatewayTlsSha256` лише як підказки. - Автоматичне націлювання SSH так само має використовувати резолвлений хост сервісу, а не підказки лише з TXT. -- TLS pinning ніколи не повинен дозволяти рекламованому `gatewayTlsSha256` перевизначати раніше збережений pin. -- iOS/Android node повинні трактувати прямі підключення на основі виявлення як **лише TLS** і вимагати явного підтвердження користувача перед довірою до відбитка, побаченого вперше. +- Закріплення TLS ніколи не повинно дозволяти рекламованому `gatewayTlsSha256` перевизначати раніше збережений pin. +- Node на iOS/Android повинні розглядати прямі підключення на основі виявлення як **лише TLS** і вимагати явного підтвердження користувача перед довірою до відбитка, побаченого вперше. ## Налагодження на macOS @@ -135,12 +135,12 @@ Gateway рекламує невеликі не секретні підказки dns-sd -L "" _openclaw-gw._tcp local. ``` -Якщо перегляд працює, а резолв — ні, зазвичай це означає проблему з політикою LAN або +Якщо перегляд працює, але резолв — ні, зазвичай це означає проблему з політикою LAN або резолвером mDNS. ## Налагодження в логах Gateway -Gateway записує ротаційний файл логу (під час запуску виводиться як +Gateway записує циклічний лог-файл (виводиться під час запуску як `gateway log file: ...`). Шукайте рядки `bonjour:`, особливо: - `bonjour: advertise failed ...` @@ -148,9 +148,9 @@ Gateway записує ротаційний файл логу (під час з - `bonjour: watchdog detected non-announced service ...` - `bonjour: disabling advertiser after ... failed restarts ...` -## Налагодження на iOS node +## Налагодження на node iOS -iOS node використовує `NWBrowser` для виявлення `_openclaw-gw._tcp`. +Node iOS використовує `NWBrowser` для виявлення `_openclaw-gw._tcp`. Щоб зібрати логи: @@ -161,24 +161,24 @@ iOS node використовує `NWBrowser` для виявлення `_opencl ## Коли вимикати Bonjour -Вимикайте Bonjour лише тоді, коли реклама через багатоадресність у LAN недоступна або шкідлива. -Типовий випадок — Gateway, що працює за Docker bridge networking, WSL або політикою -мережі, яка відкидає багатоадресність mDNS. У таких середовищах Gateway усе ще -доступний через свою опубліковану URL-адресу, SSH, Tailnet або wide-area DNS-SD, +Вимикайте Bonjour лише тоді, коли реклама багатоадресності в LAN недоступна або шкідлива. +Поширений випадок — Gateway, який працює за Docker bridge networking, WSL або +мережевою політикою, що відкидає багатоадресний трафік mDNS. У таких середовищах Gateway +усе ще доступний через опублікований URL, SSH, Tailnet або wide-area DNS-SD, але автоматичне виявлення в LAN ненадійне. -Віддавайте перевагу наявному перевизначенню через середовище, коли проблема пов’язана з конкретним розгортанням: +Віддавайте перевагу наявному перевизначенню через змінну середовища, коли проблема обмежена конкретним розгортанням: ```bash OPENCLAW_DISABLE_BONJOUR=1 ``` -Це вимикає рекламу через багатоадресність у LAN без зміни конфігурації Plugin. -Це безпечно для Docker-образів, service files, скриптів запуску та разового -налагодження, оскільки налаштування зникає разом із середовищем. +Це вимикає рекламу багатоадресності в LAN без зміни конфігурації plugin. +Це безпечно для Docker-образів, service-файлів, скриптів запуску та одноразового +налагодження, оскільки налаштування зникає разом зі змінною середовища. -Використовуйте конфігурацію Plugin лише тоді, коли ви свідомо хочете вимкнути -вбудований Plugin виявлення LAN для цієї конфігурації OpenClaw: +Використовуйте конфігурацію plugin лише тоді, коли ви свідомо хочете вимкнути +вбудований plugin виявлення LAN для цієї конфігурації OpenClaw: ```bash openclaw plugins disable bonjour @@ -186,76 +186,75 @@ openclaw plugins disable bonjour ## Особливості Docker -Комплектний Docker Compose встановлює `OPENCLAW_DISABLE_BONJOUR=1` для сервісу Gateway -за замовчуванням. Docker bridge network зазвичай не пересилають багатоадресність mDNS -(`224.0.0.251:5353`) між контейнером і LAN, тому якщо залишити Bonjour увімкненим, це може -спричиняти повторні збої ciao `probing` або `announcing`, не забезпечуючи -працездатне виявлення. +Вбудований plugin Bonjour автоматично вимикає рекламу багатоадресності в LAN у виявлених +контейнерах, коли `OPENCLAW_DISABLE_BONJOUR` не встановлено. Мережі Docker bridge +зазвичай не пересилають багатоадресний трафік mDNS (`224.0.0.251:5353`) між контейнером +та LAN, тому реклама з контейнера рідко робить виявлення працездатним. -Важливі нюанси: +Важливі особливості: -- Вимкнення Bonjour не зупиняє Gateway. Воно лише зупиняє рекламу через багатоадресність у LAN. -- Вимкнення Bonjour не змінює `gateway.bind`; Docker все ще за замовчуванням використовує +- Вимкнення Bonjour не зупиняє Gateway. Воно лише зупиняє рекламу багатоадресності в LAN. +- Вимкнення Bonjour не змінює `gateway.bind`; Docker і далі за замовчуванням використовує `OPENCLAW_GATEWAY_BIND=lan`, щоб опублікований порт хоста міг працювати. - Вимкнення Bonjour не вимикає wide-area DNS-SD. Використовуйте wide-area виявлення - або Tailnet, коли Gateway і node не в одній LAN. -- Повторне використання того самого `OPENCLAW_CONFIG_DIR` поза Docker не успадковує - значення Compose за замовчуванням, якщо середовище все ще не задає `OPENCLAW_DISABLE_BONJOUR`. -- Встановлюйте `OPENCLAW_DISABLE_BONJOUR=0` лише для host networking, macvlan або іншої - мережі, де багатоадресність mDNS гарантовано проходить. + або Tailnet, коли Gateway і node не перебувають в одній LAN. +- Повторне використання того самого `OPENCLAW_CONFIG_DIR` поза Docker не зберігає + політику автоматичного вимкнення контейнера. +- Установлюйте `OPENCLAW_DISABLE_BONJOUR=0` лише для host networking, macvlan або іншої + мережі, де відомо, що багатоадресний mDNS проходить; установлюйте `1`, щоб примусово вимкнути. ## Усунення проблем із вимкненим Bonjour Якщо node більше не виявляє Gateway автоматично після налаштування Docker: -1. Перевірте, чи Gateway навмисно пригнічує рекламу в LAN: +1. Підтвердьте, у якому режимі працює Gateway: автоматичному, примусово ввімкненому чи примусово вимкненому: ```bash docker compose config | grep OPENCLAW_DISABLE_BONJOUR ``` -2. Переконайтеся, що сам Gateway доступний через опублікований порт: +2. Підтвердьте, що сам Gateway доступний через опублікований порт: ```bash curl -fsS http://127.0.0.1:18789/healthz ``` 3. Використовуйте пряму ціль, коли Bonjour вимкнено: - - Control UI або локальні інструменти: `http://127.0.0.1:18789` - - Клієнти в LAN: `http://:18789` - - Клієнти між мережами: Tailnet MagicDNS, Tailnet IP, SSH tunnel або + - UI керування або локальні інструменти: `http://127.0.0.1:18789` + - Клієнти LAN: `http://:18789` + - Клієнти з інших мереж: Tailnet MagicDNS, Tailnet IP, SSH-тунель або wide-area DNS-SD -4. Якщо ви навмисно ввімкнули Bonjour у Docker за допомогою +4. Якщо ви свідомо ввімкнули Bonjour у Docker за допомогою `OPENCLAW_DISABLE_BONJOUR=0`, протестуйте багатоадресність із хоста: ```bash dns-sd -B _openclaw-gw._tcp local. ``` - Якщо перегляд порожній або логи Gateway показують повторні скасування - watchdog у ciao, поверніть `OPENCLAW_DISABLE_BONJOUR=1` і використовуйте прямий - маршрут або маршрут через Tailnet. + Якщо перегляд порожній або логи Gateway показують повторні скасування watchdog + ciao, поверніть `OPENCLAW_DISABLE_BONJOUR=1` і використовуйте прямий маршрут або + маршрут через Tailnet. -## Типові режими відмови +## Поширені режими відмов - **Bonjour не працює між мережами**: використовуйте Tailnet або SSH. - **Багатоадресність заблокована**: деякі мережі Wi‑Fi вимикають mDNS. -- **Advertiser застряг у probing/announcing**: хости із заблокованою багатоадресністю, - container bridge, WSL або зміни інтерфейсів можуть залишити advertiser ciao у - неанонсованому стані. OpenClaw робить кілька повторних спроб, а потім вимикає Bonjour - для поточного процесу Gateway, замість того щоб безкінечно перезапускати advertiser. -- **Docker bridge networking**: комплектний Docker Compose вимикає Bonjour - за замовчуванням через `OPENCLAW_DISABLE_BONJOUR=1`. Встановлюйте `0` лише для host, - macvlan або іншої мережі з підтримкою mDNS. +- **Рекламодавець застряг у probing/announcing**: хости із заблокованою багатоадресністю, + container bridge, WSL або зміна інтерфейсів можуть залишити рекламодавець ciao у + стані без анонсу. OpenClaw повторює спробу кілька разів, а потім вимикає Bonjour + для поточного процесу Gateway замість безкінечного перезапуску рекламодавця. +- **Docker bridge networking**: Bonjour автоматично вимикається у виявлених контейнерах. + Установлюйте `OPENCLAW_DISABLE_BONJOUR=0` лише для host, macvlan або іншої + mDNS-сумісної мережі. - **Сон / зміна інтерфейсів**: macOS може тимчасово втрачати результати mDNS; повторіть спробу. -- **Перегляд працює, а резолв — ні**: робіть назви машин простими (уникайте емодзі або - пунктуації), а потім перезапустіть Gateway. Ім’я екземпляра сервісу похідне від +- **Перегляд працює, але резолв — ні**: використовуйте прості назви машин (уникайте емодзі або + пунктуації), потім перезапустіть Gateway. Ім’я екземпляра сервісу походить від імені хоста, тому надто складні назви можуть плутати деякі резолвери. ## Екрановані імена екземплярів (`\032`) -Bonjour/DNS‑SD часто екранує байти в іменах екземплярів сервісів як десяткові послідовності `\DDD` +Bonjour/DNS‑SD часто екранує байти в іменах екземплярів сервісу як десяткові послідовності `\DDD` (наприклад, пробіли стають `\032`). - Це нормально на рівні протоколу. @@ -263,16 +262,17 @@ Bonjour/DNS‑SD часто екранує байти в іменах екзем ## Вимкнення / конфігурація -- `openclaw plugins disable bonjour` вимикає рекламу через багатоадресність у LAN, вимикаючи вбудований Plugin. -- `openclaw plugins enable bonjour` відновлює стандартний Plugin виявлення LAN. -- `OPENCLAW_DISABLE_BONJOUR=1` вимикає рекламу через багатоадресність у LAN без зміни конфігурації Plugin; підтримувані truthy-значення: `1`, `true`, `yes` і `on` (legacy: `OPENCLAW_DISABLE_BONJOUR`). -- Docker Compose за замовчуванням встановлює `OPENCLAW_DISABLE_BONJOUR=1` для bridge networking; перевизначайте значення на `OPENCLAW_DISABLE_BONJOUR=0` лише коли багатоадресність mDNS доступна. -- `gateway.bind` у `~/.openclaw/openclaw.json` керує режимом bind для Gateway. -- `OPENCLAW_SSH_PORT` перевизначає порт SSH, коли рекламується `sshPort` (legacy: `OPENCLAW_SSH_PORT`). -- `OPENCLAW_TAILNET_DNS` публікує підказку MagicDNS у TXT, коли ввімкнено повний режим mDNS (legacy: `OPENCLAW_TAILNET_DNS`). -- `OPENCLAW_CLI_PATH` перевизначає рекламований шлях CLI (legacy: `OPENCLAW_CLI_PATH`). +- `openclaw plugins disable bonjour` вимикає рекламу багатоадресності в LAN, вимикаючи вбудований plugin. +- `openclaw plugins enable bonjour` відновлює типовий plugin виявлення LAN. +- `OPENCLAW_DISABLE_BONJOUR=1` вимикає рекламу багатоадресності в LAN без зміни конфігурації plugin; допустимі truthy-значення: `1`, `true`, `yes` і `on` (застаріле: `OPENCLAW_DISABLE_BONJOUR`). +- `OPENCLAW_DISABLE_BONJOUR=0` примусово вмикає рекламу багатоадресності в LAN, зокрема всередині виявлених контейнерів; допустимі falsy-значення: `0`, `false`, `no` і `off`. +- Коли `OPENCLAW_DISABLE_BONJOUR` не встановлено, Bonjour рекламується на звичайних хостах і автоматично вимикається всередині виявлених контейнерів. +- `gateway.bind` у `~/.openclaw/openclaw.json` керує режимом прив’язки Gateway. +- `OPENCLAW_SSH_PORT` перевизначає порт SSH, коли рекламується `sshPort` (застаріле: `OPENCLAW_SSH_PORT`). +- `OPENCLAW_TAILNET_DNS` публікує підказку MagicDNS у TXT, коли ввімкнено режим mDNS full (застаріле: `OPENCLAW_TAILNET_DNS`). +- `OPENCLAW_CLI_PATH` перевизначає рекламований шлях CLI (застаріле: `OPENCLAW_CLI_PATH`). ## Пов’язана документація -- Політика виявлення та вибір транспорту: [Виявлення](/uk/gateway/discovery) -- Сполучення node + підтвердження: [Сполучення Gateway](/uk/gateway/pairing) +- Політика виявлення та вибір транспорту: [Discovery](/uk/gateway/discovery) +- Сполучення node + підтвердження: [Gateway pairing](/uk/gateway/pairing) diff --git a/docs/uk/gateway/discovery.md b/docs/uk/gateway/discovery.md index ca7ceea62..3a0b34d71 100644 --- a/docs/uk/gateway/discovery.md +++ b/docs/uk/gateway/discovery.md @@ -1,103 +1,103 @@ --- read_when: - Реалізація або зміна виявлення/оголошення Bonjour - - Налаштування режимів віддаленого підключення (напряму чи через SSH) - - Проєктування виявлення Node та сполучення для віддалених вузлів + - Налаштування режимів віддаленого підключення (пряме чи через SSH) + - Проєктування виявлення Node і сполучення для віддалених Node summary: Виявлення Node і транспорти (Bonjour, Tailscale, SSH) для пошуку Gateway -title: Виявлення та транспорти +title: Виявлення і транспорти x-i18n: - generated_at: "2026-04-26T04:54:57Z" + generated_at: "2026-04-26T23:10:42Z" model: gpt-5.4 provider: openai - source_hash: 615be0f501470772c257beb8e798c522c108b09081a603f44218404277fdf269 + source_hash: c396e6e07808e2571c6d7f539922b94443adbf39339027e6e962596c6f13deaa source_path: gateway/discovery.md workflow: 15 --- # Виявлення та транспорти -В OpenClaw є дві окремі проблеми, які на перший погляд виглядають схоже: +OpenClaw має дві окремі проблеми, які на поверхні виглядають схожими: -1. **Віддалене керування оператором**: застосунок macOS у рядку меню керує Gateway, що працює деінде. -2. **Сполучення Node**: iOS/Android (і майбутні вузли) знаходять Gateway і безпечно сполучаються з ним. +1. **Віддалене керування оператором**: застосунок macOS у рядку меню керує Gateway, що працює в іншому місці. +2. **Сполучення Node**: iOS/Android (і майбутні Node) знаходять Gateway і безпечно виконують сполучення. -Мета дизайну — зберегти все мережеве виявлення/оголошення в **Node Gateway** (`openclaw gateway`) і залишити клієнти (mac-застосунок, iOS) споживачами. +Мета дизайну — зберегти все мережеве виявлення/оголошення в **Node Gateway** (`openclaw gateway`) і залишити клієнти (застосунок macOS, iOS) споживачами. ## Терміни -- **Gateway**: один довготривалий процес Gateway, який володіє станом (сеанси, сполучення, реєстр вузлів) і запускає канали. У більшості конфігурацій використовується один на хост; можливі ізольовані конфігурації з кількома Gateway. -- **Gateway WS (площина керування)**: WebSocket-ендпойнт на `127.0.0.1:18789` за замовчуванням; може бути прив’язаний до LAN/tailnet через `gateway.bind`. -- **Прямий транспорт WS**: Gateway WS-ендпойнт, доступний із LAN/tailnet (без SSH). -- **Транспорт SSH (резервний варіант)**: віддалене керування через переадресацію `127.0.0.1:18789` поверх SSH. -- **Застарілий TCP-міст (видалений)**: старіший транспорт вузлів (див. - [Протокол Bridge](/uk/gateway/bridge-protocol)); більше не оголошується для +- **Gateway**: один довготривалий процес Gateway, який володіє станом (сеанси, сполучення, реєстр Node) і запускає канали. У більшості конфігурацій використовується один на хост; можливі ізольовані конфігурації з кількома Gateway. +- **Gateway WS (площина керування)**: кінцева точка WebSocket на `127.0.0.1:18789` за замовчуванням; може бути прив’язана до LAN/tailnet через `gateway.bind`. +- **Прямий транспорт WS**: кінцева точка Gateway WS, доступна з LAN/tailnet (без SSH). +- **Транспорт SSH (резервний варіант)**: віддалене керування через переспрямування `127.0.0.1:18789` через SSH. +- **Застарілий TCP-міст (видалено)**: старіший транспорт Node (див. + [Протокол моста](/uk/gateway/bridge-protocol)); більше не оголошується для виявлення і більше не є частиною поточних збірок. -Деталі протоколу: +Подробиці протоколу: - [Протокол Gateway](/uk/gateway/protocol) -- [Протокол Bridge (застарілий)](/uk/gateway/bridge-protocol) +- [Протокол моста (застарілий)](/uk/gateway/bridge-protocol) ## Чому ми зберігаємо і «прямий», і SSH - **Прямий WS** забезпечує найкращий UX в одній мережі та в межах tailnet: - автоматичне виявлення в LAN через Bonjour - токени сполучення + ACL, якими керує Gateway - - доступ до оболонки не потрібен; поверхня протоколу може залишатися вузькою й придатною для аудиту + - доступ до оболонки не потрібен; поверхня протоколу може залишатися вузькою й придатною до аудиту - **SSH** залишається універсальним резервним варіантом: - - працює всюди, де у вас є доступ по SSH (навіть через не пов’язані між собою мережі) - - переживає проблеми з multicast/mDNS + - працює всюди, де у вас є доступ SSH (навіть через непов’язані мережі) + - працює попри проблеми з multicast/mDNS - не потребує нових вхідних портів, окрім SSH -## Вхідні джерела виявлення (як клієнти дізнаються, де знаходиться Gateway) +## Джерела виявлення (як клієнти дізнаються, де знаходиться Gateway) ### 1) Виявлення через Bonjour / DNS-SD -Multicast Bonjour працює за принципом best-effort і не перетинає межі мереж. OpenClaw також може переглядати -той самий маяк Gateway через налаштований домен wide-area DNS-SD, тож виявлення може охоплювати: +Multicast Bonjour є best-effort і не проходить між мережами. OpenClaw також може переглядати +той самий маяк Gateway через налаштований wide-area домен DNS-SD, тож виявлення може охоплювати: -- `local.` у тій самій LAN -- налаштований домен unicast DNS-SD для міжмережевого виявлення +- `local.` в межах тієї самої LAN +- налаштований unicast-домен DNS-SD для міжмережевого виявлення -Цільовий напрям: +Цільовий напрямок: -- **Gateway** оголошує свій WS-ендпойнт через Bonjour. -- Клієнти переглядають і показують список «виберіть Gateway», а потім зберігають вибраний ендпойнт. +- **Gateway** оголошує свою кінцеву точку WS через Bonjour. +- Клієнти виконують перегляд і показують список «виберіть Gateway», а потім зберігають вибрану кінцеву точку. -Подробиці щодо усунення несправностей і маяка: [Bonjour](/uk/gateway/bonjour). +Подробиці усунення несправностей і маяка: [Bonjour](/uk/gateway/bonjour). -#### Подробиці маяка служби +#### Подробиці сервісного маяка -- Типи служб: +- Типи сервісів: - `_openclaw-gw._tcp` (маяк транспорту gateway) - Ключі TXT (не секретні): - `role=gateway` - `transport=gateway` - - `displayName=` (зрозуміле ім’я, налаштоване оператором) + - `displayName=<дружня назва>` (відображувана назва, налаштована оператором) - `lanHost=.local` - `gatewayPort=18789` (Gateway WS + HTTP) - `gatewayTls=1` (лише коли TLS увімкнено) - `gatewayTlsSha256=` (лише коли TLS увімкнено і відбиток доступний) - - `canvasPort=` (порт canvas host; наразі збігається з `gatewayPort`, коли canvas host увімкнено) + - `canvasPort=` (порт хоста canvas; наразі такий самий, як `gatewayPort`, коли хост canvas увімкнено) - `tailnetDns=` (необов’язкова підказка; визначається автоматично, коли доступний Tailscale) - - `sshPort=` (лише в повному режимі mDNS; wide-area DNS-SD може його не включати, у такому разі для SSH залишаються типові значення `22`) - - `cliPath=` (лише в повному режимі mDNS; wide-area DNS-SD все одно записує його як підказку для віддаленого встановлення) + - `sshPort=` (лише повний режим mDNS; wide-area DNS-SD може його не включати, у такому разі стандартні значення SSH залишаються `22`) + - `cliPath=` (лише повний режим mDNS; wide-area DNS-SD усе одно записує його як підказку для віддаленого встановлення) Примітки щодо безпеки: -- TXT-записи Bonjour/mDNS **не автентифіковані**. Клієнти повинні розглядати значення TXT лише як UX-підказки. -- Для маршрутизації (хост/порт) слід надавати перевагу **розв’язаному ендпойнту служби** (SRV + A/AAAA), а не переданим через TXT `lanHost`, `tailnetDns` чи `gatewayPort`. +- TXT-записи Bonjour/mDNS є **неавтентифікованими**. Клієнти повинні трактувати значення TXT лише як UX-підказки. +- Для маршрутизації (host/port) слід надавати перевагу **розв’язаній кінцевій точці сервісу** (SRV + A/AAAA), а не значенням `lanHost`, `tailnetDns` чи `gatewayPort`, наданим через TXT. - TLS pinning ніколи не повинен дозволяти оголошеному `gatewayTlsSha256` перевизначати раніше збережений pin. -- Вузли iOS/Android повинні вимагати явного підтвердження «довіряти цьому відбитку» перед збереженням pin під час першого підключення (перевірка поза каналом), коли вибраний маршрут є безпечним/на основі TLS. +- Node iOS/Android повинні вимагати явне підтвердження «довіряти цьому відбитку» перед збереженням pin під час першого підключення (перевірка поза смугою) щоразу, коли вибраний маршрут є безпечним/базованим на TLS. Вимкнення/перевизначення: - `OPENCLAW_DISABLE_BONJOUR=1` вимикає оголошення. -- Docker Compose типово використовує `OPENCLAW_DISABLE_BONJOUR=1`, оскільки мережі bridge - зазвичай не передають multicast mDNS надійно; використовуйте `0` лише на host, macvlan - або в іншій мережі з підтримкою mDNS. +- Коли `OPENCLAW_DISABLE_BONJOUR` не задано, Bonjour оголошується на звичайних хостах + і автоматично вимикається у виявлених контейнерах. Використовуйте `0` лише на host, macvlan + або в іншій мережі з підтримкою mDNS; використовуйте `1` для примусового вимкнення. - `gateway.bind` у `~/.openclaw/openclaw.json` керує режимом прив’язки Gateway. -- `OPENCLAW_SSH_PORT` перевизначає SSH-порт, що оголошується, коли виводиться `sshPort`. +- `OPENCLAW_SSH_PORT` перевизначає SSH-порт, який оголошується, коли виводиться `sshPort`. - `OPENCLAW_TAILNET_DNS` публікує підказку `tailnetDns` (MagicDNS). - `OPENCLAW_CLI_PATH` перевизначає оголошений шлях CLI. @@ -105,22 +105,22 @@ Multicast Bonjour працює за принципом best-effort і не пе Для конфігурацій у стилі London/Vienna Bonjour не допоможе. Рекомендована «пряма» ціль: -- ім’я Tailscale MagicDNS (переважно) або стабільна tailnet IP-адреса. +- ім’я Tailscale MagicDNS (бажано) або стабільна tailnet IP-адреса. -Якщо Gateway може визначити, що працює під Tailscale, він публікує `tailnetDns` як необов’язкову підказку для клієнтів (зокрема wide-area beacon). +Якщо Gateway може визначити, що він працює під Tailscale, він публікує `tailnetDns` як необов’язкову підказку для клієнтів (зокрема для wide-area beacon). -MacOS-застосунок тепер віддає перевагу іменам MagicDNS над сирими Tailscale IP-адресами для виявлення gateway. Це підвищує надійність, коли tailnet IP-адреси змінюються (наприклад після перезапуску вузлів або повторного призначення CGNAT), тому що імена MagicDNS автоматично розв’язуються в поточну IP-адресу. +Застосунок macOS тепер надає перевагу іменам MagicDNS над сирими Tailscale IP для виявлення gateway. Це підвищує надійність, коли tailnet IP змінюються (наприклад, після перезапуску Node або перепризначення CGNAT), оскільки імена MagicDNS автоматично розв’язуються в поточну IP-адресу. -Для сполучення мобільних вузлів підказки виявлення не послаблюють безпеку транспорту на tailnet/public маршрутах: +Для сполучення мобільних Node підказки виявлення не послаблюють безпеку транспорту на маршрутах tailnet/public: - iOS/Android, як і раніше, вимагають безпечний шлях першого підключення через tailnet/public (`wss://` або Tailscale Serve/Funnel). -- Виявлена сира tailnet IP-адреса є підказкою для маршрутизації, а не дозволом використовувати відкритий віддалений `ws://`. -- Пряме підключення через приватну LAN по `ws://` як і раніше підтримується. -- Якщо вам потрібен найпростіший шлях Tailscale для мобільних вузлів, використовуйте Tailscale Serve, щоб і виявлення, і код налаштування розв’язувалися до того самого безпечного ендпойнта MagicDNS. +- Виявлена сира tailnet IP — це підказка маршрутизації, а не дозвіл використовувати відкритий віддалений `ws://`. +- Пряме приватне LAN-підключення через `ws://` залишається підтримуваним. +- Якщо вам потрібен найпростіший шлях Tailscale для мобільних Node, використовуйте Tailscale Serve, щоб і виявлення, і код налаштування розв’язувалися до тієї самої захищеної кінцевої точки MagicDNS. -### 3) Ручна ціль / SSH +### 3) Ручна / SSH-ціль -Коли прямий маршрут недоступний (або пряме підключення вимкнено), клієнти завжди можуть підключитися через SSH, переадресувавши loopback-порт gateway. +Коли прямого маршруту немає (або прямий вимкнено), клієнти завжди можуть підключитися через SSH, переспрямувавши loopback-порт gateway. Див. [Віддалений доступ](/uk/gateway/remote). @@ -128,30 +128,30 @@ MacOS-застосунок тепер віддає перевагу іменам Рекомендована поведінка клієнта: -1. Якщо налаштовано сполучений прямий ендпойнт і він доступний, використовуйте його. -2. Інакше, якщо виявлення знаходить Gateway у `local.` або в налаштованому wide-area domain, запропонуйте варіант «Використовувати цей Gateway» в один дотик і збережіть його як прямий ендпойнт. -3. Інакше, якщо налаштовано DNS/IP tailnet, спробуйте пряме підключення. - Для мобільних вузлів на tailnet/public маршрутах пряме підключення означає безпечний ендпойнт, а не відкритий віддалений `ws://`. -4. Інакше поверніться до SSH. +1. Якщо налаштовано сполучену пряму кінцеву точку і вона доступна, використовуйте її. +2. Інакше, якщо виявлення знаходить Gateway у `local.` або в налаштованому wide-area домені, запропонуйте вибір «Використовувати цей Gateway» в один дотик і збережіть його як пряму кінцеву точку. +3. Інакше, якщо налаштовано tailnet DNS/IP, спробуйте пряме підключення. + Для мобільних Node на маршрутах tailnet/public пряме підключення означає безпечну кінцеву точку, а не відкритий віддалений `ws://`. +4. Інакше використовуйте SSH як резервний варіант. ## Сполучення + автентифікація (прямий транспорт) -Gateway є джерелом істини для допуску вузлів/клієнтів. +Gateway є джерелом істини для допуску Node/клієнтів. - Запити на сполучення створюються/схвалюються/відхиляються в Gateway (див. [Сполучення Gateway](/uk/gateway/pairing)). - Gateway забезпечує: - - автентифікацію (токен / keypair) + - автентифікацію (token / keypair) - області дії/ACL (Gateway не є сирим проксі до кожного методу) - обмеження швидкості -## Зони відповідальності за компонентами +## Обов’язки за компонентами -- **Gateway**: оголошує маяки виявлення, володіє рішеннями щодо сполучення та хостить WS-ендпойнт. -- **macOS-застосунок**: допомагає вибрати Gateway, показує запити на сполучення та використовує SSH лише як резервний варіант. -- **Вузли iOS/Android**: переглядають Bonjour для зручності й підключаються до сполученого Gateway WS. +- **Gateway**: оголошує маяки виявлення, керує рішеннями щодо сполучення та розміщує кінцеву точку WS. +- **Застосунок macOS**: допомагає вибрати Gateway, показує запити на сполучення і використовує SSH лише як резервний варіант. +- **Node iOS/Android**: переглядають Bonjour як зручну можливість і підключаються до сполученого Gateway WS. ## Пов’язане - [Віддалений доступ](/uk/gateway/remote) - [Tailscale](/uk/gateway/tailscale) -- [Виявлення через Bonjour](/uk/gateway/bonjour) +- [Виявлення Bonjour](/uk/gateway/bonjour) diff --git a/docs/uk/help/testing.md b/docs/uk/help/testing.md index ce0fac369..5536dec36 100644 --- a/docs/uk/help/testing.md +++ b/docs/uk/help/testing.md @@ -1,15 +1,15 @@ --- read_when: - Запуск тестів локально або в CI - - Додавання регресійних тестів для багів моделей/провайдерів - - Налагодження поведінки Gateway + агентів + - Додавання регресійних тестів для помилок моделі/провайдера + - Налагодження поведінки Gateway + агента summary: 'Набір для тестування: набори unit/e2e/live, ранери Docker і що охоплює кожен тест' title: Тестування x-i18n: - generated_at: "2026-04-26T22:39:59Z" + generated_at: "2026-04-26T23:10:41Z" model: gpt-5.4 provider: openai - source_hash: 4499f5092819a250971610ce3e31191b871cd2a1d2915bb7479f9439cea94dcd + source_hash: 7e23cc382a48b372aa5273b16f2831e37c870df265b3f30fe06f8b2b97909814 source_path: help/testing.md workflow: 15 --- @@ -18,7 +18,7 @@ OpenClaw має три набори Vitest (unit/integration, e2e, live) і не ранерів Docker. Цей документ — посібник «як ми тестуємо»: - Що охоплює кожен набір (і що він навмисно _не_ охоплює). -- Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження). +- Які команди запускати для типових сценаріїв (локально, перед push, налагодження). - Як live-тести знаходять облікові дані та вибирають моделі/провайдерів. - Як додавати регресійні тести для реальних проблем із моделями/провайдерами. @@ -26,235 +26,233 @@ OpenClaw має три набори Vitest (unit/integration, e2e, live) і не У більшості випадків: -- Повний gate (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test` -- Швидший локальний запуск повного набору на потужній машині: `pnpm test:max` +- Повна перевірка (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test` +- Швидший локальний запуск усіх наборів на потужній машині: `pnpm test:max` - Прямий цикл спостереження Vitest: `pnpm test:watch` -- Прямий таргетинг файлу тепер також маршрутизує шляхи extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- Під час ітерацій над однією помилкою спочатку віддавайте перевагу цільовим запускам. +- Пряме націлення на файл тепер також маршрутизує шляхи extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- Якщо ви ітеруєтеся над однією помилкою, спочатку віддавайте перевагу цільовим запускам. - QA-сайт на базі Docker: `pnpm qa:lab:up` -- QA-лайн на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- QA lane на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -Коли ви змінюєте тести або хочете додаткової впевненості: +Коли ви змінюєте тести або хочете більше впевненості: -- Gate покриття: `pnpm test:coverage` +- Перевірка coverage: `pnpm test:coverage` - Набір E2E: `pnpm test:e2e` Під час налагодження реальних провайдерів/моделей (потрібні реальні облікові дані): -- Live-набір (моделі + перевірки інструментів/зображень Gateway): `pnpm test:live` -- Таргетинг одного live-файлу без зайвого виводу: `pnpm test:live -- src/agents/models.profiles.live.test.ts` -- Docker-прохід live-моделей: `pnpm test:docker:live-models` - - Для кожної вибраної моделі тепер виконується текстовий хід плюс невелика перевірка у стилі читання файлу. - Моделі, у чиїх метаданих зазначено вхід `image`, також виконують маленький хід із зображенням. - Вимкніть додаткові перевірки за допомогою `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` або +- Набір live (моделі + Gateway tool/image probes): `pnpm test:live` +- Тихо націлитися на один live-файл: `pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Docker live model sweep: `pnpm test:docker:live-models` + - Кожна вибрана модель тепер запускає текстовий хід плюс невеликий probe у стилі читання файлу. + Моделі, у чиїх метаданих заявлено вхід `image`, також запускають маленький image-turn. + Вимкніть додаткові probes за допомогою `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` або `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0`, коли ізолюєте збої провайдера. - - Покриття CI: щоденний `OpenClaw Scheduled Live And E2E Checks` і ручний - `OpenClaw Release Checks` обидва викликають повторно використовуваний live/E2E workflow з - `include_live_suites: true`, що включає окремі matrix jobs Docker live-моделей, - розбиті за провайдером. - - Для цільових повторних запусків у CI викличте `OpenClaw Live And E2E Checks (Reusable)` + - Покриття в CI: щоденні `OpenClaw Scheduled Live And E2E Checks` і ручні + `OpenClaw Release Checks` обидва викликають повторно використовуваний workflow live/E2E з + `include_live_suites: true`, який включає окремі матричні Docker jobs для live-моделей, + розшардовані за провайдером. + - Для цільових повторних запусків у CI виконайте dispatch `OpenClaw Live And E2E Checks (Reusable)` з `include_live_suites: true` і `live_models_only: true`. - - Додавайте нові high-signal секрети провайдерів до `scripts/ci-hydrate-live-auth.sh`, + - Додавайте нові high-signal secrets провайдерів до `scripts/ci-hydrate-live-auth.sh`, а також до `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` і його - scheduled/release викликів. + scheduled/release callers. - Native Codex bound-chat smoke: `pnpm test:docker:live-codex-bind` - - Запускає Docker live-лайн проти шляху Codex app-server, прив’язує синтетичний + - Запускає Docker live lane проти шляху Codex app-server, прив’язує синтетичний Slack DM через `/codex bind`, виконує `/codex fast` і `/codex permissions`, а потім перевіряє, що звичайна відповідь і вкладення-зображення - проходять через native-прив’язку Plugin, а не через ACP. + маршрутизуються через native binding Plugin, а не через ACP. - Codex app-server harness smoke: `pnpm test:docker:live-codex-harness` - - Пропускає ходи агентів Gateway через harness app-server, що належить Plugin у Codex, - перевіряє `/codex status` і `/codex models`, а також за замовчуванням виконує перевірки image, - cron MCP, sub-agent і Guardian. Вимкніть перевірку sub-agent за допомогою - `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0`, коли ізолюєте інші збої app-server Codex. - Для цільової перевірки sub-agent вимкніть інші перевірки: + - Запускає ходи агента Gateway через harness app-server Codex, що належить Plugin, + перевіряє `/codex status` і `/codex models`, а за замовчуванням також виконує probes image, + cron MCP, sub-agent і Guardian. Вимкніть probe sub-agent через + `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0`, коли ізолюєте інші збої + app-server Codex. Для цільової перевірки sub-agent вимкніть інші probes: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`. - Це завершиться після перевірки sub-agent, якщо не встановлено - `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`. -- Smoke перевірки rescue-команди Crestodian: `pnpm test:live:crestodian-rescue-channel` - - Opt-in перевірка типу belt-and-suspenders для поверхні rescue-команди каналу повідомлень. - Вона виконує `/crestodian status`, ставить у чергу постійну зміну моделі, - відповідає `/crestodian yes` і перевіряє шлях запису audit/config. + Це завершиться після probe sub-agent, якщо тільки + `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0` не встановлено. +- Smoke для rescue command Crestodian: `pnpm test:live:crestodian-rescue-channel` + - Опційна перевірка belt-and-suspenders для поверхні rescue command у message-channel. + Вона виконує `/crestodian status`, ставить у чергу стійку + зміну моделі, відповідає `/crestodian yes` і перевіряє шлях запису audit/config. - Docker smoke планувальника Crestodian: `pnpm test:docker:crestodian-planner` - - Запускає Crestodian у контейнері без конфігурації з підробленим Claude CLI у `PATH` - і перевіряє, що fuzzy planner fallback перетворюється на audited typed - запис у config. + - Запускає Crestodian у контейнері без config із підробленим Claude CLI в `PATH` + і перевіряє, що fallback fuzzy planner перетворюється на типізований запис config з audit. - Docker smoke першого запуску Crestodian: `pnpm test:docker:crestodian-first-run` - - Починає з порожнього каталогу стану OpenClaw, маршрутизує простий `openclaw` до - Crestodian, застосовує записи setup/model/agent/Discord plugin + SecretRef, - валідує config і перевіряє записи audit. Той самий шлях налаштування Ring 0 - також покривається в QA Lab через + - Починає з порожнього каталогу стану OpenClaw, маршрутизує голий `openclaw` до + Crestodian, застосовує записи setup/model/agent/Discord Plugin + SecretRef, + перевіряє config і записи audit. Той самий шлях налаштування Ring 0 + також охоплюється в QA Lab через `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup`. -- Smoke перевірка вартості Moonshot/Kimi: коли встановлено `MOONSHOT_API_KEY`, виконайте - `openclaw models list --provider moonshot --json`, а потім виконайте ізольований +- Smoke вартості Moonshot/Kimi: якщо встановлено `MOONSHOT_API_KEY`, виконайте + `openclaw models list --provider moonshot --json`, а потім запустіть ізольований `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json` - проти `moonshot/kimi-k2.6`. Переконайтеся, що JSON повідомляє про Moonshot/K2.6 і що - transcript асистента зберігає нормалізований `usage.cost`. + проти `moonshot/kimi-k2.6`. Переконайтеся, що JSON повідомляє Moonshot/K2.6 і що + transcript помічника зберігає нормалізований `usage.cost`. -Порада: коли вам потрібен лише один проблемний випадок, надавайте перевагу звуженню live-тестів через env-змінні allowlist, описані нижче. +Порада: коли вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів через змінні середовища allowlist, описані нижче. ## QA-специфічні ранери -Ці команди розташовані поруч з основними наборами тестів, коли вам потрібен рівень реалістичності QA Lab: +Ці команди використовуються разом з основними наборами тестів, коли вам потрібен рівень реалістичності QA Lab: -CI запускає QA Lab в окремих workflow. `Parity gate` запускається для відповідних PR і -через manual dispatch з mock-провайдерами. `QA-Lab - All Lanes` запускається щоночі на -`main` і через manual dispatch з mock parity gate, live Matrix lane і -live Telegram lane під керуванням Convex як паралельними jobs. `OpenClaw Release Checks` -запускає ті самі лайни перед схваленням релізу. +CI запускає QA Lab в окремих workflows. `Parity gate` запускається на відповідних PR +і через ручний dispatch з mock-провайдерами. `QA-Lab - All Lanes` запускається щоночі на +`main` і через ручний dispatch із mock parity gate, live Matrix lane і +керованим Convex live Telegram lane як паралельними jobs. `OpenClaw Release Checks` +запускає ті самі lanes перед схваленням релізу. - `pnpm openclaw qa suite` - - Запускає QA-сценарії на основі репозиторію безпосередньо на хості. + - Запускає сценарії QA на базі репозиторію безпосередньо на хості. - За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими - працівниками Gateway. `qa-channel` за замовчуванням має concurrency 4 (обмежену - кількістю вибраних сценаріїв). Використовуйте `--concurrency `, щоб налаштувати - кількість працівників, або `--concurrency 1` для старішого послідовного лайну. - - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, якщо - вам потрібні артефакти без коду завершення з помилкою. + воркерами Gateway. `qa-channel` за замовчуванням має concurrency 4 (обмежується + кількістю вибраних сценаріїв). Використовуйте `--concurrency `, щоб налаштувати кількість + воркерів, або `--concurrency 1` для старішого послідовного lane. + - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, коли + хочете отримати артефакти без коду завершення з помилкою. - Підтримує режими провайдерів `live-frontier`, `mock-openai` і `aimock`. `aimock` запускає локальний сервер провайдера на базі AIMock для експериментального - покриття fixture і protocol-mock без заміни лайну `mock-openai`, - який враховує сценарії. + покриття fixtures і protocol-mock без заміни lane `mock-openai`, + що враховує сценарії. - `pnpm openclaw qa suite --runner multipass` - - Запускає той самий QA-набір усередині тимчасової Linux VM Multipass. - - Зберігає таку саму поведінку вибору сценаріїв, як і `qa suite` на хості. - - Повторно використовує ті самі прапори вибору провайдера/моделі, що й `qa suite`. - - Live-запуски передають підтримувані QA auth-входи, які практично використовувати для guest: - ключі провайдерів на основі env, шлях до config QA live provider і `CODEX_HOME`, якщо він наявний. + - Запускає той самий QA-набір усередині одноразової Linux VM Multipass. + - Зберігає ту саму поведінку вибору сценаріїв, що й `qa suite` на хості. + - Повторно використовує ті самі прапорці вибору провайдера/моделі, що й `qa suite`. + - Live-запуски пересилають підтримувані входи автентифікації QA, практичні для guest: + ключі провайдерів через env, шлях до config живого QA-провайдера і `CODEX_HOME`, якщо присутній. - Каталоги виводу мають залишатися в межах кореня репозиторію, щоб guest міг записувати назад через - змонтований workspace. - - Записує звичайні QA report + summary, а також логи Multipass у + змонтовану робочу область. + - Записує звичайний QA report + summary, а також логи Multipass у `.artifacts/qa-e2e/...`. - `pnpm qa:lab:up` - - Запускає QA-сайт на базі Docker для операторської QA-роботи. + - Запускає QA-сайт на базі Docker для операторської роботи QA. - `pnpm test:docker:npm-onboard-channel-agent` - - Збирає npm tarball з поточного checkout, встановлює його глобально в - Docker, виконує неінтерактивний onboarding OpenAI API-key, за замовчуванням налаштовує Telegram, - перевіряє, що ввімкнення Plugin встановлює runtime-залежності за потреби, - запускає doctor і виконує один локальний хід агента проти замоканого endpoint OpenAI. - - Використовуйте `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`, щоб запустити той самий лайн - встановлення упакованої версії з Discord. + - Збирає npm tarball з поточного checkout, глобально встановлює його в + Docker, виконує неінтерактивний onboarding з OpenAI API-key, налаштовує Telegram + за замовчуванням, перевіряє, що ввімкнення Plugin встановлює runtime-залежності за потреби, + запускає doctor і виконує один локальний хід агента проти змоканого endpoint OpenAI. + - Використовуйте `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`, щоб запустити той самий lane + встановлення з пакета з Discord. - `pnpm test:docker:session-runtime-context` - - Запускає детермінований Docker smoke зібраного застосунку для transcript із вбудованим runtime context. + - Запускає детермінований Docker smoke для built-app для transcript із вбудованим runtime context. Він перевіряє, що прихований runtime context OpenClaw зберігається як - недисплейне custom-повідомлення замість витоку у видимий хід користувача, - потім підставляє зламаний JSONL сесії й перевіряє, що - `openclaw doctor --fix` переписує його в активну гілку з резервною копією. + користувацьке повідомлення, яке не відображається, замість витоку у видимий user turn, + потім додає початковий зламаний JSONL сесії та перевіряє, що + `openclaw doctor --fix` переписує його до активної гілки з резервною копією. - `pnpm test:docker:npm-telegram-live` - - Встановлює опублікований пакет OpenClaw у Docker, виконує onboarding встановленого пакета, - налаштовує Telegram через встановлений CLI, а потім повторно використовує - live Telegram QA-лайн з цим встановленим пакетом як SUT Gateway. + - Встановлює опублікований пакет OpenClaw у Docker, запускає onboarding + встановленого пакета, налаштовує Telegram через встановлений CLI, а потім повторно використовує + live Telegram QA lane з цим встановленим пакетом як SUT Gateway. - За замовчуванням використовується `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`. - - Використовує ті самі env-облікові дані Telegram або джерело облікових даних Convex, що й + - Використовує ті самі облікові дані Telegram через env або джерело облікових даних Convex, що й `pnpm openclaw qa telegram`. Для автоматизації CI/release встановіть `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`, а також `OPENCLAW_QA_CONVEX_SITE_URL` і role secret. Якщо - `OPENCLAW_QA_CONVEX_SITE_URL` і Convex role secret наявні в CI, - обгортка Docker автоматично вибирає Convex. + `OPENCLAW_QA_CONVEX_SITE_URL` і role secret Convex присутні в CI, + Docker wrapper автоматично вибирає Convex. - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` перевизначає спільний - `OPENCLAW_QA_CREDENTIAL_ROLE` лише для цього лайну. - - GitHub Actions надає цей лайн як ручний workflow для супровідників - `NPM Telegram Beta E2E`. Він не запускається під час merge. Workflow використовує - середовище `qa-live-shared` і оренди облікових даних Convex CI. + `OPENCLAW_QA_CREDENTIAL_ROLE` лише для цього lane. + - GitHub Actions надає цей lane як ручний maintainer workflow + `NPM Telegram Beta E2E`. Він не запускається при merge. Workflow використовує + середовище `qa-live-shared` і оренду облікових даних Convex CI. - `pnpm test:docker:bundled-channel-deps` - - Пакує та встановлює поточну збірку OpenClaw у Docker, запускає Gateway + - Пакує й установлює поточну збірку OpenClaw у Docker, запускає Gateway з налаштованим OpenAI, а потім вмикає вбудовані channel/plugins через редагування config. - - Перевіряє, що виявлення setup залишає відсутніми runtime-залежності - неналаштованих plugin, що перший налаштований запуск Gateway або doctor встановлює runtime-залежності - кожного вбудованого plugin за потреби, і що другий перезапуск не перевстановлює залежності, - які вже були активовані. - - Також встановлює відому старішу npm-базову версію, вмикає Telegram перед запуском - `openclaw update --tag ` і перевіряє, що post-update doctor кандидата - відновлює runtime-залежності вбудованих channel без відновлення postinstall + - Перевіряє, що виявлення setup залишає runtime-залежності + неналаштованого Plugin відсутніми, перший налаштований запуск Gateway або doctor + встановлює runtime-залежності кожного вбудованого Plugin за потреби, а другий перезапуск не + перевстановлює залежності, які вже були активовані. + - Також установлює відому старішу базову версію npm, вмикає Telegram перед запуском + `openclaw update --tag `, і перевіряє, що post-update doctor кандидата + відновлює runtime-залежності вбудованого channel без postinstall-відновлення з боку harness. - `pnpm test:parallels:npm-update` - - Запускає native smoke оновлення встановленого пакета в Parallels guest. Кожна - вибрана платформа спочатку встановлює потрібний базовий пакет, потім виконує - встановлену команду `openclaw update` у тому самому guest і перевіряє встановлену + - Запускає native smoke оновлення встановленого пакета в гостьових системах Parallels. Кожна + вибрана платформа спочатку встановлює потрібний базовий пакет, а потім запускає + встановлену команду `openclaw update` у тій самій guest-системі та перевіряє встановлену версію, статус оновлення, готовність gateway і один локальний хід агента. - - Використовуйте `--platform macos`, `--platform windows` або `--platform linux` під час - ітерацій над одним guest. Використовуйте `--json` для шляху до summary artifact і - статусу кожного лайну. - - Лайн OpenAI за замовчуванням використовує `openai/gpt-5.5` для перевірки live agent-turn. + - Використовуйте `--platform macos`, `--platform windows` або `--platform linux`, коли ітеруєтеся на одній guest-системі. Використовуйте `--json` для шляху до summary artifact і статусу + для кожного lane. + - OpenAI lane за замовчуванням використовує `openai/gpt-5.5` для підтвердження живого ходу агента. Передайте `--model ` або встановіть - `OPENCLAW_PARALLELS_OPENAI_MODEL`, якщо навмисно перевіряєте іншу модель OpenAI. + `OPENCLAW_PARALLELS_OPENAI_MODEL`, якщо навмисно перевіряєте іншу + модель OpenAI. - Обгортайте довгі локальні запуски в host timeout, щоб зависання транспорту Parallels не - поглинало решту вікна тестування: + забрало решту вікна тестування: ```bash timeout --foreground 150m pnpm test:parallels:npm-update -- --json timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json ``` - - Скрипт записує вкладені логи лайнів у `/tmp/openclaw-parallels-npm-update.*`. + - Скрипт записує вкладені логи lanes у `/tmp/openclaw-parallels-npm-update.*`. Перевіряйте `windows-update.log`, `macos-update.log` або `linux-update.log`, перш ніж вважати, що зовнішня обгортка зависла. - - Оновлення Windows може витрачати 10–15 хвилин на відновлення doctor/runtime dependency - після оновлення на cold guest; це все ще вважається нормальним, якщо вкладений - npm debug log продовжує оновлюватися. - - Не запускайте цю агреговану обгортку паралельно з окремими smoke-лайнами Parallels - macOS, Windows або Linux. Вони використовують спільний стан VM і можуть конфліктувати під час - відновлення snapshot, видачі пакета або стану guest gateway. - - Перевірка після оновлення запускає звичайну поверхню bundled plugin, оскільки - capability facades, як-от speech, image generation і media - understanding, завантажуються через bundled runtime API навіть тоді, коли сам + - Оновлення Windows може витрачати від 10 до 15 хвилин на post-update doctor/відновлення + runtime-залежностей у холодній guest-системі; це все ще є нормальним, якщо вкладений + лог налагодження npm просувається. + - Не запускайте цю агреговану обгортку паралельно з окремими smoke lanes Parallels + для macOS, Windows або Linux. Вони використовують спільний стан VM і можуть конфліктувати через + відновлення snapshot, роздачу пакета або стан guest Gateway. + - Підтвердження після оновлення запускає звичайну поверхню bundled Plugin, оскільки + такі capability facades, як speech, image generation і media + understanding, завантажуються через bundled runtime APIs, навіть якщо сам хід агента перевіряє лише просту текстову відповідь. - `pnpm openclaw qa aimock` - Запускає лише локальний сервер провайдера AIMock для прямого smoke-тестування протоколу. - `pnpm openclaw qa matrix` - - Запускає live QA-лайн Matrix проти тимчасового homeserver Tuwunel на базі Docker. - - Цей QA-хост наразі призначений лише для репозиторію/розробки. Упаковані встановлення OpenClaw не постачаються з - `qa-lab`, тому не надають `openclaw qa`. - - Checkout репозиторію завантажують вбудований раннер напряму; окремий крок - встановлення plugin не потрібен. - - Налаштовує трьох тимчасових користувачів Matrix (`driver`, `sut`, `observer`) плюс одну приватну кімнату, а потім запускає дочірній QA gateway з реальним plugin Matrix як транспортом SUT. - - За замовчуванням використовує зафіксований стабільний образ Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Перевизначайте через `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE`, якщо потрібно протестувати інший образ. - - Matrix не надає спільні прапори джерела облікових даних, оскільки лайн локально створює тимчасових користувачів. + - Запускає live QA lane Matrix проти одноразового homeserver Tuwunel на базі Docker. + - Цей QA host зараз призначений лише для репозиторію/розробки. Встановлення OpenClaw з пакета не постачають + `qa-lab`, тому вони не надають `openclaw qa`. + - Checkout-и репозиторію безпосередньо завантажують вбудований runner; окремий крок + встановлення Plugin не потрібен. + - Підготовлює трьох тимчасових користувачів Matrix (`driver`, `sut`, `observer`) і одну приватну кімнату, після чого запускає дочірній QA gateway з реальним Plugin Matrix як транспортом SUT. + - За замовчуванням використовує зафіксований стабільний образ Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Перевизначте через `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE`, якщо потрібно протестувати інший образ. + - Matrix не надає спільні прапорці джерела облікових даних, оскільки цей lane локально створює одноразових користувачів. - Записує звіт Matrix QA, summary, observed-events artifact і комбінований лог виводу stdout/stderr у `.artifacts/qa-e2e/...`. - - За замовчуванням виводить прогрес і застосовує жорсткий timeout виконання через `OPENCLAW_QA_MATRIX_TIMEOUT_MS` (типово 30 хвилин). Очищення обмежується `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS`, а помилки містять команду відновлення `docker compose ... down --remove-orphans`. + - За замовчуванням виводить прогрес і застосовує жорсткий тайм-аут виконання через `OPENCLAW_QA_MATRIX_TIMEOUT_MS` (типово 30 хвилин). Очищення обмежується `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS`, а в разі збоїв додається команда відновлення `docker compose ... down --remove-orphans`. - `pnpm openclaw qa telegram` - - Запускає live QA-лайн Telegram проти реальної приватної групи, використовуючи токени bot driver і SUT з env. - - Потребує `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` і `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. ID групи має бути числовим Telegram chat id. - - Підтримує `--credential-source convex` для спільних пулових облікових даних. За замовчуванням використовуйте режим env або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб увімкнути пулові lease. - - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, якщо - вам потрібні артефакти без коду завершення з помилкою. - - Потребує двох різних bot в одній приватній групі, причому bot SUT має мати Telegram username. - - Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у `@BotFather` для обох bot і переконайтеся, що bot driver може спостерігати трафік bot у групі. - - Записує звіт Telegram QA, summary і observed-messages artifact у `.artifacts/qa-e2e/...`. Сценарії з відповідями включають RTT від запиту на надсилання driver до спостереженої відповіді SUT. + - Запускає live QA lane Telegram проти реальної приватної групи, використовуючи токени ботів driver і SUT з env. + - Потребує `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` і `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. Ідентифікатор групи має бути числовим chat id Telegram. + - Підтримує `--credential-source convex` для спільних пулових облікових даних. За замовчуванням використовуйте режим env або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб увімкнути pooled leases. + - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, коли + хочете отримати артефакти без коду завершення з помилкою. + - Потребує двох різних ботів в одній приватній групі, причому бот SUT має мати ім’я користувача Telegram. + - Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у `@BotFather` для обох ботів і переконайтеся, що бот driver може спостерігати трафік ботів у групі. + - Записує звіт Telegram QA, summary і observed-messages artifact у `.artifacts/qa-e2e/...`. Сценарії з відповідями включають RTT від запиту надсилання driver до спостережуваної відповіді SUT. -Live transport-лайни мають спільний стандартний контракт, щоб нові транспорти не розходилися: +Live transport lanes мають спільний стандартний контракт, щоб нові транспорти не розходилися в поведінці: -`qa-channel` залишається широким синтетичним QA-набором і не входить до матриці покриття live -transport. +`qa-channel` залишається широким синтетичним QA-набором і не входить до матриці покриття live transport. -| Лайн | Canary | Гейтінг згадок | Блокування allowlist | Відповідь верхнього рівня | Відновлення після перезапуску | Подальше повідомлення в треді | Ізоляція тредів | Спостереження реакцій | Команда help | -| ------- | ------ | -------------- | -------------------- | ------------------------- | ----------------------------- | ----------------------------- | --------------- | --------------------- | ------------ | -| Matrix | x | x | x | x | x | x | x | x | | -| Telegram | x | | | | | | | | x | +| Lane | Canary | Mention gating | Allowlist block | Top-level reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command | +| -------- | ------ | -------------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ | +| Matrix | x | x | x | x | x | x | x | x | | +| Telegram | x | | | | | | | | x | ### Спільні облікові дані Telegram через Convex (v1) Коли для `openclaw qa telegram` увімкнено `--credential-source convex` (або `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`), -QA lab отримує ексклюзивний lease із пулу на базі Convex, надсилає Heartbeat -для цього lease, поки виконується лайн, і звільняє lease під час завершення роботи. +QA lab отримує ексклюзивну оренду з пулу на базі Convex, надсилає Heartbeat +цієї оренди під час виконання lane і звільняє оренду під час завершення. -Еталонний scaffold проєкту Convex: +Еталонний каркас проєкту Convex: - `qa/convex-credential-broker/` -Обов’язкові env-змінні: +Обов’язкові змінні env: - `OPENCLAW_QA_CONVEX_SITE_URL` (наприклад, `https://your-deployment.convex.site`) -- Один секрет для вибраної ролі: +- Один secret для вибраної ролі: - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` для `maintainer` - `OPENCLAW_QA_CONVEX_SECRET_CI` для `ci` - Вибір ролі облікових даних: - CLI: `--credential-role maintainer|ci` - Типове значення env: `OPENCLAW_QA_CREDENTIAL_ROLE` (типово `ci` у CI, інакше `maintainer`) -Необов’язкові env-змінні: +Необов’язкові змінні env: - `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (типово `1200000`) - `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (типово `30000`) @@ -262,14 +260,14 @@ QA lab отримує ексклюзивний lease із пулу на базі - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (типово `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (типово `/qa-credentials/v1`) - `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (необов’язковий trace id) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` дозволяє loopback `http://` URL Convex лише для локальної розробки. +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` дозволяє loopback `http://` URL-адреси Convex лише для локальної розробки. -У звичайному режимі `OPENCLAW_QA_CONVEX_SITE_URL` має використовувати `https://`. +У звичайному режимі роботи `OPENCLAW_QA_CONVEX_SITE_URL` має використовувати `https://`. -Адміністраторські команди maintainer (додати/видалити/перелічити пул) потребують +Адміністративні команди maintainer (додавання/видалення/перелік пулу) вимагають саме `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`. -Допоміжні CLI-команди для maintainer: +Допоміжні команди CLI для maintainer: ```bash pnpm openclaw qa credentials doctor @@ -278,10 +276,9 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -Перед live-запусками використовуйте `doctor`, щоб перевірити URL сайту Convex, секрети -broker, префікс endpoint, HTTP timeout і доступність admin/list без виведення -значень секретів. Використовуйте `--json` для машиночитаного виводу в скриптах і CI -утилітах. +Використовуйте `doctor` перед live-запусками, щоб перевірити URL сайту Convex, secrets брокера, +префікс endpoint, HTTP timeout і доступність admin/list без виведення +значень secret. Використовуйте `--json` для machine-readable output у скриптах і утилітах CI. Типовий контракт endpoint (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): @@ -295,74 +292,74 @@ broker, префікс endpoint, HTTP timeout і доступність admin/li - `POST /release` - Запит: `{ kind, ownerId, actorRole, credentialId, leaseToken }` - Успіх: `{ status: "ok" }` (або порожній `2xx`) -- `POST /admin/add` (лише секрет maintainer) +- `POST /admin/add` (лише secret maintainer) - Запит: `{ kind, actorId, payload, note?, status? }` - Успіх: `{ status: "ok", credential }` -- `POST /admin/remove` (лише секрет maintainer) +- `POST /admin/remove` (лише secret maintainer) - Запит: `{ credentialId, actorId }` - Успіх: `{ status: "ok", changed, credential }` - - Захист від активного lease: `{ status: "error", code: "LEASE_ACTIVE", ... }` -- `POST /admin/list` (лише секрет maintainer) + - Захист активної оренди: `{ status: "error", code: "LEASE_ACTIVE", ... }` +- `POST /admin/list` (лише secret maintainer) - Запит: `{ kind?, status?, includePayload?, limit? }` - Успіх: `{ status: "ok", credentials, count }` Форма payload для типу Telegram: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` має бути рядком із числовим Telegram chat id. -- `admin/add` валідує цю форму для `kind: "telegram"` і відхиляє некоректні payload. +- `groupId` має бути рядком числового chat id Telegram. +- `admin/add` перевіряє цю форму для `kind: "telegram"` і відхиляє некоректні payload. -### Додавання каналу до QA +### Додавання channel до QA -Додавання каналу до markdown-системи QA потребує рівно двох речей: +Додавання channel до markdown-системи QA вимагає рівно двох речей: -1. Транспортного адаптера для каналу. -2. Пакета сценаріїв, який перевіряє контракт каналу. +1. Транспортного adapter для channel. +2. Пакета сценаріїв, який перевіряє контракт channel. -Не додавайте новий кореневий QA-командний простір верхнього рівня, якщо спільний хост `qa-lab` може -керувати цим потоком. +Не додавайте новий кореневий QA-командний простір верхнього рівня, якщо спільний host `qa-lab` може +володіти цим потоком. -`qa-lab` керує спільною механікою хоста: +`qa-lab` володіє спільною механікою host: - коренем команди `openclaw qa` - запуском і завершенням набору -- конкурентністю worker +- паралелізмом воркерів - записом артефактів - генерацією звітів - виконанням сценаріїв -- compatibility aliases для старих сценаріїв `qa-channel` +- alias сумісності для старіших сценаріїв `qa-channel` -Plugin раннера керують транспортним контрактом: +Runner plugins володіють транспортним контрактом: - як `openclaw qa ` монтується під спільним коренем `qa` -- як налаштовується gateway для цього транспорту +- як Gateway налаштовується для цього транспорту - як перевіряється готовність - як інжектуються вхідні події - як спостерігаються вихідні повідомлення - як надаються transcript і нормалізований стан транспорту - як виконуються дії на базі транспорту -- як обробляється transport-specific reset або cleanup +- як обробляється транспортно-специфічне скидання або очищення -Мінімальний поріг впровадження для нового каналу: +Мінімальний поріг впровадження для нового channel: -1. Залиште `qa-lab` власником спільного кореня `qa`. -2. Реалізуйте транспортний раннер на спільному seam хоста `qa-lab`. -3. Зберігайте transport-specific механіку всередині Plugin раннера або harness каналу. -4. Монтуйте раннер як `openclaw qa `, а не реєструйте конкуруючий кореневий command. - Plugin раннера мають оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` з `runtime-api.ts`. - Зберігайте `runtime-api.ts` легким; lazy CLI і виконання раннера мають залишатися за окремими entrypoint. +1. Зберігайте `qa-lab` як власника спільного кореня `qa`. +2. Реалізуйте transport runner на спільному host seam `qa-lab`. +3. Зберігайте транспортно-специфічну механіку всередині runner Plugin або harness channel. +4. Монтуйте runner як `openclaw qa ` замість реєстрації конкуруючої кореневої команди. + Runner plugins мають оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` із `runtime-api.ts`. + Тримайте `runtime-api.ts` легким; ледаче виконання CLI і runner має залишатися за окремими entrypoint. 5. Створюйте або адаптуйте markdown-сценарії в тематичних каталогах `qa/scenarios/`. -6. Для нових сценаріїв використовуйте загальні scenario helper. -7. Зберігайте наявні compatibility aliases працездатними, якщо тільки репозиторій не виконує навмисну міграцію. +6. Використовуйте загальні helper-и сценаріїв для нових сценаріїв. +7. Зберігайте наявні alias сумісності працюючими, якщо тільки репозиторій не виконує навмисну міграцію. -Правило прийняття рішення суворе: +Правило ухвалення рішення суворе: -- Якщо поведінку можна один раз виразити в `qa-lab`, розміщуйте її в `qa-lab`. -- Якщо поведінка залежить від одного транспортного каналу, зберігайте її в Plugin цього раннера або в harness plugin. -- Якщо сценарію потрібна нова можливість, яку може використовувати більш ніж один канал, додайте загальний helper замість channel-specific гілки в `suite.ts`. -- Якщо поведінка має сенс лише для одного транспорту, зберігайте сценарій transport-specific і явно позначайте це в контракті сценарію. +- Якщо поведінку можна виразити один раз у `qa-lab`, розміщуйте її в `qa-lab`. +- Якщо поведінка залежить від одного транспорту channel, зберігайте її в цьому runner Plugin або harness Plugin. +- Якщо сценарію потрібна нова можливість, яку може використати більше ніж один channel, додавайте загальний helper замість channel-специфічної гілки в `suite.ts`. +- Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій транспортно-специфічним і явно вказуйте це в контракті сценарію. -Бажані назви загальних helper для нових сценаріїв: +Переважні назви загальних helper-ів для нових сценаріїв: - `waitForTransportReady` - `waitForChannelReady` @@ -377,7 +374,7 @@ Plugin раннера керують транспортним контракто - `formatTransportTranscript` - `resetTransport` -Compatibility aliases залишаються доступними для наявних сценаріїв, зокрема: +Alias сумісності залишаються доступними для наявних сценаріїв, зокрема: - `waitForQaChannelReady` - `waitForOutboundMessage` @@ -385,8 +382,8 @@ Compatibility aliases залишаються доступними для ная - `formatConversationTranscript` - `resetBus` -Нова робота з каналами має використовувати загальні назви helper. -Compatibility aliases існують, щоб уникнути міграції одним днем, а не як модель для +Нова робота над channel має використовувати загальні назви helper-ів. +Alias сумісності існують, щоб уникнути міграції за принципом flag day, а не як модель для створення нових сценаріїв. ## Набори тестів (що де запускається) @@ -396,57 +393,58 @@ Compatibility aliases існують, щоб уникнути міграції ### Unit / integration (типово) - Команда: `pnpm test` -- Config: нетаргетовані запуски використовують набір shard `vitest.full-*.config.ts` і можуть розгортати multi-project shard у конфігурації для кожного проєкту для паралельного планування -- Файли: core/unit inventory у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelist тести `ui` для node, які покриває `vitest.unit.config.ts` +- Config: ненаправлені запуски використовують набір шардів `vitest.full-*.config.ts` і можуть розгортати багатопроєктні шарди в конфігурації окремих проєктів для паралельного планування +- Файли: інвентарі core/unit у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і дозволені node-тести `ui`, які покриваються `vitest.unit.config.ts` - Обсяг: - Чисті unit-тести - - In-process integration-тести (auth gateway, маршрутизація, tooling, парсинг, config) - - Детерміновані регресії для відомих багів + - In-process integration-тести (автентифікація gateway, маршрутизація, tooling, парсинг, config) + - Детерміновані регресійні тести для відомих помилок - Очікування: - Запускається в CI - Реальні ключі не потрібні - Має бути швидким і стабільним - + - - Нетаргетований `pnpm test` запускає дванадцять менших shard-конфігурацій (`core-unit-fast`, `core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського процесу native root-project. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension виснажувати не пов’язані набори. - - `pnpm test --watch` як і раніше використовує граф проєктів native root `vitest.config.ts`, оскільки цикл спостереження з кількома shard непрактичний. - - `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped-лайни, тому `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` не сплачує повну ціну запуску root project. - - `pnpm test:changed` розгортає змінені шляхи git у ті самі scoped-лайни, коли diff торкається лише routable вихідних/тестових файлів; редагування config/setup, як і раніше, повертаються до широкого повторного запуску root-project. - - `pnpm check:changed` — це звичайний розумний локальний gate для вузької роботи. Він класифікує diff на core, тести core, extensions, тести extension, apps, docs, метадані релізу, live Docker tooling і tooling, а потім запускає відповідні лайни typecheck/lint/test. Зміни публічного Plugin SDK і plugin-contract включають один validation-прохід extension, оскільки extensions залежать від цих контрактів core. Оновлення версій лише в metadata релізу запускають цільові перевірки version/config/root-dependency замість повного набору, із захистом, який відхиляє зміни package поза полем version верхнього рівня. - - Редагування harness live Docker ACP запускають фокусований локальний gate: shell syntax для скриптів auth live Docker, dry-run планувальника live Docker, unit-тести ACP bind і тести extension ACPX. Зміни `package.json` включаються лише тоді, коли diff обмежений `scripts["test:docker:live-*"]`; редагування dependency, export, version та інших поверхонь package, як і раніше, використовують ширші guard. - - Import-light unit-тести з agents, commands, plugins, helper auto-reply, `plugin-sdk` та подібних чистих utility-ділянок маршрутизуються через лайн `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy файли залишаються в наявних лайнах. - - Вибрані helper-вихідні файли `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними sibling-тестами в цих light-лайнах, тож редагування helper уникають повторного запуску повного важкого набору для цього каталогу. - - `auto-reply` має окремі bucket для helper core верхнього рівня, integration-тестів `reply.*` верхнього рівня та піддерева `src/auto-reply/reply/**`. CI додатково розділяє піддерево reply на shard agent-runner, dispatch і commands/state-routing, щоб один import-heavy bucket не контролював увесь хвіст Node. + - Ненаправлений `pnpm test` запускає дванадцять менших shard-configs (`core-unit-fast`, `core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського native root-project process. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension виснажувати не пов’язані набори. + - `pnpm test --watch` усе ще використовує native root project graph `vitest.config.ts`, оскільки multi-shard цикл watch непрактичний. + - `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped lanes, тож `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` уникає повної вартості запуску root project. + - `pnpm test:changed` за замовчуванням розгортає змінені git-шляхи в дешеві scoped lanes: прямі зміни тестів, сусідні файли `*.test.ts`, явні відображення вихідного коду та локальні залежні елементи import graph. Зміни config/setup/package не запускають тести широко, якщо ви явно не використовуєте `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`. + - `pnpm check:changed` — це звичайна розумна локальна перевірка для вузьких змін. Вона класифікує diff на core, core tests, extensions, extension tests, apps, docs, release metadata, live Docker tooling і tooling, а потім запускає відповідні команди typecheck, lint і guard. Вона не запускає тести Vitest; для підтвердження тестів викликайте `pnpm test:changed` або явний `pnpm test `. Підвищення версії лише в release metadata запускають цільові перевірки version/config/root-dependency із guard, який відхиляє зміни package поза полем версії верхнього рівня. + - Зміни live Docker ACP harness запускають цільові перевірки: синтаксис shell для скриптів автентифікації live Docker і dry-run планувальника live Docker. Зміни `package.json` включаються лише тоді, коли diff обмежено `scripts["test:docker:live-*"]`; зміни dependency, export, version та іншої поверхні package, як і раніше, використовують ширші guard-и. + - Полегшені за import unit-тести з agents, commands, plugins, helper-ів auto-reply, `plugin-sdk` і подібних чисто утилітарних областей маршрутизуються через lane `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; файли зі станом/важким runtime залишаються на наявних lanes. + - Вибрані helper source files у `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними сусідніми тестами в цих легких lanes, щоб редагування helper-ів не перезапускали повний важкий набір для цього каталогу. + - `auto-reply` має окремі buckets для helper-ів core верхнього рівня, integration-тестів верхнього рівня `reply.*` і піддерева `src/auto-reply/reply/**`. У CI піддерево reply додатково розбивається на shard-и agent-runner, dispatch і commands/state-routing, щоб один bucket із важкими import не володів усім Node tail. - - Коли ви змінюєте вхідні дані виявлення message-tool або runtime context Compaction, зберігайте обидва рівні покриття. - - Додавайте фокусовані helper-регресії для чистих меж маршрутизації та нормалізації. - - Підтримуйте справність integration-наборів embedded runner: + - Коли ви змінюєте вхідні дані виявлення message-tool або runtime context Compaction, + зберігайте обидва рівні покриття. + - Додавайте цільові регресії helper-ів для чистих меж маршрутизації та нормалізації. + - Підтримуйте integration-набори embedded runner у робочому стані: `src/agents/pi-embedded-runner/compact.hooks.test.ts`, `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` і `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`. - - Ці набори перевіряють, що scoped id і поведінка Compaction, як і раніше, проходять - через реальні шляхи `run.ts` / `compact.ts`; самі лише helper-тести не є + - Ці набори перевіряють, що scoped id і поведінка Compaction як і раніше проходять + через реальні шляхи `run.ts` / `compact.ts`; тести лише helper-ів не є достатньою заміною для цих integration-шляхів. - + - - Базовий config Vitest типово використовує `threads`. + - Базовий config Vitest за замовчуванням використовує `threads`. - Спільний config Vitest фіксує `isolate: false` і використовує - non-isolated runner для root project, e2e і live config. - - Кореневий лайн UI зберігає свій `jsdom` setup і optimizer, але також запускається на - спільному non-isolated runner. + runner без isolation у root projects, e2e і live configs. + - Кореневий lane UI зберігає свій `jsdom` setup та optimizer, але теж працює на + спільному runner без isolation. - Кожен shard `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false` зі спільного config Vitest. - - `scripts/run-vitest.mjs` типово додає `--no-maglev` для дочірніх Node-процесів Vitest, - щоб зменшити churn компіляції V8 під час великих локальних запусків. + - `scripts/run-vitest.mjs` за замовчуванням додає `--no-maglev` для дочірніх Node process + Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. Встановіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, щоб порівняти зі стандартною поведінкою V8. @@ -454,141 +452,144 @@ Compatibility aliases існують, щоб уникнути міграції - - `pnpm changed:lanes` показує, які архітектурні лайни запускає diff. - - Pre-commit hook виконує лише форматування. Він повторно додає форматовані файли в stage і + - `pnpm changed:lanes` показує, які архітектурні lanes запускає diff. + - Pre-commit hook виконує лише форматування. Він повторно додає відформатовані файли до staging і не запускає lint, typecheck або тести. - - Явно запускайте `pnpm check:changed` перед передачею або push, коли - вам потрібен розумний локальний gate. Зміни публічного Plugin SDK і plugin-contract - включають один validation-прохід extension. - - `pnpm test:changed` маршрутизує через scoped-лайни, коли змінені шляхи - чітко відповідають меншому набору. + - Явно запускайте `pnpm check:changed` перед передачею або push, коли вам + потрібна розумна локальна перевірка. + - `pnpm test:changed` за замовчуванням маршрутизується через дешеві scoped lanes. Використовуйте + `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed` лише тоді, коли агент + вирішує, що редагування harness, config, package або contract справді потребує ширшого + покриття Vitest. - `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації, - лише з вищою межею worker. - - Автомасштабування локальних worker навмисно консервативне і знижує навантаження, + лише з вищою межею воркерів. + - Автоматичне масштабування локальних воркерів навмисно консервативне і знижує навантаження, коли середнє навантаження хоста вже високе, тому кілька одночасних запусків Vitest за замовчуванням завдають менше шкоди. - - Базовий config Vitest позначає файли project/config як - `forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними - при зміні wiring тестів. - - Config зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних - хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо вам потрібне - одне явне розташування кешу для прямого профілювання. + - Базовий config Vitest позначає проєкти/config files як + `forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними, + коли змінюється прив’язка тестів. + - Config тримає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних + хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо хочете + одну явну локацію кешу для прямого профілювання. - - `pnpm test:perf:imports` вмикає звітування Vitest про тривалість import, а також - вивід деталізації import. - - `pnpm test:perf:imports:changed` обмежує той самий вигляд профілювання - файлами, зміненими відносно `origin/main`. - - Дані про час виконання shard записуються в `.artifacts/vitest-shard-timings.json`. - Запуски всього config використовують шлях config як ключ; shard CI з include-pattern - додають ім’я shard, щоб відфільтровані shard можна було + - `pnpm test:perf:imports` вмикає звітність Vitest про тривалість import, а також + вивід import-breakdown. + - `pnpm test:perf:imports:changed` обмежує той самий режим профілювання + файлами, зміненими від `origin/main`. + - Дані про час shard-ів записуються в `.artifacts/vitest-shard-timings.json`. + Запуски всього config використовують шлях config як ключ; shard-и CI + з include-pattern додають ім’я shard, щоб відфільтровані shard-и можна було відстежувати окремо. - - Коли один гарячий тест усе ще витрачає більшість часу на startup import, - тримайте важкі dependency за вузьким локальним seam `*.runtime.ts` і напряму мокуйте - цей seam замість deep-import runtime helper лише для того, щоб передати їх через `vi.mock(...)`. + - Коли один гарячий тест усе ще витрачає більшу частину часу на стартові import, + тримайте важкі залежності за вузьким локальним seam `*.runtime.ts` і + мокайте цей seam безпосередньо замість deep-import runtime helper-ів лише + для того, щоб передати їх через `vi.mock(...)`. - `pnpm test:perf:changed:bench -- --ref ` порівнює маршрутизований - `test:changed` з native шляхом root-project для цього закоміченого diff і виводить wall time плюс macOS max RSS. - - `pnpm test:perf:changed:bench -- --worktree` бенчмаркує поточне брудне дерево, - маршрутизуючи список змінених файлів через - `scripts/test-projects.mjs` і root config Vitest. - - `pnpm test:perf:profile:main` записує CPU profile головного потоку для + `test:changed` із native root-project path для цього зафіксованого + diff і виводить wall time плюс max RSS на macOS. + - `pnpm test:perf:changed:bench -- --worktree` виконує benchmark поточного + брудного дерева, маршрутизуючи список змінених файлів через + `scripts/test-projects.mjs` і кореневий config Vitest. + - `pnpm test:perf:profile:main` записує CPU profile основного потоку для startup і transform overhead у Vitest/Vite. - - `pnpm test:perf:profile:runner` записує CPU+heap profile раннера для - unit-набору з вимкненим file parallelism. + - `pnpm test:perf:profile:runner` записує CPU+heap profiles runner-а для + unit-набору з вимкненим паралелізмом файлів. -### Стабільність (Gateway) +### Стабільність (gateway) - Команда: `pnpm test:stability:gateway` -- Config: `vitest.gateway.config.ts`, примусово один worker +- Config: `vitest.gateway.config.ts`, примусово один воркер - Обсяг: - - Запускає реальний loopback Gateway з увімкненою діагностикою за замовчуванням - - Пропускає синтетичне навантаження повідомлень gateway, пам’яті та великих payload через шлях діагностичних подій - - Виконує запит до `diagnostics.stability` через Gateway WS RPC - - Покриває helper збереження diagnostic stability bundle - - Перевіряє, що recorder залишається обмеженим, синтетичні вибірки RSS не перевищують бюджет тиску, а глибина черги для кожної сесії знову спадає до нуля + - Запускає реальний loopback Gateway із діагностикою, увімкненою за замовчуванням + - Проганяє синтетичне churn повідомлень gateway, пам’яті та великих payload через шлях діагностичних подій + - Виконує запит до `diagnostics.stability` через WS RPC Gateway + - Покриває helper-и збереження діагностичного stability bundle + - Перевіряє, що recorder залишається обмеженим, синтетичні зразки RSS не перевищують бюджет тиску, а глибина черги для кожної сесії знову зменшується до нуля - Очікування: - Безпечно для CI і без ключів - - Вузький лайн для подальшого опрацювання регресій стабільності, а не заміна повного набору Gateway + - Вузький lane для подальшої роботи над регресіями стабільності, а не заміна повного набору Gateway ### E2E (gateway smoke) - Команда: `pnpm test:e2e` - Config: `vitest.e2e.config.ts` -- Файли: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` і E2E-тести bundled-plugin у `extensions/` +- Файли: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` і E2E-тести вбудованих Plugin у `extensions/` - Типові параметри runtime: - - Використовує Vitest `threads` з `isolate: false`, як і решта репозиторію. - - Використовує adaptive worker (CI: до 2, локально: типово 1). - - За замовчуванням запускається в silent mode, щоб зменшити накладні витрати на console I/O. + - Використовує `threads` Vitest з `isolate: false`, як і в решті репозиторію. + - Використовує адаптивну кількість воркерів (CI: до 2, локально: 1 за замовчуванням). + - За замовчуванням працює в тихому режимі, щоб зменшити накладні витрати на console I/O. - Корисні перевизначення: - - `OPENCLAW_E2E_WORKERS=`, щоб примусово задати кількість worker (обмежено 16). + - `OPENCLAW_E2E_WORKERS=`, щоб примусово задати кількість воркерів (обмежено 16). - `OPENCLAW_E2E_VERBOSE=1`, щоб знову ввімкнути докладний вивід у console. - Обсяг: - - End-to-end поведінка gateway з кількома екземплярами - - Поверхні WebSocket/HTTP, pairing Node і важче мережеве навантаження + - End-to-end поведінка gateway з кількома інстансами + - Поверхні WebSocket/HTTP, pairing Node і складніший networking - Очікування: - - Запускається в CI (коли ввімкнено в pipeline) + - Запускається в CI (коли увімкнено в pipeline) - Реальні ключі не потрібні - - Має більше рухомих частин, ніж unit-тести (може бути повільніше) + - Більше рухомих частин, ніж у unit-тестах (може бути повільніше) -### E2E: smoke OpenShell backend +### E2E: smoke backend OpenShell - Команда: `pnpm test:e2e:openshell` - Файл: `extensions/openshell/src/backend.e2e.test.ts` - Обсяг: - Запускає ізольований Gateway OpenShell на хості через Docker - Створює sandbox з тимчасового локального Dockerfile - - Виконує backend OpenShell в OpenClaw через реальні `sandbox ssh-config` + SSH exec - - Перевіряє remote-canonical поведінку файлової системи через sandbox fs bridge + - Перевіряє backend OpenShell OpenClaw через реальні `sandbox ssh-config` + SSH exec + - Перевіряє поведінку remote-canonical filesystem через fs bridge sandbox - Очікування: - - Лише opt-in; не є частиною типового запуску `pnpm test:e2e` - - Потребує локальний CLI `openshell` і працездатний Docker daemon - - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, після чого знищує test gateway і sandbox + - Лише за запитом; не входить до типового запуску `pnpm test:e2e` + - Потребує локальний CLI `openshell` і робочий Docker daemon + - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, а потім знищує тестовий gateway і sandbox - Корисні перевизначення: - - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого e2e-набору - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб вказати нестандартний двійковий файл CLI або wrapper script + - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого набору e2e + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб вказати нестандартний бінарний файл CLI або wrapper script ### Live (реальні провайдери + реальні моделі) - Команда: `pnpm test:live` - Config: `vitest.live.config.ts` -- Файли: `src/**/*.live.test.ts`, `test/**/*.live.test.ts` і live-тести bundled-plugin у `extensions/` +- Файли: `src/**/*.live.test.ts`, `test/**/*.live.test.ts` і live-тести вбудованих Plugin у `extensions/` - Типово: **увімкнено** через `pnpm test:live` (встановлює `OPENCLAW_LIVE_TEST=1`) - Обсяг: - - «Чи цей провайдер/модель справді працює _сьогодні_ з реальними обліковими даними?» - - Виявлення змін формату провайдера, особливостей виклику інструментів, проблем auth і поведінки rate limit + - «Чи справді цей провайдер/модель працює _сьогодні_ з реальними обліковими даними?» + - Виявлення змін формату провайдера, особливостей виклику tool, проблем автентифікації та поведінки rate limit - Очікування: - За задумом не є стабільним для CI (реальні мережі, реальні політики провайдерів, квоти, збої) - - Коштує грошей / використовує rate limit + - Коштує грошей / використовує rate limits - Краще запускати звужені підмножини, а не «все» -- Live-запуски підвантажують `~/.profile`, щоб отримати відсутні API key. -- За замовчуванням live-запуски все одно ізолюють `HOME` і копіюють матеріали config/auth у тимчасовий test home, щоб unit-fixture не могли змінити ваш реальний `~/.openclaw`. -- Встановлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли навмисно потрібно, щоб live-тести використовували ваш реальний home-каталог. -- `pnpm test:live` тепер за замовчуванням працює в тихішому режимі: він зберігає вивід прогресу `[live] ...`, але приглушує додаткове повідомлення `~/.profile` і вимикає bootstrap-логи gateway/шум Bonjour. Встановіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете повернути повні startup-логи. -- Ротація API key (залежно від провайдера): встановіть `*_API_KEYS` у форматі comma/semicolon або `*_API_KEY_1`, `*_API_KEY_2` (наприклад `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) чи використайте перевизначення для live через `OPENCLAW_LIVE_*_KEY`; тести повторюють спробу у відповідь на rate limit. -- Вивід прогресу/Heartbeat: - - Live-набори тепер виводять рядки прогресу в stderr, тож довгі виклики провайдера залишаються видимо активними, навіть коли перехоплення console у Vitest тихе. - - `vitest.live.config.ts` вимикає перехоплення console у Vitest, щоб рядки прогресу провайдера/gateway одразу передавалися під час live-запусків. - - Налаштовуйте Heartbeat для direct-model через `OPENCLAW_LIVE_HEARTBEAT_MS`. +- Live-запуски підключають `~/.profile`, щоб підхопити відсутні API keys. +- За замовчуванням live-запуски все одно ізолюють `HOME` і копіюють матеріали config/auth у тимчасовий тестовий home, щоб unit-fixtures не могли змінити ваш реальний `~/.openclaw`. +- Встановлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли свідомо хочете, щоб live-тести використовували ваш реальний домашній каталог. +- `pnpm test:live` тепер за замовчуванням використовує тихіший режим: він зберігає вивід прогресу `[live] ...`, але пригнічує додаткове повідомлення `~/.profile` і заглушує логи bootstrap Gateway/шум Bonjour. Встановіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете повернути повні стартові логи. +- Ротація API keys (залежно від провайдера): задавайте `*_API_KEYS` у форматі через кому/крапку з комою або `*_API_KEY_1`, `*_API_KEY_2` (наприклад, `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) або перевизначення для конкретного live-запуску через `OPENCLAW_LIVE_*_KEY`; тести повторюють спробу у відповідь на rate limit. +- Вивід progress/Heartbeat: + - Live-набори тепер виводять рядки прогресу в stderr, тому довгі виклики провайдерів видно як активні навіть коли захоплення console у Vitest тихе. + - `vitest.live.config.ts` вимикає перехоплення console у Vitest, тож рядки progress провайдера/Gateway передаються одразу під час live-запусків. + - Налаштовуйте Heartbeat прямих моделей через `OPENCLAW_LIVE_HEARTBEAT_MS`. - Налаштовуйте Heartbeat gateway/probe через `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. ## Який набір мені запускати? -Скористайтеся цією таблицею рішень: +Використовуйте цю таблицю рішень: -- Редагуєте логіку/тести: запускайте `pnpm test` (і `pnpm test:coverage`, якщо змінили багато) -- Торкаєтеся мережевої взаємодії gateway / WS protocol / pairing: додайте `pnpm test:e2e` -- Налагоджуєте «мій bot не працює» / збої, специфічні для провайдера / виклик інструментів: запускайте звужений `pnpm test:live` +- Редагування логіки/тестів: запускайте `pnpm test` (і `pnpm test:coverage`, якщо змінили багато) +- Зміни в networking gateway / протоколі WS / pairing: додайте `pnpm test:e2e` +- Налагодження «мій бот не працює» / збоїв, специфічних для провайдера / виклику tool: запускайте звужений `pnpm test:live` -## Live (мережеві) тести +## Live-тести (які торкаються мережі) -Для live matrix моделей, smoke CLI backend, smoke ACP, harness app-server Codex -і всіх live-тестів media-provider (Deepgram, BytePlus, ComfyUI, image, +Для матриці live-моделей, smoke-тестів CLI backend, smoke ACP, harness Codex app-server +і всіх live-тестів медіапровайдерів (Deepgram, BytePlus, ComfyUI, image, music, video, media harness) — а також обробки облікових даних для live-запусків — див. [Тестування — live-набори](/uk/help/testing-live). @@ -596,221 +597,221 @@ music, video, media harness) — а також обробки облікових Ці ранери Docker поділяються на дві категорії: -- Ранери live-моделей: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний live-файл для свого profile-key всередині Docker-образу репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог config і workspace (і підвантажують `~/.profile`, якщо його змонтовано). Відповідні локальні entrypoint — `test:live:models-profiles` і `test:live:gateway-profiles`. -- Ранери Docker live за замовчуванням мають меншу межу smoke, щоб повний Docker-прохід залишався практичним: +- Live-model ранери: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний live-файл із ключем профілю всередині образу Docker репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог config і робочу область (і підключають `~/.profile`, якщо змонтовано). Відповідні локальні entrypoint — `test:live:models-profiles` і `test:live:gateway-profiles`. +- За замовчуванням Docker live runners використовують менше обмеження smoke, щоб повний Docker sweep залишався практичним: `test:docker:live-models` типово використовує `OPENCLAW_LIVE_MAX_MODELS=12`, а `test:docker:live-gateway` типово використовує `OPENCLAW_LIVE_GATEWAY_SMOKE=1`, `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`, `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` і - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Перевизначайте ці env-змінні, коли - вам явно потрібен більший вичерпний прохід. -- `test:docker:all` один раз збирає live Docker-образ через `test:docker:live-build`, один раз пакує OpenClaw як npm tarball через `scripts/package-openclaw-for-docker.mjs`, а потім збирає/повторно використовує два образи `scripts/e2e/Dockerfile`. Базовий образ — це лише раннер Node/Git для лайнів install/update/plugin-dependency; ці лайни монтують попередньо зібраний tarball. Функціональний образ встановлює той самий tarball у `/app` для лайнів функціональності зібраного застосунку. Визначення Docker-лайнів містяться в `scripts/lib/docker-e2e-scenarios.mjs`; логіка planner міститься в `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` виконує вибраний план. Агрегатор використовує зважений локальний scheduler: `OPENCLAW_DOCKER_ALL_PARALLELISM` керує слотами процесів, а ліміти ресурсів не дають усім важким live-, npm-install- і multi-service-лайнам стартувати одночасно. Типові значення: 10 слотів, `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; налаштовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` лише тоді, коли Docker-хост має більший запас ресурсів. Раннер за замовчуванням виконує Docker preflight, видаляє застарілі контейнери OpenClaw E2E, виводить статус кожні 30 секунд, зберігає час виконання успішних лайнів у `.artifacts/docker-tests/lane-timings.json` і використовує ці дані, щоб у наступних запусках спочатку стартували довші лайни. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести зважений маніфест лайнів без збирання або запуску Docker, або `node scripts/test-docker-all.mjs --plan-json`, щоб вивести план CI для вибраних лайнів, потреб package/image і облікових даних. -- Контейнерні smoke-ранери: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:npm-onboard-channel-agent`, `test:docker:update-channel-switch`, `test:docker:session-runtime-context`, `test:docker:agents-delete-shared-workspace`, `test:docker:gateway-network`, `test:docker:browser-cdp-snapshot`, `test:docker:mcp-channels`, `test:docker:pi-bundle-mcp-tools`, `test:docker:cron-mcp-cleanup`, `test:docker:plugins`, `test:docker:plugin-update` і `test:docker:config-reload` запускають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня. + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Перевизначайте ці змінні env, коли + вам явно потрібне більше вичерпне сканування. +- `test:docker:all` один раз збирає live Docker image через `test:docker:live-build`, один раз пакує OpenClaw як npm tarball через `scripts/package-openclaw-for-docker.mjs`, а потім збирає/повторно використовує два образи `scripts/e2e/Dockerfile`. Базовий образ — це лише раннер Node/Git для lane встановлення/оновлення/залежностей Plugin; ці lanes монтують попередньо зібраний tarball. Функціональний образ встановлює той самий tarball у `/app` для lane функціональності built-app. Визначення Docker lanes знаходяться в `scripts/lib/docker-e2e-scenarios.mjs`; логіка planner — у `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` виконує вибраний план. Агрегатор використовує зважений локальний scheduler: `OPENCLAW_DOCKER_ALL_PARALLELISM` керує слотами процесів, а обмеження ресурсів не дають важким live, npm-install і multi-service lanes запускатися одночасно. Типові значення — 10 слотів, `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; налаштовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` лише тоді, коли хост Docker має більше запасу ресурсів. За замовчуванням раннер виконує Docker preflight, видаляє застарілі контейнери OpenClaw E2E, друкує статус кожні 30 секунд, зберігає час успішних lanes у `.artifacts/docker-tests/lane-timings.json` і використовує ці значення часу, щоб у наступних запусках спочатку запускати довші lanes. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб надрукувати зважений маніфест lanes без збирання чи запуску Docker, або `node scripts/test-docker-all.mjs --plan-json`, щоб вивести план CI для вибраних lanes, потреб package/image і облікових даних. +- Container smoke runners: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:npm-onboard-channel-agent`, `test:docker:update-channel-switch`, `test:docker:session-runtime-context`, `test:docker:agents-delete-shared-workspace`, `test:docker:gateway-network`, `test:docker:browser-cdp-snapshot`, `test:docker:mcp-channels`, `test:docker:pi-bundle-mcp-tools`, `test:docker:cron-mcp-cleanup`, `test:docker:plugins`, `test:docker:plugin-update` і `test:docker:config-reload` запускають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня. -Docker-ранери live-моделей також bind-mount лише потрібні auth-home для CLI (або всі підтримувані, якщо запуск не звужений), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без зміни auth-store хоста: +Docker runners для live-моделей також bind-mount лише потрібні домівки автентифікації CLI (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без змін у сховищі автентифікації хоста: - Прямі моделі: `pnpm test:docker:live-models` (скрипт: `scripts/test-live-models-docker.sh`) -- Smoke ACP bind: `pnpm test:docker:live-acp-bind` (скрипт: `scripts/test-live-acp-bind-docker.sh`; за замовчуванням покриває Claude, Codex і Gemini, із суворим покриттям Droid/OpenCode через `pnpm test:docker:live-acp-bind:droid` і `pnpm test:docker:live-acp-bind:opencode`) +- Smoke ACP bind: `pnpm test:docker:live-acp-bind` (скрипт: `scripts/test-live-acp-bind-docker.sh`; за замовчуванням охоплює Claude, Codex і Gemini, із суворим покриттям Droid/OpenCode через `pnpm test:docker:live-acp-bind:droid` і `pnpm test:docker:live-acp-bind:opencode`) - Smoke CLI backend: `pnpm test:docker:live-cli-backend` (скрипт: `scripts/test-live-cli-backend-docker.sh`) -- Smoke harness app-server Codex: `pnpm test:docker:live-codex-harness` (скрипт: `scripts/test-live-codex-harness-docker.sh`) +- Smoke harness Codex app-server: `pnpm test:docker:live-codex-harness` (скрипт: `scripts/test-live-codex-harness-docker.sh`) - Gateway + dev agent: `pnpm test:docker:live-gateway` (скрипт: `scripts/test-live-gateway-models-docker.sh`) -- Live smoke Open WebUI: `pnpm test:docker:openwebui` (скрипт: `scripts/e2e/openwebui-docker.sh`) -- Майстер onboarding (TTY, повне scaffolding): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`) -- Smoke onboarding/channel/agent через npm tarball: `pnpm test:docker:npm-onboard-channel-agent` глобально встановлює упакований tarball OpenClaw у Docker, налаштовує OpenAI через onboarding env-ref плюс Telegram за замовчуванням, перевіряє, що doctor відновлює активовані runtime dependency plugin, і виконує один замоканий хід агента OpenAI. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть перебудову хоста через `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` або змініть канал через `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`. -- Smoke перемикання каналу оновлення: `pnpm test:docker:update-channel-switch` глобально встановлює упакований tarball OpenClaw у Docker, перемикається з package `stable` на git `dev`, перевіряє, що збережений канал і plugin після оновлення працюють, потім перемикається назад на package `stable` і перевіряє статус оновлення. -- Smoke runtime context сесії: `pnpm test:docker:session-runtime-context` перевіряє збереження transcript прихованого runtime context, а також відновлення doctor для уражених дубльованих гілок prompt-rewrite. -- Smoke глобального встановлення Bun: `bash scripts/e2e/bun-global-install-smoke.sh` пакує поточне дерево, встановлює його через `bun install -g` в ізольованому home і перевіряє, що `openclaw infer image providers --json` повертає bundled image provider замість зависання. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть збирання хоста через `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` або скопіюйте `dist/` із зібраного Docker-образу через `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local`. -- Installer Docker smoke: `bash scripts/test-install-sh-docker.sh` використовує спільний npm cache для контейнерів root, update і direct-npm. Smoke оновлення за замовчуванням використовує npm `latest` як стабільну базу перед оновленням до candidate tarball. Перевірки installer без root зберігають ізольований npm cache, щоб записи cache, які належать root, не маскували поведінку локального встановлення користувача. Встановіть `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`, щоб повторно використовувати cache root/update/direct-npm між локальними повторними запусками. -- Install Smoke у CI пропускає дубльоване пряме глобальне оновлення npm через `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1`; запускайте скрипт локально без цього env, коли потрібне покриття прямого `npm install -g`. -- CLI smoke видалення спільного workspace агентів: `pnpm test:docker:agents-delete-shared-workspace` (скрипт: `scripts/e2e/agents-delete-shared-workspace-docker.sh`) за замовчуванням збирає образ root Dockerfile, створює два agent з одним workspace в ізольованому home контейнера, запускає `agents delete --json` і перевіряє коректний JSON та поведінку збереженого workspace. Повторно використовуйте образ install-smoke через `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1`. -- Мережева взаємодія Gateway (два контейнери, WS auth + health): `pnpm test:docker:gateway-network` (скрипт: `scripts/e2e/gateway-network-docker.sh`) -- Smoke CDP snapshot браузера: `pnpm test:docker:browser-cdp-snapshot` (скрипт: `scripts/e2e/browser-cdp-snapshot-docker.sh`) збирає вихідний E2E-образ плюс шар Chromium, запускає Chromium із сирим CDP, виконує `browser doctor --deep` і перевіряє, що snapshot ролей CDP покривають URL посилань, clickables, підняті курсором, iframe refs і метадані frame. -- Мінімальна reasoning-регресія OpenAI Responses web_search: `pnpm test:docker:openai-web-search-minimal` (скрипт: `scripts/e2e/openai-web-search-minimal-docker.sh`) запускає замоканий сервер OpenAI через Gateway, перевіряє, що `web_search` підвищує `reasoning.effort` з `minimal` до `low`, потім примусово викликає відхилення schema у провайдера і перевіряє, що сирі деталі з’являються в логах Gateway. -- MCP channel bridge (seeded Gateway + stdio bridge + smoke сирого notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`) -- Інструменти MCP bundle Pi (реальний stdio MCP-сервер + smoke allow/deny для вбудованого профілю Pi): `pnpm test:docker:pi-bundle-mcp-tools` (скрипт: `scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Очищення Cron/subagent MCP (реальний Gateway + завершення дочірнього stdio MCP після ізольованого cron і одноразових запусків subagent): `pnpm test:docker:cron-mcp-cleanup` (скрипт: `scripts/e2e/cron-mcp-cleanup-docker.sh`) +- Smoke Open WebUI live: `pnpm test:docker:openwebui` (скрипт: `scripts/e2e/openwebui-docker.sh`) +- Wizard онбордингу (TTY, повне scaffolding): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`) +- Smoke онбордингу/channel/agent для npm tarball: `pnpm test:docker:npm-onboard-channel-agent` глобально встановлює запакований tarball OpenClaw у Docker, налаштовує OpenAI через онбординг env-ref плюс Telegram за замовчуванням, перевіряє, що doctor відновлює активовані runtime-залежності Plugin, і виконує один змоканий хід агента OpenAI. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропускайте host rebuild через `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` або перемикайте channel через `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`. +- Smoke перемикання каналу оновлення: `pnpm test:docker:update-channel-switch` глобально встановлює запакований tarball OpenClaw у Docker, перемикається з package `stable` на git `dev`, перевіряє, що збережений channel і post-update Plugin працюють, потім перемикається назад на package `stable` і перевіряє статус оновлення. +- Smoke runtime context сесії: `pnpm test:docker:session-runtime-context` перевіряє збереження transcript прихованого runtime context плюс відновлення doctor для уражених дубльованих гілок prompt-rewrite. +- Smoke глобального встановлення Bun: `bash scripts/e2e/bun-global-install-smoke.sh` пакує поточне дерево, встановлює його через `bun install -g` в ізольованому home і перевіряє, що `openclaw infer image providers --json` повертає вбудовані image providers замість зависання. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропускайте host build через `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` або копіюйте `dist/` із зібраного Docker image через `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local`. +- Installer Docker smoke: `bash scripts/test-install-sh-docker.sh` спільно використовує один кеш npm у своїх контейнерах root, update і direct-npm. Smoke оновлення за замовчуванням використовує npm `latest` як стабільну базову версію перед оновленням до tarball-кандидата. Перевірки інсталятора без root зберігають ізольований кеш npm, щоб записи кешу, які належать root, не маскували поведінку локального встановлення користувача. Встановіть `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`, щоб повторно використовувати кеш root/update/direct-npm у локальних повторних запусках. +- Install Smoke CI пропускає дубльоване глобальне оновлення direct-npm через `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1`; запускайте скрипт локально без цього env, коли потрібне покриття прямого `npm install -g`. +- Smoke CLI видалення спільної робочої області агентів: `pnpm test:docker:agents-delete-shared-workspace` (скрипт: `scripts/e2e/agents-delete-shared-workspace-docker.sh`) за замовчуванням збирає image root Dockerfile, створює два агенти з однією робочою областю в ізольованому home контейнера, запускає `agents delete --json` і перевіряє коректний JSON плюс поведінку збереження робочої області. Повторно використовуйте image install-smoke через `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1`. +- Networking Gateway (два контейнери, WS auth + health): `pnpm test:docker:gateway-network` (скрипт: `scripts/e2e/gateway-network-docker.sh`) +- Smoke snapshot Browser CDP: `pnpm test:docker:browser-cdp-snapshot` (скрипт: `scripts/e2e/browser-cdp-snapshot-docker.sh`) збирає образ джерельного E2E плюс шар Chromium, запускає Chromium з raw CDP, виконує `browser doctor --deep` і перевіряє, що snapshots ролей CDP охоплюють URL-адреси посилань, clickables, підвищені курсором, посилання iframe і метадані frame. +- Мінімальна регресія reasoning OpenAI Responses web_search: `pnpm test:docker:openai-web-search-minimal` (скрипт: `scripts/e2e/openai-web-search-minimal-docker.sh`) запускає змоканий сервер OpenAI через Gateway, перевіряє, що `web_search` підвищує `reasoning.effort` з `minimal` до `low`, потім примусово викликає відхилення схеми провайдера та перевіряє, що сирі деталі з’являються в логах Gateway. +- Міст channel MCP (засіяний Gateway + stdio bridge + raw smoke notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`) +- Інструменти MCP у наборі Pi (реальний сервер stdio MCP + smoke allow/deny для вбудованого профілю Pi): `pnpm test:docker:pi-bundle-mcp-tools` (скрипт: `scripts/e2e/pi-bundle-mcp-tools-docker.sh`) +- Очищення MCP Cron/subagent (реальний Gateway + teardown дочірнього stdio MCP після ізольованих запусків cron і одноразового subagent): `pnpm test:docker:cron-mcp-cleanup` (скрипт: `scripts/e2e/cron-mcp-cleanup-docker.sh`) - Plugins (smoke встановлення, встановлення/видалення ClawHub, оновлення marketplace і ввімкнення/перевірка Claude-bundle): `pnpm test:docker:plugins` (скрипт: `scripts/e2e/plugins-docker.sh`) Встановіть `OPENCLAW_PLUGINS_E2E_CLAWHUB=0`, щоб пропустити live-блок ClawHub, або перевизначте package за замовчуванням через `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` і `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID`. - Smoke незмінного оновлення Plugin: `pnpm test:docker:plugin-update` (скрипт: `scripts/e2e/plugin-update-unchanged-docker.sh`) -- Smoke метаданих перезавантаження config: `pnpm test:docker:config-reload` (скрипт: `scripts/e2e/config-reload-source-docker.sh`) -- Runtime dependency bundled plugin: `pnpm test:docker:bundled-channel-deps` за замовчуванням збирає невеликий образ Docker runner, один раз збирає та пакує OpenClaw на хості, а потім монтує цей tarball у кожен сценарій Linux install. Повторно використовуйте образ через `OPENCLAW_SKIP_DOCKER_BUILD=1`, пропустіть перебудову хоста після свіжого локального збирання через `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` або вкажіть на наявний tarball через `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. Повний Docker-агрегатор попередньо пакує цей tarball один раз, а потім розбиває перевірки bundled channel на незалежні лайни, включно з окремими лайнами оновлення для Telegram, Discord, Slack, Feishu, memory-lancedb і ACPX. Використовуйте `OPENCLAW_BUNDLED_CHANNELS=telegram,slack`, щоб звузити matrix channel під час прямого запуску bundled-лайну, або `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx`, щоб звузити сценарій оновлення. Лайн також перевіряє, що `channels..enabled=false` і `plugins.entries..enabled=false` пригнічують відновлення doctor/runtime dependency. -- Звужуйте runtime dependency bundled plugin під час ітерацій, вимикаючи непов’язані сценарії, наприклад: +- Smoke metadata перезавантаження config: `pnpm test:docker:config-reload` (скрипт: `scripts/e2e/config-reload-source-docker.sh`) +- Runtime-залежності вбудованих Plugin: `pnpm test:docker:bundled-channel-deps` за замовчуванням збирає невеликий image Docker runner, один раз збирає та пакує OpenClaw на хості, а потім монтує цей tarball у кожен сценарій встановлення Linux. Повторно використовуйте image через `OPENCLAW_SKIP_DOCKER_BUILD=1`, пропускайте host rebuild після свіжої локальної збірки через `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` або вказуйте на наявний tarball через `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. Повний Docker aggregate попередньо пакує цей tarball один раз, а потім шардує перевірки вбудованих channel на незалежні lanes, зокрема окремі lanes оновлення для Telegram, Discord, Slack, Feishu, memory-lancedb і ACPX. Використовуйте `OPENCLAW_BUNDLED_CHANNELS=telegram,slack`, щоб звузити матрицю channel під час прямого запуску bundled lane, або `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx`, щоб звузити сценарій оновлення. Lane також перевіряє, що `channels..enabled=false` і `plugins.entries..enabled=false` пригнічують відновлення doctor/runtime-dependency. +- Звужуйте runtime-залежності вбудованих Plugin під час ітерації, вимикаючи не пов’язані сценарії, наприклад: `OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`. -Щоб вручну попередньо зібрати і повторно використовувати спільний функціональний образ: +Щоб вручну попередньо зібрати й повторно використовувати спільний функціональний image: ```bash OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-build OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels ``` -Перевизначення образу для конкретного набору, як-от `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`, усе ще мають пріоритет, якщо їх установлено. Коли `OPENCLAW_SKIP_DOCKER_BUILD=1` вказує на віддалений спільний образ, скрипти завантажують його, якщо він ще не локальний. QR- і installer-тести Docker зберігають власні Dockerfile, оскільки вони перевіряють поведінку package/install, а не спільний runtime зібраного застосунку. +Перевагу все одно мають перевизначення image для конкретного набору, такі як `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`, якщо їх установлено. Коли `OPENCLAW_SKIP_DOCKER_BUILD=1` вказує на віддалений спільний image, скрипти завантажують його, якщо його ще немає локально. Docker-тести QR та installer зберігають власні Dockerfile, оскільки перевіряють поведінку package/install, а не спільний runtime built-app. -Docker-ранери live-моделей також монтують поточний checkout лише для читання і -розгортають його в тимчасовий workdir усередині контейнера. Це дозволяє зберегти -runtime-образ компактним, водночас запускаючи Vitest точно на вашому локальному source/config. -Під час етапу розгортання пропускаються великі локальні кеші та артефакти збирання застосунків, як-от +Docker runners для live-моделей також bind-mount поточний checkout лише для читання і +розгортають його в тимчасовий workdir усередині контейнера. Це зберігає runtime +image компактним, але при цьому все одно запускає Vitest проти вашого точного локального source/config. +Крок розгортання пропускає великі локальні кеші та результати збирання застосунків, такі як `.pnpm-store`, `.worktrees`, `__openclaw_vitest__` і локальні для застосунків каталоги `.build` або виводу Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання -артефактів, специфічних для машини. -Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-probe Gateway не запускали -реальні worker каналів Telegram/Discord тощо всередині контейнера. -`test:docker:live-models` усе ще запускає `pnpm test:live`, тож також передавайте -`OPENCLAW_LIVE_GATEWAY_*`, коли потрібно звузити або виключити покриття gateway -live із цього Docker-лайну. -`test:docker:openwebui` — це smoke перевірка сумісності вищого рівня: вона запускає -контейнер gateway OpenClaw з увімкненими HTTP-endpoint, сумісними з OpenAI, -запускає зафіксований контейнер Open WebUI проти цього gateway, входить через +машинно-специфічних артефактів. +Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб Gateway live probes не запускали +реальні воркери channel Telegram/Discord тощо всередині контейнера. +`test:docker:live-models` усе ще запускає `pnpm test:live`, тому також передавайте +`OPENCLAW_LIVE_GATEWAY_*`, коли вам потрібно звузити або виключити gateway +live-покриття з цього Docker lane. +`test:docker:openwebui` — це compatibility smoke вищого рівня: він запускає +контейнер Gateway OpenClaw з увімкненими HTTP endpoint, сумісними з OpenAI, +запускає закріплений контейнер Open WebUI проти цього Gateway, виконує вхід через Open WebUI, перевіряє, що `/api/models` надає `openclaw/default`, а потім надсилає -реальний chat-запит через проксі `/api/chat/completions` Open WebUI. -Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження -образу Open WebUI, а сам Open WebUI може ще завершувати власне налаштування cold-start. -Цей лайн очікує наявність придатного live-ключа моделі, а `OPENCLAW_PROFILE_FILE` -(типово `~/.profile`) є основним способом надати його в Dockerized-запусках. +реальний запит чату через proxy Open WebUI `/api/chat/completions`. +Перший запуск може бути помітно повільнішим, оскільки Docker може знадобитися завантажити +образ Open WebUI, а самому Open WebUI — завершити власне cold-start налаштування. +Цей lane очікує придатний ключ live-моделі, а `OPENCLAW_PROFILE_FILE` +(типово `~/.profile`) — основний спосіб надати його у Dockerized runs. Успішні запуски виводять невеликий JSON payload на кшталт `{ "ok": true, "model": "openclaw/default", ... }`. `test:docker:mcp-channels` навмисно детермінований і не потребує -реального облікового запису Telegram, Discord або iMessage. Він запускає -контейнер Gateway із початковим станом, запускає другий контейнер, який піднімає `openclaw mcp serve`, а потім -перевіряє виявлення маршрутизованих розмов, читання transcript, метадані вкладень, -поведінку черги live-подій, маршрутизацію вихідного надсилання та сповіщення у стилі Claude про канал + -дозволи через реальний stdio MCP bridge. Перевірка сповіщень -безпосередньо аналізує сирі stdio MCP frame, тож smoke перевіряє саме те, що -bridge реально надсилає, а не лише те, що випадково показує конкретний SDK клієнта. -`test:docker:pi-bundle-mcp-tools` є детермінованим і не потребує -live-ключа моделі. Він збирає Docker-образ репозиторію, запускає реальний stdio MCP probe server -усередині контейнера, матеріалізує цей сервер через вбудований runtime bundle -MCP для Pi, виконує інструмент, а потім перевіряє, що `coding` і `messaging` зберігають -інструменти `bundle-mcp`, тоді як `minimal` і `tools.deny: ["bundle-mcp"]` їх відфільтровують. -`test:docker:cron-mcp-cleanup` є детермінованим і не потребує live-ключа моделі. -Він запускає Gateway із початковим станом із реальним stdio MCP probe server, виконує +реального облікового запису Telegram, Discord або iMessage. Він запускає засіяний +контейнер Gateway, запускає другий контейнер, який піднімає `openclaw mcp serve`, а потім +перевіряє маршрутизоване виявлення розмов, читання transcript, метадані вкладень, +поведінку черги live events, маршрутизацію вихідного надсилання і повідомлення channel + +про дозволи в стилі Claude через реальний міст stdio MCP. Перевірка повідомлень +безпосередньо інспектує сирі кадри stdio MCP, тож smoke перевіряє те, що міст +справді виводить, а не лише те, що випадково показує певний client SDK. +`test:docker:pi-bundle-mcp-tools` детермінований і не потребує +ключа live-моделі. Він збирає Docker image репозиторію, запускає реальний сервер probe stdio MCP +усередині контейнера, матеріалізує цей сервер через вбудований runtime Pi bundle +MCP, виконує tool, а потім перевіряє, що `coding` і `messaging` зберігають +інструменти `bundle-mcp`, тоді як `minimal` і `tools.deny: ["bundle-mcp"]` їх фільтрують. +`test:docker:cron-mcp-cleanup` детермінований і не потребує ключа live-моделі. +Він запускає засіяний Gateway із реальним сервером probe stdio MCP, виконує ізольований хід cron і одноразовий дочірній хід `/subagents spawn`, а потім перевіряє, що дочірній процес MCP завершується після кожного запуску. -Ручна smoke перевірка plain-language thread для ACP (не CI): +Ручний smoke plain-language thread ACP (не CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- Зберігайте цей скрипт для workflow регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації thread ACP, тож не видаляйте його. +- Зберігайте цей скрипт для робочих процесів регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації ACP thread, тому не видаляйте його. -Корисні env-змінні: +Корисні змінні env: - `OPENCLAW_CONFIG_DIR=...` (типово: `~/.openclaw`) монтується в `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...` (типово: `~/.openclaw/workspace`) монтується в `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...` (типово: `~/.profile`) монтується в `/home/node/.profile` і підвантажується перед запуском тестів -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`, щоб перевіряти лише env-змінні, підвантажені з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace і без монтування auth зовнішнього CLI -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (типово: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих встановлень CLI усередині Docker -- Зовнішні auth-каталоги/файли CLI в `$HOME` монтуються лише для читання під `/host-auth...`, а потім копіюються в `/home/node/...` перед запуском тестів +- `OPENCLAW_PROFILE_FILE=...` (типово: `~/.profile`) монтується в `/home/node/.profile` і підключається перед запуском тестів +- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`, щоб перевіряти лише змінні env, підключені з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace і без зовнішніх mount автентифікації CLI +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (типово: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих встановлень CLI у Docker +- Зовнішні каталоги/файли автентифікації CLI в `$HOME` монтуються лише для читання під `/host-auth...`, а потім копіюються в `/home/node/...` до початку тестів - Типові каталоги: `.minimax` - Типові файли: `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json` - - Звужені запуски провайдерів монтують лише потрібні каталоги/файли, виведені з `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` - - Перевизначайте вручну через `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` або список через кому, наприклад `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` + - Звужені запуски провайдерів монтують лише потрібні каталоги/файли, визначені з `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` + - Перевизначайте вручну через `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` або список через кому, як-от `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` - `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...`, щоб звузити запуск -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`, щоб відфільтрувати провайдерів усередині контейнера -- `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб повторно використати наявний образ `openclaw:local-live` для повторних запусків, яким не потрібне нове збирання -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб переконатися, що облікові дані беруться зі сховища profile (а не з env) -- `OPENCLAW_OPENWEBUI_MODEL=...`, щоб вибрати модель, яку gateway надає для smoke Open WebUI -- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб перевизначити nonce-check prompt, який використовує smoke Open WebUI -- `OPENWEBUI_IMAGE=...`, щоб перевизначити зафіксований тег образу Open WebUI +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`, щоб фільтрувати провайдерів усередині контейнера +- `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб повторно використовувати наявний образ `openclaw:local-live` для повторних запусків, яким не потрібне повторне збирання +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб гарантувати, що облікові дані надходять зі сховища profile (а не з env) +- `OPENCLAW_OPENWEBUI_MODEL=...`, щоб вибрати модель, яку Gateway надає для smoke Open WebUI +- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб перевизначити prompt nonce-check, який використовує smoke Open WebUI +- `OPENWEBUI_IMAGE=...`, щоб перевизначити закріплений тег образу Open WebUI -## Перевірка коректності документації +## Перевірка документації -Запускайте перевірки docs після редагування документації: `pnpm check:docs`. -Запускайте повну перевірку anchor у Mintlify, коли також потрібні перевірки заголовків усередині сторінки: `pnpm docs:check-links:anchors`. +Після редагування документації запускайте перевірки документації: `pnpm check:docs`. +Запускайте повну перевірку anchor у Mintlify, коли вам також потрібні перевірки заголовків усередині сторінок: `pnpm docs:check-links:anchors`. -## Offline-регресії (безпечні для CI) +## Офлайн-регресія (безпечно для CI) Це регресії «реального pipeline» без реальних провайдерів: -- Виклик інструментів Gateway (замоканий OpenAI, реальний gateway + цикл агента): `src/gateway/gateway.test.ts` (випадок: "runs a mock OpenAI tool call end-to-end via gateway agent loop") -- Майстер Gateway (WS `wizard.start`/`wizard.next`, записує config + застосовує auth): `src/gateway/gateway.test.ts` (випадок: "runs wizard over ws and writes auth token config") +- Виклик tool у Gateway (змоканий OpenAI, реальний цикл gateway + agent): `src/gateway/gateway.test.ts` (case: "runs a mock OpenAI tool call end-to-end via gateway agent loop") +- Wizard Gateway (WS `wizard.start`/`wizard.next`, записує config + примусово застосовану auth): `src/gateway/gateway.test.ts` (case: "runs wizard over ws and writes auth token config") -## Оцінювання надійності агентів (Skills) +## Оцінювання надійності агента (Skills) -У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агентів»: +У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агента»: -- Замоканий виклик інструментів через реальний gateway + цикл агента (`src/gateway/gateway.test.ts`). -- End-to-end потоки майстра, які перевіряють wiring сесії та вплив config (`src/gateway/gateway.test.ts`). +- Змоканий виклик tool через реальний цикл gateway + agent (`src/gateway/gateway.test.ts`). +- End-to-end потоки wizard, які перевіряють прив’язку сесії та ефекти config (`src/gateway/gateway.test.ts`). -Що все ще відсутнє для Skills (див. [Skills](/uk/tools/skills)): +Що для Skills ще відсутнє (див. [Skills](/uk/tools/skills)): -- **Прийняття рішень:** коли Skills перелічені в prompt, чи вибирає агент правильний Skill (або уникає нерелевантних)? -- **Відповідність:** чи читає агент `SKILL.md` перед використанням і чи виконує потрібні кроки/аргументи? -- **Контракти workflow:** багатокрокові сценарії, які перевіряють порядок інструментів, перенесення історії сесії та межі sandbox. +- **Вибір рішення:** коли Skills перелічені в prompt, чи вибирає агент правильний Skill (або уникає нерелевантних)? +- **Відповідність:** чи читає агент `SKILL.md` перед використанням і чи дотримується обов’язкових кроків/аргументів? +- **Контракти workflow:** багатокрокові сценарії, які перевіряють порядок tool, перенесення історії сесії та межі sandbox. -Майбутні оцінювання мають спочатку залишатися детермінованими: +Майбутні eval-и мають насамперед залишатися детермінованими: -- Раннер сценаріїв із mock-провайдерами для перевірки викликів інструментів + їхнього порядку, читання skill-файлів і wiring сесії. -- Невеликий набір сценаріїв, сфокусованих на Skills (використовувати чи уникати, гейтінг, ін’єкція prompt). -- Необов’язкові live-оцінювання (opt-in, з керуванням через env) лише після того, як буде готовий безпечний для CI набір. +- Ранер сценаріїв із mock-провайдерами для перевірки викликів tool + порядку, читання файлів Skill і прив’язки сесії. +- Невеликий набір сценаріїв, зосереджених на Skills (використовувати чи уникати, gating, ін’єкція prompt). +- Необов’язкові live eval-и (за запитом, із керуванням через env) лише після того, як буде готовий безпечний для CI набір. -## Контрактні тести (форма plugin і channel) +## Контрактні тести (форма Plugin і channel) -Контрактні тести перевіряють, що кожен зареєстрований plugin і channel відповідає своєму -контракту інтерфейсу. Вони перебирають усі виявлені plugin і запускають набір -перевірок форми та поведінки. Типовий unit-лайн `pnpm test` навмисно +Контрактні тести перевіряють, що кожен зареєстрований Plugin і channel відповідає своєму +контракту інтерфейсу. Вони проходять по всіх виявлених Plugin і запускають набір +перевірок форми та поведінки. Типовий unit lane `pnpm test` навмисно пропускає ці файли спільних seam і smoke; запускайте контрактні команди явно, -коли торкаєтеся спільних поверхонь channel або provider. +коли змінюєте спільні поверхні channel або провайдера. ### Команди - Усі контракти: `pnpm test:contracts` - Лише контракти channel: `pnpm test:contracts:channels` -- Лише контракти provider: `pnpm test:contracts:plugins` +- Лише контракти провайдерів: `pnpm test:contracts:plugins` ### Контракти channel Розташовані в `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - Базова форма plugin (id, name, capabilities) -- **setup** - Контракт майстра налаштування +- **plugin** - Базова форма Plugin (id, name, capabilities) +- **setup** - Контракт wizard налаштування - **session-binding** - Поведінка прив’язки сесії - **outbound-payload** - Структура payload повідомлення - **inbound** - Обробка вхідних повідомлень - **actions** - Обробники дій channel -- **threading** - Обробка ID thread -- **directory** - API directory/roster -- **group-policy** - Застосування group policy +- **threading** - Обробка ID потоків +- **directory** - API каталогу/реєстру +- **group-policy** - Застосування групової політики -### Контракти статусу provider +### Контракти статусу провайдера Розташовані в `src/plugins/contracts/*.contract.test.ts`. -- **status** - Перевірки статусу channel -- **registry** - Форма registry plugin +- **status** - Probes статусу channel +- **registry** - Форма реєстру Plugin -### Контракти provider +### Контракти провайдера Розташовані в `src/plugins/contracts/*.contract.test.ts`: - **auth** - Контракт потоку auth -- **auth-choice** - Вибір/selection auth +- **auth-choice** - Вибір/відбір auth - **catalog** - API каталогу моделей -- **discovery** - Виявлення plugin -- **loader** - Завантаження plugin -- **runtime** - Runtime provider -- **shape** - Форма/інтерфейс plugin -- **wizard** - Майстер налаштування +- **discovery** - Виявлення Plugin +- **loader** - Завантаження Plugin +- **runtime** - Runtime провайдера +- **shape** - Форма/інтерфейс Plugin +- **wizard** - Wizard налаштування ### Коли запускати -- Після зміни export або subpath у plugin-sdk -- Після додавання або зміни plugin channel чи provider -- Після рефакторингу реєстрації plugin або виявлення +- Після зміни export-ів або subpath `plugin-sdk` +- Після додавання чи зміни channel або provider Plugin +- Після рефакторингу реєстрації чи виявлення Plugin -Контрактні тести запускаються в CI і не потребують реальних API key. +Контрактні тести запускаються в CI і не потребують реальних API keys. ## Додавання регресій (рекомендації) -Коли ви виправляєте проблему provider/model, виявлену в live: +Коли ви виправляєте проблему провайдера/моделі, виявлену в live: -- Додайте безпечну для CI регресію, якщо це можливо (mock/stub provider або фіксація точної трансформації форми запиту) -- Якщо проблема за своєю природою стосується лише live (rate limit, політики auth), залишайте live-тест вузьким і opt-in через env-змінні -- Намагайтеся націлюватися на найменший шар, який виявляє баг: - - баг перетворення/відтворення запиту provider → тест direct models - - баг pipeline сесії/історії/інструментів gateway → smoke gateway live або безпечний для CI mock-тест gateway -- Guardrail обходу SecretRef: - - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль для кожного класу SecretRef з metadata registry (`listSecretTargetRegistryEntries()`), а потім перевіряє, що exec id сегмента обходу відхиляються. - - Якщо ви додаєте нове сімейство цілей SecretRef `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно завершується з помилкою для некласифікованих target id, щоб нові класи не можна було тихо пропустити. +- Якщо можливо, додавайте безпечну для CI регресію (mock/stub провайдера або фіксацію точного перетворення форми запиту) +- Якщо проблема за своєю природою лише live (rate limits, політики auth), залишайте live-тест вузьким і опційним через змінні env +- Віддавайте перевагу найменшому рівню, який виявляє помилку: + - помилка перетворення/повторення запиту провайдера → тест прямих моделей + - помилка pipeline сесії/історії/tool у gateway → live smoke gateway або безпечний для CI тест mock gateway +- Захисний механізм обходу SecretRef: + - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль для кожного класу SecretRef з метаданих реєстру (`listSecretTargetRegistryEntries()`), а потім перевіряє, що exec id сегментів обходу відхиляються. + - Якщо ви додаєте нове сімейство цілей SecretRef `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно завершується помилкою для некласифікованих target id, щоб нові класи не можна було тихо пропустити. ## Пов’язане diff --git a/docs/uk/reference/test.md b/docs/uk/reference/test.md index 534cd0c77..f474a707b 100644 --- a/docs/uk/reference/test.md +++ b/docs/uk/reference/test.md @@ -1,54 +1,55 @@ --- read_when: - Запуск або виправлення тестів -summary: Як запускати тести локально (`vitest`) і коли використовувати режими force/coverage +summary: Як локально запускати тести (`vitest`) і коли використовувати режими force/coverage title: Тести x-i18n: - generated_at: "2026-04-26T22:39:57Z" + generated_at: "2026-04-26T23:10:39Z" model: gpt-5.4 provider: openai - source_hash: 57a5eff6e46662960a9b06a1f6883bb22b3fd8598de6338b4e7da3fa1b90b492 + source_hash: ac57661d94c1d83195f63c342356c44130b4c3c459dd3965caad8ae3826266e3 source_path: reference/test.md workflow: 15 --- -- Повний набір для тестування (набори тестів, live, Docker): [Тестування](/uk/help/testing) +- Повний набір тестування (набори, live, Docker): [Тестування](/uk/help/testing) -- `pnpm test:force`: завершує будь-який завислий процес Gateway, який утримує типовий порт керування, а потім запускає повний набір Vitest з ізольованим портом Gateway, щоб серверні тести не конфліктували із запущеним екземпляром. Використовуйте це, коли попередній запуск Gateway залишив зайнятим порт 18789. -- `pnpm test:coverage`: запускає набір unit-тестів із покриттям V8 (через `vitest.unit.config.ts`). Це перевірка покриття unit-тестів для завантажених файлів, а не покриття всього репозиторію для всіх файлів. Порогові значення: 70% для рядків/функцій/інструкцій і 55% для гілок. Оскільки `coverage.all` має значення false, перевірка вимірює файли, завантажені набором unit-тестів із покриттям, замість того щоб вважати кожен файл вихідного коду з розділених lane без покриття. -- `pnpm test:coverage:changed`: запускає unit-покриття лише для файлів, змінених відносно `origin/main`. -- `pnpm test:changed`: розгортає змінені git-шляхи у відповідні lane Vitest, коли diff зачіпає лише маршрутизовані файли коду/тестів. Зміни конфігурації/налаштування все одно повертаються до нативного запуску кореневих проєктів, щоб зміни в обв’язці перезапускалися ширше, коли це потрібно. -- `pnpm test:changed:focused`: запуск змінених тестів для внутрішнього циклу розробки. Він запускає лише точні цілі з прямих змін у тестах, сусідніх файлів `*.test.ts`, явних відповідностей вихідного коду та локального графа імпортів. Широкі зміни, зміни конфігурації або пакетів пропускаються замість розгортання до повного резервного запуску changed-test. -- `pnpm changed:lanes`: показує архітектурні lane, які активуються diff відносно `origin/main`. -- `pnpm check:changed`: запускає розумну перевірку changed gate для diff відносно `origin/main`. Вона запускає core-роботи з core test lanes, роботу extensions з extension test lanes, зміни лише в тестах — лише з перевіркою типів тестів/тестами, розгортає зміни публічного Plugin SDK або plugin-contract до одного проходу перевірки extension і залишає підвищення версій лише в метаданих релізу на цільових перевірках версій/конфігурації/кореневих залежностей. -- `pnpm test`: спрямовує явні цілі файлів/каталогів через відповідні lane Vitest. Запуски без цілей використовують фіксовані shard-групи та розгортаються до leaf-конфігурацій для локального паралельного виконання; група extensions завжди розгортається до конфігурацій shard для кожного extension окремо, а не в один гігантський процес root-project. -- Повні запуски, запуски shards extensions і include-pattern оновлюють локальні дані часу виконання в `.artifacts/vitest-shard-timings.json`; пізніші запуски всієї конфігурації використовують ці дані, щоб збалансувати повільні й швидкі shards. CI-shards з include-pattern додають ім’я shard до ключа часу, що дозволяє зберігати видимість часу відфільтрованих shards без заміни даних часу для всієї конфігурації. Установіть `OPENCLAW_TEST_PROJECTS_TIMINGS=0`, щоб ігнорувати локальний артефакт часу. -- Вибрані тестові файли `plugin-sdk` і `commands` тепер спрямовуються через окремі легкі lane, які зберігають лише `test/setup.ts`, залишаючи ресурсоємні runtime-випадки у їхніх наявних lane. -- Вихідні файли із сусідніми тестами зіставляються з цим сусіднім тестом перед переходом до ширших glob шаблонів каталогу. Зміни helper-файлів у `test/helpers/channels` і `test/helpers/plugins` використовують локальний граф імпортів, щоб запускати тести, які їх імпортують, замість широкого запуску кожного shard, коли шлях залежності точний. -- `auto-reply` тепер також поділяється на три окремі конфігурації (`core`, `top-level`, `reply`), щоб harness для reply не домінував над легшими top-level тестами status/token/helper. -- Базова конфігурація Vitest тепер за замовчуванням використовує `pool: "threads"` і `isolate: false`, а спільний неізольований runner увімкнений у конфігураціях репозиторію. +- `pnpm test:force`: завершує будь-який завислий процес Gateway, що утримує стандартний control port, а потім запускає повний набір Vitest з ізольованим портом Gateway, щоб серверні тести не конфліктували із запущеним екземпляром. Використовуйте це, коли попередній запуск Gateway залишив зайнятим порт 18789. +- `pnpm test:coverage`: запускає набір unit-тестів із V8 coverage (через `vitest.unit.config.ts`). Це coverage-гейт unit-тестів для завантажених файлів, а не coverage всіх файлів у всьому репозиторії. Порогові значення: 70% для lines/functions/statements і 55% для branches. Оскільки `coverage.all` має значення false, гейт вимірює файли, завантажені набором unit coverage, замість того, щоб вважати всі файли вихідного коду зі split lanes непокритими. +- `pnpm test:coverage:changed`: запускає unit coverage лише для файлів, змінених відносно `origin/main`. +- `pnpm test:changed`: дешевий розумний запуск changed tests. Він запускає точні цілі на основі прямих змін у тестах, сусідніх файлів `*.test.ts`, явних мапінгів вихідного коду та локального графа імпортів. Широкі зміни/config/package пропускаються, якщо вони не мапляться на точні тести. +- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`: явний широкий запуск changed tests. Використовуйте його, коли редагування test harness/config/package має перейти до ширшої поведінки changed tests у Vitest. +- `pnpm changed:lanes`: показує архітектурні lanes, активовані diff відносно `origin/main`. +- `pnpm check:changed`: запускає розумний changed check gate для diff відносно `origin/main`. Він запускає typecheck, lint і guard-команди для зачеплених архітектурних lanes, але не запускає тести Vitest. Використовуйте `pnpm test:changed` або явний `pnpm test ` для підтвердження тестами. +- `pnpm test`: спрямовує явні цілі файлів/каталогів через scoped Vitest lanes. Запуски без цілі використовують фіксовані shard groups і розгортаються до leaf configs для локального паралельного виконання; група extension завжди розгортається до конфігурацій shard для кожного extension окремо замість одного гігантського root-project process. +- Запуски test wrapper завершуються коротким підсумком `[test] passed|failed|skipped ... in ...`. Власний рядок тривалості Vitest залишається деталізацією для кожного shard. +- Повні, extension та include-pattern shard-запуски оновлюють локальні дані часу в `.artifacts/vitest-shard-timings.json`; пізніші запуски whole-config використовують ці таймінги, щоб балансувати повільні й швидкі shards. Include-pattern CI shards додають назву shard до ключа таймінгу, що зберігає видимість таймінгів відфільтрованих shard без заміни даних таймінгів whole-config. Встановіть `OPENCLAW_TEST_PROJECTS_TIMINGS=0`, щоб ігнорувати локальний артефакт таймінгів. +- Вибрані тестові файли `plugin-sdk` і `commands` тепер спрямовуються через окремі легкі lanes, які залишають лише `test/setup.ts`, а випадки з важким runtime лишаються у своїх наявних lanes. +- Вихідні файли із сусідніми тестами мапляться на цей сусідній тест перед тим, як перейти до ширших glob шаблонів каталогу. Зміни helper у `test/helpers/channels` і `test/helpers/plugins` використовують локальний граф імпортів, щоб запускати тести-імпортери замість широкого запуску кожного shard, коли шлях залежності є точним. +- `auto-reply` тепер також розбито на три окремі конфігурації (`core`, `top-level`, `reply`), щоб reply harness не домінував над легшими top-level тестами status/token/helper. +- Базова конфігурація Vitest тепер типово використовує `pool: "threads"` і `isolate: false`, а спільний non-isolated runner увімкнено в усіх конфігураціях репозиторію. - `pnpm test:channels` запускає `vitest.channels.config.ts`. -- `pnpm test:extensions` і `pnpm test extensions` запускають усі shards extension/plugin. Важкі channel plugins, browser plugin та OpenAI запускаються як окремі shards; інші групи plugins залишаються пакетними. Використовуйте `pnpm test extensions/` для одного lane конкретного bundled plugin. -- `pnpm test:perf:imports`: вмикає звітування Vitest про тривалість імпорту та деталізацію імпорту, водночас і далі використовуючи маршрутизацію lane для явних цілей файлів/каталогів. -- `pnpm test:perf:imports:changed`: той самий профайлінг імпортів, але лише для файлів, змінених відносно `origin/main`. -- `pnpm test:perf:changed:bench -- --ref ` виконує бенчмарк маршрутизованого шляху в режимі changed проти нативного запуску root-project для того самого зафіксованого git diff. -- `pnpm test:perf:changed:bench -- --worktree` виконує бенчмарк поточного набору змін у worktree без попереднього коміту. -- `pnpm test:perf:profile:main`: записує CPU-профіль для головного потоку Vitest (`.artifacts/vitest-main-profile`). -- `pnpm test:perf:profile:runner`: записує профілі CPU + heap для unit runner (`.artifacts/vitest-runner-profile`). -- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`: послідовно запускає кожну leaf-конфігурацію Vitest повного набору тестів і записує згруповані дані тривалості разом з JSON/log-артефактами для кожної конфігурації. Агент продуктивності тестів використовує це як базову лінію перед спробами виправити повільні тести. -- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`: порівнює згруповані звіти після змін, спрямованих на продуктивність. -- Інтеграція Gateway: вмикається через `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` або `pnpm test:gateway`. -- `pnpm test:e2e`: запускає наскрізні smoke-тести Gateway (парування WS/HTTP/node з кількома екземплярами). За замовчуванням використовує `threads` + `isolate: false` з адаптивною кількістю workers у `vitest.e2e.config.ts`; налаштовується через `OPENCLAW_E2E_WORKERS=`, а для докладних логів установіть `OPENCLAW_E2E_VERBOSE=1`. -- `pnpm test:live`: запускає live-тести провайдерів (minimax/zai). Потребує API-ключів і `LIVE=1` (або специфічного для провайдера `*_LIVE_TEST=1`), щоб зняти пропуск. -- `pnpm test:docker:all`: збирає спільний образ live-тестів, один раз пакує OpenClaw як npm tarball, збирає/повторно використовує базовий образ runner з Node/Git і функціональний образ, який встановлює цей tarball у `/app`, а потім запускає Docker smoke lanes з `OPENCLAW_SKIP_DOCKER_BUILD=1` через зважений планувальник. Базовий образ (`OPENCLAW_DOCKER_E2E_BARE_IMAGE`) використовується для lane встановлення/оновлення/залежностей plugin; ці lane монтують попередньо зібраний tarball замість використання скопійованих вихідних кодів репозиторію. Функціональний образ (`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`) використовується для звичайних lane функціональності зібраного застосунку. `scripts/package-openclaw-for-docker.mjs` — єдиний локальний/CI пакувальник пакета. Визначення Docker lane містяться в `scripts/lib/docker-e2e-scenarios.mjs`; логіка планувальника — у `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` виконує вибраний план. `node scripts/test-docker-all.mjs --plan-json` виводить CI-план, яким керує планувальник, для вибраних lane, типів образів, потреб пакета/live-image та перевірок облікових даних без збирання або запуску Docker. `OPENCLAW_DOCKER_ALL_PARALLELISM=` керує кількістю слотів процесів і за замовчуванням дорівнює 10; `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=` керує tail pool, чутливим до провайдерів, і за замовчуванням теж дорівнює 10. Обмеження важких lane за замовчуванням: `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; обмеження провайдерів за замовчуванням — один важкий lane на провайдера через `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`, `OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` і `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4`. Використовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` для більших хостів. Запуски lane за замовчуванням розподіляються з інтервалом 2 секунди, щоб уникнути штормів створення на локальному Docker daemon; змініть через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=`. Runner за замовчуванням виконує попередню перевірку Docker, очищає застарілі контейнери OpenClaw E2E, виводить статус активних lane кожні 30 секунд, спільно використовує кеші CLI-інструментів провайдерів між сумісними lane, за замовчуванням один раз повторює тимчасові збої live-провайдерів (`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=`) і зберігає час lane в `.artifacts/docker-tests/lane-timings.json` для впорядкування за принципом “найдовші спочатку” в наступних запусках. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести маніфест lane без запуску Docker, `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=` для налаштування частоти статусів, або `OPENCLAW_DOCKER_ALL_TIMINGS=0`, щоб вимкнути повторне використання даних часу. Використовуйте `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` лише для детермінованих/локальних lane або `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` лише для lane live-провайдерів; пакетні псевдоніми — `pnpm test:docker:local:all` і `pnpm test:docker:live:all`. Режим лише live об’єднує основні та tail live-lanes в один pool з порядком “найдовші спочатку”, щоб кошики провайдерів могли разом пакувати роботу Claude, Codex і Gemini. Runner припиняє планувати нові pooled lanes після першої помилки, якщо не встановлено `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`, а кожен lane має резервний тайм-аут 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; окремі live/tail lanes використовують жорсткіші обмеження часу на lane. Команди налаштування Docker для бекенда CLI мають власний тайм-аут через `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` (за замовчуванням 180). Логи для кожного lane та `summary.json` з часом етапів записуються в `.artifacts/docker-tests//`. -- `pnpm test:docker:browser-cdp-snapshot`: збирає контейнер source E2E на базі Chromium, запускає сирий CDP і ізольований Gateway, виконує `browser doctor --deep` і перевіряє, що знімки ролей CDP містять URL посилань, clickables, підвищені курсором, iframe refs і метадані frame. -- Live Docker probes для бекенда CLI можна запускати як сфокусовані lane, наприклад `pnpm test:docker:live-cli-backend:codex`, `pnpm test:docker:live-cli-backend:codex:resume` або `pnpm test:docker:live-cli-backend:codex:mcp`. Для Claude і Gemini є відповідні псевдоніми `:resume` і `:mcp`. -- `pnpm test:docker:openwebui`: запускає Dockerized OpenClaw + Open WebUI, виконує вхід через Open WebUI, перевіряє `/api/models`, а потім запускає реальний проксійований чат через `/api/chat/completions`. Потребує придатного ключа live-моделі (наприклад, OpenAI у `~/.profile`), завантажує зовнішній образ Open WebUI і не вважається стабільним для CI так, як звичайні набори unit/e2e. -- `pnpm test:docker:mcp-channels`: запускає контейнер Gateway із підготовленими даними та другий клієнтський контейнер, який запускає `openclaw mcp serve`, а потім перевіряє виявлення маршрутизованих розмов, читання транскриптів, метадані вкладень, поведінку черги live-подій, маршрутизацію вихідного надсилання, а також сповіщення про channel і permissions у стилі Claude через реальний stdio bridge. Перевірка сповіщень Claude читає сирі stdio MCP-кадри безпосередньо, щоб smoke-тест відображав те, що bridge реально надсилає. +- `pnpm test:extensions` і `pnpm test extensions` запускають усі extension/plugin shards. Важкі channel plugins, browser plugin і OpenAI запускаються як окремі shards; інші групи plugin залишаються згрупованими. Використовуйте `pnpm test extensions/` для одного bundled plugin lane. +- `pnpm test:perf:imports`: вмикає звітність Vitest про import-duration та import-breakdown, зберігаючи scoped lane routing для явних цілей файлів/каталогів. +- `pnpm test:perf:imports:changed`: те саме профілювання імпортів, але лише для файлів, змінених відносно `origin/main`. +- `pnpm test:perf:changed:bench -- --ref ` виконує benchmark routed changed-mode path порівняно з нативним root-project run для того самого закоміченого git diff. +- `pnpm test:perf:changed:bench -- --worktree` виконує benchmark поточного набору змін у worktree без попереднього commit. +- `pnpm test:perf:profile:main`: записує CPU profile для головного потоку Vitest (`.artifacts/vitest-main-profile`). +- `pnpm test:perf:profile:runner`: записує CPU + heap profiles для unit runner (`.artifacts/vitest-runner-profile`). +- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`: послідовно запускає кожну leaf config Vitest повного набору й записує згруповані дані тривалості разом з JSON/log артефактами для кожної config. Агент продуктивності тестів використовує це як baseline перед спробами виправити повільні тести. +- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`: порівнює згруповані звіти після зміни, спрямованої на продуктивність. +- Інтеграція Gateway: opt-in через `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` або `pnpm test:gateway`. +- `pnpm test:e2e`: запускає Gateway end-to-end smoke-тести (multi-instance WS/HTTP/node pairing). Типово використовує `threads` + `isolate: false` з адаптивною кількістю workers у `vitest.e2e.config.ts`; налаштовуйте через `OPENCLAW_E2E_WORKERS=` і встановіть `OPENCLAW_E2E_VERBOSE=1` для докладних логів. +- `pnpm test:live`: запускає live-тести провайдерів (minimax/zai). Потрібні API keys і `LIVE=1` (або специфічний для провайдера `*_LIVE_TEST=1`) для зняття пропуску. +- `pnpm test:docker:all`: збирає спільний образ live-tests, один раз пакує OpenClaw як npm tarball, збирає/повторно використовує bare Node/Git runner image і functional image, який встановлює цей tarball у `/app`, а потім запускає Docker smoke lanes з `OPENCLAW_SKIP_DOCKER_BUILD=1` через weighted scheduler. Bare image (`OPENCLAW_DOCKER_E2E_BARE_IMAGE`) використовується для lanes installer/update/plugin-dependency; ці lanes монтують попередньо зібраний tarball замість використання скопійованих вихідних кодів репозиторію. Functional image (`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`) використовується для звичайних lanes функціональності зібраного застосунку. `scripts/package-openclaw-for-docker.mjs` — єдиний локальний/CI пакувальник пакетів, який перевіряє tarball і `dist/postinstall-inventory.json` перед тим, як Docker почне їх використовувати. Визначення Docker lanes містяться у `scripts/lib/docker-e2e-scenarios.mjs`; логіка planner — у `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` виконує вибраний plan. `node scripts/test-docker-all.mjs --plan-json` виводить план CI, яким володіє scheduler, для вибраних lanes, типів image, потреб package/live-image та перевірок credentials без збирання або запуску Docker. `OPENCLAW_DOCKER_ALL_PARALLELISM=` керує кількістю process slots і типово дорівнює 10; `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=` керує provider-sensitive tail pool і типово також дорівнює 10. Обмеження для heavy lanes типово: `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; обмеження для провайдерів типово допускають один heavy lane на провайдера через `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`, `OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` і `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4`. Використовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` для потужніших хостів. Запуски lanes типово розносяться на 2 секунди, щоб уникнути локальних штормів create у Docker daemon; перевизначайте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=`. Runner типово виконує попередню перевірку Docker, очищає застарілі контейнери OpenClaw E2E, виводить статус активних lanes кожні 30 секунд, ділиться кешами provider CLI tool між сумісними lanes, типово один раз повторює transient live-provider failures (`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=`) і зберігає таймінги lanes у `.artifacts/docker-tests/lane-timings.json` для впорядкування від найдовших до найкоротших у наступних запусках. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести manifest lanes без запуску Docker, `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=` для налаштування виводу статусу або `OPENCLAW_DOCKER_ALL_TIMINGS=0` для вимкнення повторного використання таймінгів. Використовуйте `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` лише для детермінованих/локальних lanes або `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` лише для lanes live-provider; package aliases — `pnpm test:docker:local:all` і `pnpm test:docker:live:all`. Режим лише live об’єднує main і tail live lanes в один пул longest-first, щоб provider buckets могли разом пакувати роботу Claude, Codex і Gemini. Runner припиняє планувати нові pooled lanes після першої помилки, якщо не встановлено `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`, а кожен lane має резервний timeout 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail lanes використовують жорсткіші обмеження для окремих lanes. Команди налаштування Docker для CLI backend мають окремий timeout через `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` (типово 180). Логи для кожного lane, `summary.json`, `failures.json` і таймінги фаз записуються у `.artifacts/docker-tests//`; використовуйте `pnpm test:docker:timings `, щоб переглянути повільні lanes, і `pnpm test:docker:rerun `, щоб вивести дешеві команди цільового повторного запуску. +- `pnpm test:docker:browser-cdp-snapshot`: збирає source E2E container на базі Chromium, запускає raw CDP плюс ізольований Gateway, виконує `browser doctor --deep` і перевіряє, що CDP role snapshots містять URL-адреси посилань, clickables, підняті курсором, iframe refs і метадані frame. +- Live Docker probes для CLI backend можна запускати як цільові lanes, наприклад `pnpm test:docker:live-cli-backend:codex`, `pnpm test:docker:live-cli-backend:codex:resume` або `pnpm test:docker:live-cli-backend:codex:mcp`. Для Claude і Gemini є відповідні aliases `:resume` і `:mcp`. +- `pnpm test:docker:openwebui`: запускає Dockerized OpenClaw + Open WebUI, входить через Open WebUI, перевіряє `/api/models`, а потім виконує реальний проксійований чат через `/api/chat/completions`. Потребує придатний ключ live model (наприклад, OpenAI у `~/.profile`), завантажує зовнішній образ Open WebUI і не вважається настільки стабільним для CI, як звичайні набори unit/e2e. +- `pnpm test:docker:mcp-channels`: запускає seeded Gateway container і другий client container, який запускає `openclaw mcp serve`, а потім перевіряє routed conversation discovery, читання transcript, метадані attachment, поведінку live event queue, outbound send routing і сповіщення каналу + дозволів у стилі Claude через реальний stdio bridge. Перевірка сповіщення Claude читає сирі stdio MCP frames безпосередньо, щоб smoke відображав те, що міст насправді надсилає. -## Локальна перевірка PR +## Локальний PR gate -Для локальних перевірок перед злиттям/проходженням gate PR виконайте: +Для локальних перевірок перед land/gate PR виконуйте: - `pnpm check:changed` - `pnpm check` @@ -57,7 +58,7 @@ x-i18n: - `pnpm test` - `pnpm check:docs` -Якщо `pnpm test` нестабільно працює на навантаженому хості, перезапустіть його один раз, перш ніж вважати це регресією, а потім ізолюйте за допомогою `pnpm test `. Для хостів з обмеженою пам’яттю використовуйте: +Якщо `pnpm test` флейкить на навантаженому хості, повторіть запуск один раз, перш ніж вважати це регресією, а потім ізолюйте через `pnpm test `. Для хостів з обмеженою пам’яттю використовуйте: - `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test` - `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed` @@ -69,13 +70,13 @@ x-i18n: Використання: - `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10` -- Необов’язкові змінні середовища: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY` -- Типовий запит: “Відповідай одним словом: ok. Без розділових знаків або додаткового тексту.” +- Необов’язкові env: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY` +- Типовий prompt: “Відповідай одним словом: ok. Без розділових знаків або зайвого тексту.” Останній запуск (2025-12-31, 20 запусків): -- minimax: медіана 1279 мс (мін. 1114, макс. 2431) -- opus: медіана 2454 мс (мін. 1224, макс. 3170) +- minimax median 1279ms (min 1114, max 2431) +- opus median 2454ms (min 1224, max 3170) ## Бенчмарк запуску CLI @@ -104,25 +105,25 @@ x-i18n: - `real`: `health`, `status`, `status --json`, `sessions`, `sessions --json`, `agents list --json`, `gateway status`, `gateway status --json`, `gateway health --json`, `config get gateway.port` - `all`: обидва набори preset -Вивід містить `sampleCount`, avg, p50, p95, min/max, розподіл кодів виходу/сигналів і зведення максимального RSS для кожної команди. Необов’язкові `--cpu-prof-dir` / `--heap-prof-dir` записують профілі V8 для кожного запуску, тож вимірювання часу та захоплення профілю використовують одну й ту саму harness. +Вивід містить `sampleCount`, avg, p50, p95, min/max, розподіл exit-code/signal і підсумки max RSS для кожної команди. Необов’язкові `--cpu-prof-dir` / `--heap-prof-dir` записують профілі V8 для кожного запуску, тож вимірювання часу й захоплення профілів використовують той самий harness. -Умовні позначення для збереженого виводу: +Угоди для збереженого виводу: - `pnpm test:startup:bench:smoke` записує цільовий smoke-артефакт у `.artifacts/cli-startup-bench-smoke.json` -- `pnpm test:startup:bench:save` записує артефакт повного набору тестів у `.artifacts/cli-startup-bench-all.json` з використанням `runs=5` і `warmup=1` -- `pnpm test:startup:bench:update` оновлює baseline fixture, що зберігається в репозиторії, у `test/fixtures/cli-startup-bench.json` з використанням `runs=5` і `warmup=1` +- `pnpm test:startup:bench:save` записує артефакт повного набору в `.artifacts/cli-startup-bench-all.json` з `runs=5` і `warmup=1` +- `pnpm test:startup:bench:update` оновлює baseline fixture, закомічений у репозиторій, за шляхом `test/fixtures/cli-startup-bench.json` з `runs=5` і `warmup=1` -Fixture, що зберігається в репозиторії: +Fixture, закомічений у репозиторій: - `test/fixtures/cli-startup-bench.json` -- Оновити за допомогою `pnpm test:startup:bench:update` -- Порівняти поточні результати з fixture за допомогою `pnpm test:startup:bench:check` +- Оновіть через `pnpm test:startup:bench:update` +- Порівняйте поточні результати з fixture через `pnpm test:startup:bench:check` ## Onboarding E2E (Docker) -Docker не є обов’язковим; це потрібно лише для контейнеризованих smoke-тестів onboarding. +Docker необов’язковий; це потрібно лише для containerized smoke-тестів onboarding. -Повний потік холодного старту в чистому Linux-контейнері: +Повний cold-start flow у чистому Linux container: ```bash scripts/e2e/onboard-docker.sh @@ -130,9 +131,9 @@ scripts/e2e/onboard-docker.sh Цей скрипт керує інтерактивним майстром через pseudo-tty, перевіряє файли config/workspace/session, потім запускає Gateway і виконує `openclaw health`. -## QR import smoke (Docker) +## Smoke-тест імпорту QR (Docker) -Гарантує, що підтримуваний helper runtime для QR завантажується в підтримуваних Docker runtime Node (Node 24 за замовчуванням, Node 22 сумісний): +Гарантує, що підтримуваний runtime helper QR завантажується в підтримуваних Docker runtime Node (типово Node 24, сумісність із Node 22): ```bash pnpm test:docker:qr @@ -141,4 +142,4 @@ pnpm test:docker:qr ## Пов’язане - [Тестування](/uk/help/testing) -- [Тестування live](/uk/help/testing-live) +- [Live-тестування](/uk/help/testing-live)