--- name: amxb-migration description: >- Миграция AMXX-проекта (AMX Mod X, Counter-Strike) на сборщик amxb (amxx-builder): перевод репозитория на amxbuild.yml, подключение зависимостей (deps), настройка .gitignore / CI / MCP, замена старых скриптов сборки. Использовать, когда пользователь просит «настроить сборку через amxb», «перевести/перенести проект на amxb / amxbuild.yml», «заменить старые bat/ps1/sh-скрипты или CI на amxb», «добавить/дополнить amxbuild.yml», либо мигрирует проект с ручной компиляции (compile.exe/amxxpc) на автоматическую. Скилл работает в проекте, где amxb ещё не установлен (установка — шаг 0). Триггеры: amxb, amxx-builder, amxbuild.yml, AMX Mod X, AMXX, миграция сборки, build system migration, amxx-builder migration. Use when migrating an AMX Mod X plugin/server project to the amxb builder. --- # Миграция AMXX-проекта на amxb Перевод репозитория AMXX-плагинов на сборщик **amxb** (`amxx-builder`). Конфигурация — один файл `amxbuild.yml` в корне проекта. Результат миграции: проект собирается командой `amxb build` (или в CI через `AmxxModularEcosystem/amxx-builder@v1`) в готовый `.zip`. ## Когда применять / не применять **Применять**, когда пользователь просит: - настроить сборку через amxb / перевести проект на `amxbuild.yml`; - заменить старые скрипты сборки (`.bat`/`.ps1`/`.sh`, `config.bat`, `.build-config`) или старый CI на amxb; - разобрать существующий `amxbuild.yml`, дополнить его, найти ошибку в deps. **Не применять**, когда: - задача — просто собрать/задеплоить уже настроенный amxb-проект (это обычные команды `amxb build` / `amxb deploy`, скилл не нужен); - пользователь хочет писать плагины (это не миграция). ## Стартовое состояние Проект может находиться в любом из состояний, все они корректны: - уже есть старая система сборки (`bat`/`ps1`/`sh`-скрипты, `.build-config`, CI со сборкой); - есть только CI со списком зависимостей; - вообще нет никакой системы сборки — это нормально, просто входных данных меньше. **Правило (границы доступа):** вся информация берётся **только из папки целевого проекта**. Запрещено читать, открывать или иначе исследовать любые файлы/папки **вне её** — соседние проекты на диске, sibling-репозитории, аналоги пользователя, чужие репозитории. Запрет действует **независимо от цели**: и как источник данных, и «просто для понимания экосистемы», и для проверки гипотез. Такое чтение нарушает границы задачи и приватность (соседний проект может быть приватным/чужим/нерелевантным). Если данных не хватает — задаём вопросы пользователю, а не докапываемся самостоятельно. **Где работать:** все шаги выполняются в корне целевого проекта (там, где должен лежать `amxbuild.yml`). Пути в манифесте относительны именно него. ## Что amxb делает «из коробки» (минимальный манифест) Прежде чем задавать вопросы о структуре пакета — понять, что amxb даёт сам. Манифест из одного `name:` уже собирает проект в архив по умолчанию: ```text {name}.zip ← output.archive_name (default: "{name}.zip") ├── README.md ← output.readme: true (если есть в корне проекта) └── {name}/ ← обёртка: часть output.amxmodx_path / assets_path ├── addons/amxmodx/ ← output.amxmodx_path (default: "{name}/addons/amxmodx") │ ├── configs/... ← локальная amxmodx/configs (мержится с репо) │ ├── data/... lang/... │ ├── plugins/*.amxx ← скомпилированные .sma │ └── scripting/... ← исходники (копируются и компилируются) └── sound/, models/, ... ← содержимое assets/ → в {name}/ (source: local) ``` Ключевое: **дефолтная раскладка архива уже совпадает с типовым пакетом плагина/сервера** (`{name}/addons/amxmodx/...`) — обычно структуру менять не нужно и вопросы про неё не задаются. README попадает в архив только при `output.readme: true` (это дефолт). Архив ложится в `output.dir` рядом с манифестом (default: `./`). Точные пути печатает план сборки — см. Шаг 4 (проверка через `amxb build --dry-run`), а не догадки о схеме. ## Шаг 0. Убедиться, что amxb доступен Скилл рассчитан на проект, где amxb может быть ещё **не установлен**. 1. Проверить наличие: ```bash amxb --version ``` 2. Если команды нет — установить (нужен Node.js 18+): Глобально через npm: ```bash npm i -g amxx-builder ``` Или через официальный установщик (не требует npm): ```bash # Windows (PowerShell): irm https://raw.githubusercontent.com/AmxxModularEcosystem/amxx-builder/master/install.ps1 | iex ``` ```bash # Linux / macOS: curl -fsSL https://raw.githubusercontent.com/AmxxModularEcosystem/amxx-builder/master/install.sh | bash ``` Для приватных репозиториев во время установки передать `GITHUB_TOKEN`: ```bash GITHUB_TOKEN=ghp_xxx curl -fsSL https://raw.githubusercontent.com/AmxxModularEcosystem/amxx-builder/master/install.sh | bash ``` Конкретную версию можно зафиксировать переменной `AMXB_VERSION` (тег `v1.2.3`). 3. Если глобальная установка нежелательна/невозможна — можно запускать любую команду amxb через npx без установки: ```bash npx --yes amxx-builder@latest build --dry-run ``` (далее в тексте команды записаны как `amxb ...` — при работе через npx подставлять `npx --yes amxx-builder@latest ...`.) 4. Проверить окружение (Node, доступность GitHub API, кэш, при наличии — валидность манифеста): ```bash amxb doctor ``` > Для самой миграции amxb не нужно добавлять в зависимости проекта — > это глобальный CLI (или GitHub Action в CI). ## Шаг 1. Собрать входные данные (только внутри проекта) 1. **Список плагинов**: все `.sma` в `amxmodx/scripting/` (рекурсивно). amxb компилирует `**/*.sma` и сохраняет относительный путь (вложенный `.sma` → `plugins/подпапка/имя.amxx`). 2. **Используемые include** — по всему `scripting/` (и `.sma`, и `.inc`): ```bash grep -rhoE '^\s*#include\s*[<"][^>"]+[>"]' amxmodx/scripting \ --include='*.sma' --include='*.inc' \ | sed -E 's/^\s*#include\s*([<"])(.*)/\2/' | sed -E 's/[>"]$//' \ | sort | uniq -c | sort -rn ``` 3. **Целевая структура пакета**: если есть старый `*.zip` или каталог `.build/` — распаковать и посмотреть, что входило: `configs/`, `plugins/`, `scripting/`, ini-файлы, `data/lang/`. Это эталон для сверки. 4. **Подсказки о зависимостях** — что может лежать в проекте. Приоритет — по ценности источника, от самого конкретного к самому общему: 1. **CI/workflow** (`.github/workflows/`, `.gitlab-ci.yml` и т.п.) — самый ценный источник: в нём проект когда-то собирался и все версии зафиксированы. Искать конкретику, а не «список зависимостей вообще»: - упоминания репозиториев: `uses: AmxxModularEcosystem/...`, `wget`/`curl` `github.com//`, переменные `REPO=...`, `OWNER/REPO`; - **версии**: `*_TAG=...`, `ref: v...`, `@v...`, теги в URL релизов; - **include-пути**: `INCLUDE_PATH=...`, флаги `-i...`, пути вида `addons/amxmodx/scripting/include`, `amxmodx/scripting/include`; - версию компилятора/AMXX (обычно в той же строке установки include). 2. `deps.txt` — список GitHub-репо зависимостей (если есть). 3. `.build-config` / `config.bat` / другие скрипты сборки — дают доп. параметры для манифеста (имя пакета, ini-постфикс, defines). В них же могут встречаться пути вида `C:\AmxModX\1.9.0`, имена `amxx190`/`amxxpc` — это указание на линию AMXX, под которую собран проект; значение оно имеет только если линия <= 1.8.3 (см. Шаг 4 — версию компилятора пиним только для этой старой линии). Если CI в проекте есть — он даёт и источники, и версии, и include-пути сразу, и вопросов пользователю может не понадобиться вовсе. ## Шаг 2. Классифицировать include | Группа | Примеры | Действие | |---|---|---| | Стандартная библиотека AMXX | `amxmodx`, `fakemeta`, `hamsandwich`, `nvault`, `regex`, `json` | ничего не нужно | | Локальные (внутри проекта) | свои `.inc` в `scripting/`, `scripting/include/` | ничего не нужно — amxb сам подключает `scripting/` и `scripting/include/`, а дерево `amxmodx/` мержится в пакет | | Внешние | чужие API-библиотеки/модули | запись в `deps:` манифеста | > Публичные API самого проекта (свои `.inc`, объявляющие natives, которые > реализуют плагины проекта) — НЕ deps. deps — только то, что приходит извне. ## Шаг 3. Поиск источников внешних include Имея только имя инклуда (``, ``, ``...), агент никак не может надёжно определить его источник. Поэтому **источник include ищется только внутри проекта или уточняется у пользователя** — поиск по GitHub/вебу по имени инклуда запрещён (это чтение чужих репозиториев, см. правило выше): 1. **CI/workflow проекта** — самый конкретный источник (см. Шаг 1): репо в `uses:`/URL, версии в `*_TAG=`, include-пути. Если CI есть — начать с него. 2. `deps.txt` / `.build-config` — если упоминают репозиторий, дающий этот include — берём его. 3. Чтение шапки `.inc` или места использования внутри проекта: часто инклуд сам включает другие (`#include ` внутри чужого API → ReAPI нужен отдельным dep). 4. **Если после разбора CI и скриптов сборки источник не находится — НЕ копаем сами.** Задаём вопрос пользователю: откуда инклуд, в каком репозитории он лежит. Вопрос задаём по каждому неопознанному include, а не по одному самому очевидному. **Репозиторий «не найден» — это ещё не «репозитория не существует».** GitHub отвечает 404 одинаково и для несуществующих, и для приватных (или недоступных без токена) репозиториев. Поэтому, если подтверждённый (названный пользователем или найденный в CI) репозиторий не резолвится (`amxb deps-tree` показывает not found), действуем по порядку: 1. **Сначала пробуем токены из `.env`** рядом с манифестом (если они там есть: `GITHUB_TOKEN`, `GITHUB_TOKEN_*`). Прописываем их в манифест (`github.token_env` / `github.tokens`, см. Шаг 5) и повторяем `amxb deps-tree` — репозиторий мог быть приватным, и токен уже лежит рядом. Не спрашиваем пользователя, пока не проверили имеющиеся токены. 2. **Если токенов нет или они не помогли** — первая гипотеза: репозиторий приватный. Задаём пользователю вопрос с двумя вариантами: - дать токен для этого владельца (`github.tokens` + `.env`), либо - уточнить имя репозитория — если в CI/запросе была опечатка (`Owner/Repoo` → `Owner/Repo`). Не делаем вывод «репозитория не существует» без подтверждения пользователя. **Проверка версии у подтверждённого источника — штатными средствами amxb, не вручную.** Список релизов/тегов репозитория-источника (после того как источник назван пользователем или найден в CI) смотрим командой: ```bash amxb releases Owner/Repo # релизы; --tags для тегов, --limit N ``` Ту же информацию (и резолв include/деревьев) дают MCP-инструменты `amxx-dep-resolver` (`list_releases`, `get_dep_tree`, `resolve_include`) — **это инструменты для АГЕНТА: они дают миграции больше данных о проекте без ручных запросов**. Но они доступны только если реально видны в текущей сессии — MCP подхватывается **после перезапуска opencode, который нужен самому агенту** (см. Шаг 9), а не пользователю. Если инструментов в сессии нет — не ждём и не молчим, а работаем CLI: `amxb releases` / `amxb deps-tree` дают ту же информацию без перезапуска. Ручные запросы к GitHub API/вебу для выбора версии не нужны и не делаются — см. «Формат deps» ниже. Чужие/соседние репозитории и их содержимое при этом не открываем. ### Формат deps ```yaml deps: # git-репо: owner/repo@ref, опционально :путь_до_include_внутри_репо - Owner/Repo@tag - Owner/Repo@tag:нестандартный/путь/до/include # модуль из release-архива; ref: latest резолвится в последний релиз, # но в манифест пишем конкретный тег (см. «Выбор версии» ниже) - repo: Owner/Repo ref: 5.29.0.358 source: release include_path: путь/внутри/архива/до/include # .inc закрытого плагина с fungun.net (магазин без архивов и git-репо): # id — индекс плагина в адресе страницы; можно указать полную ссылку url: - source: fungun id: 106 ``` Источников у deps три: `git` (по умолчанию), `release` (GitHub release-архив) и `fungun` (публичный `.inc` со страницы закрытого плагина на fungun.net). **Что даёт `deps:` и чего не даёт.** `deps:` — это **только заголовочные файлы (`.inc`) для компиляции**. amxb **не компилирует и не упаковывает** плагины из репозиториев-зависимостей. Для большинства плагинов это корректно (модули ставятся на сервер отдельно). Но если мигрируемый проект — это сборка, где плагины зависимостей должны **попасть в итоговый пакет**, нужны `repos:` (репозитории как часть сборки) и/или `assets:` — а не `deps:`. Определить, что нужно, можно по старой системе сборки: если она клонировала репозитории и компилировала их `.sma` в один пакет — это `repos:`; если только клала их include в папку инклудов — это `deps:`. **Выбор версии** — под «последней версией» понимается не строка `latest` в манифесте, а **получение конкретной версии и её фиксация**. Алгоритм: 1. **Узнать последнюю версию** подтверждённого источника: для `source: release` `ref: latest` резолвится в последний GitHub-релиз, для git-репо — в последний тег. Смотрим штатно: `amxb releases Owner/Repo` (релизы), `amxb releases Owner/Repo --tags` (теги), либо MCP `list_releases`. 2. **Проверить последнюю версию реальной сборкой** (`amxb deps-tree`, затем `amxb build`), что include резолвится и natives находятся (`--dry-run` план не компилирует и этого не покажет). 3. **Если последняя версия найдена и подходит — берём её**, в манифест пишем **конкретный тег** (а не строку `latest`) — сборка становится воспроизводимой. `latest` в манифесте оставляем только если политика источника осознанно «всегда последняя» (подтверждена старым CI). 4. **Если последней версии нет или она не подходит** (свежая линия сменила неймспейс include `` → `` или префиксы natives `MOD_*` → `NS_MOD_*`) — берём версию, **найденную по проекту** (старый CI: `*_TAG=...`, `ref: v...`; `deps.txt`; README) — с ней проект уже собирался. Её тоже проверяем сборкой. 5. **Если нет ни того ни другого** — НЕ молчим и НЕ правим код втихую. Формулируем пользователю развилку: **(A)** зафиксировать совместимый старый тег (например rc-линию) — если на серверах стоит именно эта линия, либо **(B)** обновлять код проекта под новое API — отдельная задача за рамками миграции. Без ответа пользователя версию не закрепляем. 6. Если пользователь не может назвать точные версии (отвечает «latest» / «не знаю») — закрепляем выбранные, но **явно помечаем их как предварительные** и выносим в итоговый отчёт как открытый вопрос, чтобы риск несовместимости был зафиксирован, а не замолчан. ## Шаг 4. Манифест и структура проекта 1. **Сначала написать минимальный манифест и посмотреть план**, а не угадывать структуру/задавать вопросы о ней. Дефолтная раскладка уже совпадает с типовым пакетом (см. «Что amxb делает из коробки» выше), а `amxb build --dry-run` печатает фактические пути: ```bash amxb build --dry-run # ... # Output: # archive → /abs/path/./{name}.zip # amxmodx path in archive: {name}/addons/amxmodx/ # assets path: {name}/ # generate_ini: false | on_conflict: last_wins ``` Вопросы пользователю про структуру задаём **только если** фактическая раскладка отличается от дефолтной и это принципиально (серверная сборка, нестандартное расположение `amxmodx/`). 2. Если структура проекта отличается от дефолтной для amxb (`amxmodx/scripting/`, `amxmodx/configs/`, `assets/`) — можно предложить привести её к стандарту. **Если пользователь отказывается менять структуру — описываем в манифесте всё, что нужно для работы с текущей** (поля `amxmodx.dir`, пути в deps, `output.*`). 3. Базовые вопросы при нехватке данных: имя пакета, нужен ли ini со списком плагинов и с каким постфиксом, что входит в пакет. 4. **Версия компилятора (amxxpc) — всегда последняя.** В манифесте поле `amxmodx.version` **не указываем** — amxb сам берёт последнюю доступную версию. Единственное исключение: если проект таргетит AMXX **1.8.3 или старее** — эта линия достаточно старая и сильно отличается (другой набор инклудов/нативов, поведение компилятора), поэтому её версию пиним явно. Подсказки в старых скриптах (`amxx190`, пути `C:\AmxModX\1.9.0`) — не повод пинить: 1.9 и новее компилируются последним amxxpc. Уточнять у пользователя нужно только одно: не 1.8.x ли у него сервер. 5. Минимально полезный манифест: ```yaml # yaml-language-server: $schema=https://raw.githubusercontent.com/AmxxModularEcosystem/amxx-builder/master/schema/amxbuild.schema.json name: MyPackage # amxmodx.version не указываем — amxb берёт последний компилятор. # Исключение — AMXX 1.8.3 или старее, тогда пиним явно (точное значение # версии согласовать с пользователем — у линии 1.8 своя нумерация): # amxmodx: # version: "1.8.3" # строка в кавычках deps: - Owner/Repo@tag # plugins-*.ini: по умолчанию НЕ генерируется (generate_ini: false). # Если старой сборке ini не нужен — ничего добавлять не надо. # Если нужен (как в старой сборке) — включить генерацию и постфикс: # plugins_ini_postfix: core # → plugins-core.ini # output: # generate_ini: true ``` 6. **Правила `plugins:`** — фильтрация локальных плагинов (к репо-плагинам не применяются). Первое совпадение побеждает. Например, исключить из сборки тестовые/легаси `.sma`: ```yaml plugins: - match: "*Test*.sma" enabled: false - match: "utils/*.sma" ini: false # компилировать, но не включать ни в один INI ``` 7. Помнить особенности amxb: - локальная папка `amxmodx/` всегда выигрывает у файлов из репо (намеренный слой переопределения, предупреждений нет); - `.sma`-файлы **и копируются** в пакет (как любые файлы), **и компилируются**; если исходники не должны попадать в архив — исключить их (для репо — `exclude:`/`exclude_files:` в правиле репозитория); - README.md попадает в архив только при `output.readme: true` (дефолт). ## Шаг 5. Приватные репозитории **Сигнал приватности — 404.** Если deps/repos не резолвятся (`amxb deps-tree` показывает not found), а пользователь уверен, что репозиторий существует, — первая гипотеза: репозиторий приватный, а не удалённый и не опечатка (GitHub отдаёт 404 одинаково в обоих случаях). Порядок действий: 1. Проверить, нет ли уже токенов в `.env` рядом с манифестом; если есть — подключить (`github.token_env` / `github.tokens`) и повторить `deps-tree`, прежде чем что-либо спрашивать. 2. Если токенов нет/не помогли — спросить пользователя: дать токен для владельца приватного репо или уточнить имя (вдруг опечатка). Если приватность подтверждена (или сам проект приватный) — конфигурация такая: ```yaml github: tokens: OwnerName: GITHUB_TOKEN_OWNER ``` и рядом с манифестом — `.env`: ``` GITHUB_TOKEN_OWNER=ghp_... ``` `.env` обязательно в `.gitignore`! В CI те же переменные прокидываются из секретов в `env:` шага с action `AmxxModularEcosystem/amxx-builder@v1` (встроенного `GITHUB_TOKEN` для чужих приватных репо недостаточно). ## Шаг 6. .gitignore За основу берётся шаблон `amxb init --gitignore`. При миграции **свериться с исходным `.gitignore`** и сохранить специфичные для проекта строки, которых нет в шаблоне. Типовой результат: ```gitignore # Артефакты сборки *.amxx *.zip build/ dist/ plugins-*.ini # старый bat-билд (если был) .build # amxb: секреты и кэш .env .env.local .amxb-cache/ # инструменты / редактор .omo/ .codegraph/ .vscode/ .claude/ node_modules/ ``` ## Шаг 7. Замена старых скриптов Мини-чек-лист адаптации (шаблоны `amxb init` не перезаписывают существующие файлы — только явный `amxb init --force` перезапишет; всё, что уже есть, правим/создаём вручную): - `amxb init --script` создаёт тонкий `build.bat`/`build.sh` (просто `amxb build`) — только если файлов ещё нет. Если `build.bat`/`build.sh` уже существуют — **заменяем их вручную** тонкими (init их не тронет без `--force`). - Старые скрипты сборки (`config.bat`, `build-debug.bat`, `build-release.bat`, `.build-config`, `deps.txt` после переноса данных в манифест, старые `*.zip`, `.build/`) — удаляем. - Debug/release — через defines: `amxb build --define DEBUG`. - **НЕ создавать тестовые плагины** через `amxb init --plugin ` в рамках миграции/отладки: файл создаётся пустым и сам провоцирует `error 100` при компиляции (см. Шаг 10). Проверка идёт по реальным `.sma` проекта. ## Шаг 8. CI Если CI уже есть — правим существующий файл, не плодим новый. Что учесть: - ветки и триггеры: сверить с фактической дефолтной веткой репозитория (`main`/`master`) и со старым CI (перенести `paths-ignore`, типы PR и т.п.); - секреты токенов для приватных deps — в `env:` шага сборки; - dev-артефакт на каждый push + zip в релиз — как в шаблоне `amxb init --workflow` (именование dev: `{name}-{sha}-dev`, релизный zip: `{name}-{ref_name}.zip`); - `output.readme: true` работает и при `output.pack: false` — README копируется в каталог артефакта сам, отдельный шаг копирования в publish-джобе не нужен; - если в шаблоне CI ветки/триггеры не совпадают с реальностью — правим, шаблон не догма. ## Шаг 9. MCP (опционально) `amxb init --opencode` создаёт `.opencode/opencode.json` с MCP-сервером `amxx-dep-resolver` (`amxb mcp`), дающим агенту инструменты резолва include, дерева зависимостей и компиляции. **Это инструменты для АГЕНТА, а не для пользователя**: они дают миграции больше данных о проекте (резолв инклудов, список релизов, дерево deps) без ручных запросов и ускоряют её. Файл коммитим (внутренние `node_modules`/`package*.json` — нет, у них свой `.gitignore`). **Перезапуск opencode нужен самому агенту, а не пользователю.** Без перезапуска инструменты `amxx-dep-resolver` не появятся в сессии агента, и миграция лишится MCP-данных о проекте (придётся работать через CLI `amxb releases`/`deps-tree` — это работает, но медленнее). Поэтому после создания/правки конфига: 1. проверить, появились ли инструменты `amxx-dep-resolver` в текущей сессии; 2. если не появились (или проверить не удалось) — **явно попросить пользователя перезапустить opencode** (выйти и запустить заново), объяснив, что перезапуск нужен агенту, чтобы получить инструменты для миграции; продолжить миграцию можно и без них, но с MCP она точнее; 3. не утверждать, что MCP работает, если инструменты не видны, и не молча продолжать без MCP там, где он мог бы дать данные о проекте. ## Шаг 10. Проверка результата ```bash amxb validate # манифест валиден amxb deps-tree # все deps резолвятся (приватные — по токенам) amxb build --dry-run # план: компилятор, deps, архив, ini amxb build # полная сборка ``` Критерии успеха: - все плагины компилируются (`OK` по каждому); - ini-файл(ы) сгенерированы, если включены; - содержимое архива структурно совпадает со старым пакетом (если он был). Как читать ошибки: - `fatal error 100: cannot read from file: "<путь>.sma"` — сначала проверить **сам файл**, а не окружение: 1. файл существует (`ls -l <путь>.sma`); 2. файл **не пустой** — пустой `.sma` (0 байт) даёт ровно ту же ошибку. Пустые `.sma` не должны попадать в сборку: `amxb init --plugin` создаёт пустую заготовку, и если она осталась в `scripting/` — это ложный след. Такие файлы удаляем или исключаем (`plugins:` → `enabled: false`). 3. Если файлы на месте и непустые, а ошибка **для всех** файлов при верных путях → проблема окружения, не манифеста (например, WSL: amxxpc 32-битный и не читает `/mnt/c`). - **WSL (`/mnt/c`) — готовый рецепт полной проверки.** В WSL из `/mnt/c` работают `validate`, `deps-tree`, `--dry-run` (компилятор не запускается), но полный `amxb build` падает на 32-битном amxxpc. Полную сборку выполняем из нативной Linux-папки — кэш общий, повторно ничего не качается: ```bash mkdir -p ~/amxb-build-check && cp -r amxmodx assets amxbuild.yml README.md ~/amxb-build-check/ cd ~/amxb-build-check && amxb build # кэш ~/.cache/amxx-builder общий для всех папок — deps/компилятор уже там ``` Финальную сборку из `/mnt/c` пользователь выполняет на Windows (`build.bat`) или в CI; в WSL проверяются `validate`/`deps-tree`/`--dry-run`. - `unable to open include file` для конкретного инклуда → не хватает dep или неверный путь до include внутри dep. - `undefined symbol/native` → несовпадение версии API: include резолвится, но код использует другой неймспейс/префиксы (`MOD_*` vs `NS_MOD_*`) — значит, выбрана не та линия релизов зависимости (см. «Формат deps»). Уточнить у пользователя корректную версию. ## Чек-лист - [ ] amxb доступен (установлен глобально или вызывается через npx) - [ ] НЕ читались файлы/репозитории вне папки целевого проекта (в т.ч. соседние проекты, «для понимания») - [ ] Входные данные собраны только из папки проекта: CI/workflow разобран первым (репо, версии, include-пути) - [ ] Внешние include сопоставлены с источниками; не найденные после разбора CI/скриптов — согласованы с пользователем - [ ] При «репо не найден» (404): сначала проверены токены из `.env`, затем у пользователя запрошен токен/уточнение имени — вывод «репо не существует» без подтверждения не делался - [ ] Дефолтная раскладка проверена `amxb build --dry-run`; вопросы про структуру — только при отличии от дефолта - [ ] `amxbuild.yml`: name, deps, ini/постфикс при необходимости; `amxmodx.version` не указан (последний компилятор), кроме AMXX <= 1.8.3 - [ ] Версии deps: последняя проверена сборкой → иначе версия из проекта/CI → иначе вопрос; в манифесте конкретные теги, не «latest» - [ ] Приватные deps: 404 обработан как «приватный/опечатка» → `github.tokens` + `.env` (в .gitignore) - [ ] `.gitignore`: шаблон amxb + сохранены специфичные строки проекта - [ ] Старые скрипты удалены; существовавший `build.bat`/`build.sh` заменён тонким вручную - [ ] Пустые/заглушечные `.sma` (в т.ч. от `init --plugin`) не попадают в сборку - [ ] CI обновлён: ветки/триггеры сверены со старым CI и дефолтной веткой; README при `pack=false` не копируется вручную - [ ] MCP (если делали): файл создан; если инструменты `amxx-dep-resolver` не подхватились — пользователю сказано перезапустить opencode (перезапуск нужен агенту для доступа к инструментам) - [ ] `amxb validate` + `deps-tree` + `build` проходят (в WSL из `/mnt/c` — полная сборка из нативной Linux-папки) - [ ] Архив структурно совпадает со старым пакетом