amxx-builder 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +13 -3
- package/README.md +276 -20
- package/action.yml +1 -1
- package/defaults/amxbuild.defaults.yml +7 -1
- package/mcp/handlers.js +342 -152
- package/mcp/registry.js +264 -25
- package/package.json +1 -1
- package/skills/amxb-migration/SKILL.md +126 -27
- package/skills/amxx-pawn-style/SKILL.md +422 -0
- package/src/agent-assets.js +206 -0
- package/src/asset-fetcher.js +33 -48
- package/src/build-plan.js +22 -5
- package/src/build-service.js +54 -11
- package/src/cli.js +38 -4
- package/src/collector.js +9 -1
- package/src/commands/build.js +5 -4
- package/src/commands/dry-run.js +28 -1
- package/src/commands/init.js +125 -11
- package/src/commands/opencode-skills.js +47 -0
- package/src/commands/serve.js +309 -111
- package/src/commands/skills-dir.js +21 -0
- package/src/commands/watch.js +66 -23
- package/src/compile-utils.js +119 -4
- package/src/compiler-fetcher.js +196 -41
- package/src/compiler.js +68 -29
- package/src/dep-graph.js +27 -0
- package/src/deployer.js +39 -15
- package/src/deps-resolver.js +151 -11
- package/src/deps-tree.js +20 -9
- package/src/download.js +132 -0
- package/src/fs-utils.js +35 -1
- package/src/fungun-fetcher.js +28 -8
- package/src/github-api.js +32 -0
- package/src/include-tree.js +30 -61
- package/src/ini-builder.js +1 -1
- package/src/jsonrpc-transport.js +53 -5
- package/src/local-sources.js +363 -0
- package/src/manifest-path.js +18 -1
- package/src/manifest.js +398 -40
- package/src/opencode-skills.js +262 -0
- package/src/release-fetcher.js +26 -33
- package/src/repo-fetcher.js +388 -37
- package/src/retry.js +3 -1
- package/src/schema.js +1 -1
- package/templates/init-deploy.env +9 -0
- package/templates/init-gitignore +22 -0
- package/src/dep-docs.js +0 -115
package/AGENTS.md
CHANGED
|
@@ -8,7 +8,7 @@ Entry: `index.js` (CLI via `commander`). Action: `action-entry.js` → synthesis
|
|
|
8
8
|
- Node.js 18+, pure **CommonJS** (`require`), no ESM. Exception: `action-entry.js` uses `import * as core from '@actions/core'` because `@actions/core@3.x` is ESM-only — esbuild transpiles it to CJS in the bundle. Do not "fix" that import back to `require`, it fails to resolve.
|
|
9
9
|
- **Node 18+ is a deliberate, genuinely minimal floor.** Write code that works on Node 18 — do not use newer-version-only APIs (stable `node:test` features, `fetch`, `AbortSignal.timeout`, …) unless they exist in 18. If a feature truly requires a newer Node, propose raising the minimum in the PR/discussion first; right now there is no practical benefit in raising it (no feature pressure, no dependency forcing it), and a raised floor would only cut off users stuck on 18. CI tests the matrix 18/24 (floor + newest) to keep this honest.
|
|
10
10
|
- Only dev dep: `esbuild` for bundling the GitHub Action.
|
|
11
|
-
- Tests: `node --test` (built-in node:test, zero deps; discovers `test/*.test.js`
|
|
11
|
+
- Tests: `node --test` (built-in node:test, zero deps; discovers `test/*.test.js`). Keep fixtures out of `test/`, and do NOT name non-test scripts `*-test.js` — the runner's default glob (`**/*-test.js`) would execute them as tests. The bundler smoke script is `scripts/smoke.js` (needs a bundled `dist/` + compiler cache, so it is run explicitly, never by the test runner). No linter or type checker configured.
|
|
12
12
|
|
|
13
13
|
## Architecture: logic lives once in the core
|
|
14
14
|
- All business logic MUST live in `src/` (the core) and be interface-agnostic: no `process.argv`, no `process.stdout` writes, no `commander`, no JSON-RPC/MCP schemas, no CLI rendering.
|
|
@@ -21,6 +21,7 @@ Entry: `index.js` (CLI via `commander`). Action: `action-entry.js` → synthesis
|
|
|
21
21
|
- Include-path candidate lists (`['scripting/include', 'amxmodx/scripting/include', 'include', '.']`) — single source: `src/deps-resolver.js` (`resolveIncludePath`)
|
|
22
22
|
- Dep string parsing (`owner/repo@ref[:include_path]`) — single source: `src/manifest.js` (`parseDepsLines`)
|
|
23
23
|
- GitHub token resolution — `src/manifest.js` (`resolveGithubToken`); repo key / normalization — `src/deps-resolver.js` (`repoKey`, `normalize`)
|
|
24
|
+
- Local sources — `source: local` resolution and `AMXB_LOCAL_SOURCES` env-override parsing, `_localDir` resolution, `_resolvedRef = 'local'` stamping, `ensureRepoDir` — single source: `src/local-sources.js` (`applyLocalOverrides`, `parseLocalSourcesEnv`, `ensureRepoDir`)
|
|
24
25
|
- When touching an interface layer, check whether the logic already exists in `src/` before writing new code. New core exports are cheap; new duplication is debt.
|
|
25
26
|
|
|
26
27
|
## Commands
|
|
@@ -37,12 +38,17 @@ Entry: `index.js` (CLI via `commander`). Action: `action-entry.js` → synthesis
|
|
|
37
38
|
| `amxb init` | Scaffold manifest and optional files |
|
|
38
39
|
| `amxb init --force` | Scaffold, overwriting existing files (default: skip) |
|
|
39
40
|
| `amxb init --script` | Also create `build.bat` / `build.sh` quick-build scripts |
|
|
41
|
+
| `amxb init --vscode` | Also create `.vscode/extensions.json` with recommended extensions (alias `--vsc`; merges into an existing file) |
|
|
40
42
|
| `amxb clean` | Clean build/ and clone cache |
|
|
41
43
|
| `amxb clean --all` | Also clean compiler cache |
|
|
42
44
|
| `amxb cache info` | Show cache contents |
|
|
45
|
+
| `amxb skills-dir` | Print absolute path to the bundled `skills/` dir (used by the opencode bridge plugin) |
|
|
46
|
+
| `amxb opencode-skills` | Print container path(s) of materialized skills (bundled + current project + deps/repos) for the opencode bridge |
|
|
43
47
|
| `amxb serve` | Start JSON-RPC server for editor integration (stdio transport) |
|
|
44
48
|
| `npm start` | Alias for `node index.js` |
|
|
45
49
|
|
|
50
|
+
The opencode bridge plugin (`.opencode/plugin/amxb-skills.js`, generated by `amxb init --opencode`) registers skills from three sources: the builder's bundled `skills/` (`amxb skills-dir`), the current project's own `skills:`, and all `deps`/`repos` skills read from their manifests (`amxb opencode-skills`; missing ones fetched from the network on demand).
|
|
51
|
+
|
|
46
52
|
## Build order (matters)
|
|
47
53
|
1. Parse manifest (deep-merge with `defaults/amxbuild.defaults.yml`)
|
|
48
54
|
2. Fetch compiler (`amxxpc`, auto-resolves latest version)
|
|
@@ -58,15 +64,17 @@ Entry: `index.js` (CLI via `commander`). Action: `action-entry.js` → synthesis
|
|
|
58
64
|
- **Arrays are replaced entirely** (repos, deps, assets.sources) — not merged with defaults.
|
|
59
65
|
- `version` **must be a quoted string** in YAML or parsing fails.
|
|
60
66
|
- `ref: latest` resolves to the latest GitHub release tag automatically.
|
|
61
|
-
-
|
|
67
|
+
- `ref_ttl` (optional, git `repos[]`/`deps[]` objects only) sets the TTL of the `ref → SHA` resolution cache: `never`, a duration (`30m`/`1h`/`7d`), or an integer number of seconds. Default: a named ref GitHub confirms as a **tag** is cached forever; a branch (including the default branch when no `ref` is given) revalidates after 1 hour. When a ref name exists as both a tag and a branch, the tag wins and the ref is cached as immutable. Because clones are SHA-keyed, an unchanged SHA is never re-downloaded; a force-pushed tag is only picked up via an explicit `ref_ttl` or `amxb clean`. It does not affect `source: release`/`fungun`/`local`, `latest`, or `null` refs, and the string dep form / `DEPS_LIST` cannot express it.
|
|
68
|
+
- Plugin rules (`plugins.rules:`) apply **only to local** `.sma` files, not repo plugins; `plugins.defaults` and `repos[].plugins` apply to all plugins. An effective non-`false` `ini` enables INI generation.
|
|
62
69
|
- Local `amxmodx/` always wins over repo files (intentional override layer, no conflict warning).
|
|
63
70
|
- `.sma` files ARE copied during collect (like any other file) and are also compiled; exclude them per-repo via `exclude_files` if sources should not ship.
|
|
71
|
+
- `repos:`/`deps:` entries can be satisfied by a **local directory** instead of GitHub: `source: local` + `path` (relative to the manifest dir, or absolute; optional `name` gives the synthetic id `local/<name>`, defaulting to the path basename). A local repo is collected + its `.sma` compiled and may still set `amxmodx_dir` / `plugins` / `exclude` / `exclude_files` / `deps_override` (`repo`/`ref` forbidden; the deprecated `plugins_ini_postfix` is still accepted with a build warning); a local dep contributes `.inc` to `build/_includes/` (`repo`/`ref`/`id`/`url`/`asset` forbidden; object form only, the `owner/repo@ref[:include_path]` string stays git-only). Local sources are unpinned (the working tree is read as-is) so builds are not reproducible, and watch does not follow dirs outside the manifest's `amxmodx/`/`assets/`.
|
|
64
72
|
|
|
65
73
|
## GitHub Action release flow
|
|
66
74
|
```bash
|
|
67
75
|
npm ci
|
|
68
76
|
npm run bundle # esbuild action-entry.js → dist/index.js + scripts/gen-licenses.js → dist/licenses.txt
|
|
69
|
-
node scripts/smoke
|
|
77
|
+
node scripts/smoke.js # runs the bundled action with INPUT_* env, asserts GITHUB_OUTPUT name output
|
|
70
78
|
# Commit dist/, update package.json version, push tags, publish to npm (idempotent: re-runs are no-ops)
|
|
71
79
|
```
|
|
72
80
|
This is automated in `.github/workflows/release.yml` on `v*.*.*` tags.
|
|
@@ -97,6 +105,8 @@ This is automated in `.github/workflows/release.yml` on `v*.*.*` tags.
|
|
|
97
105
|
## Cache
|
|
98
106
|
- Win: `%LOCALAPPDATA%\amxx-builder`, Unix: `~/.cache/amxx-builder`
|
|
99
107
|
- Override: `AMXX_BUILDER_CACHE`
|
|
108
|
+
- Local source redirects: `AMXB_LOCAL_SOURCES` maps an existing repo/dep id (`owner/repo`) to a path (pairs `id=path` separated by `;`/newlines, or a JSON object), `AMXB_LOCAL_STRICT=1` makes an unmatched id an error (default: warn and ignore). `.env` next to the manifest is honored — see `src/local-sources.js`.
|
|
109
|
+
- Plugin INI debug override: `AMXB_PLUGINS_DEBUG` (read from `.env` next to the manifest, local only — `.env` is gitignored) forces the ` debug` suffix in generated `plugins-*.ini` on/off for every included plugin. `1`/`true`/`yes`/`on` force on, `0`/`false`/`no`/`off` force off, anything else (unset/empty) leaves the manifest in charge. Case-insensitive. Precedence: `AMXB_PLUGINS_DEBUG` > per-rule/per-repo `debug` > `plugins.defaults.debug`; it only affects plugins already in an INI and never enables INI generation by itself.
|
|
100
110
|
- Local per-manifest asset cache: `.amxb-cache/` next to `amxbuild.yml`
|
|
101
111
|
- Separate dirs: `repos/`, `release-deps/`, `amxxpc/` (compiler binaries)
|
|
102
112
|
|
package/README.md
CHANGED
|
@@ -60,6 +60,11 @@ $env:AMXB_VERSION="v1.2.3"; irm https://raw.githubusercontent.com/AmxxModularEco
|
|
|
60
60
|
|
|
61
61
|
Расширение для VSCode - [AMXB — AMX Mod X Builder](https://marketplace.visualstudio.com/items?itemName=amxx-modular-ecosystem.amxb-vscode).
|
|
62
62
|
|
|
63
|
+
Команда `amxb init --vscode` создаёт `.vscode/extensions.json` с рекомендациями расширений
|
|
64
|
+
для AMXX-проекта (`Faktor.amxx-pawn-all-in` + `amxx-modular-ecosystem.amxb-vscode`).
|
|
65
|
+
Существующий файл не перезаписывается: рекомендации проекта сохраняются, недостающие
|
|
66
|
+
добавляются.
|
|
67
|
+
|
|
63
68
|
## Использование
|
|
64
69
|
|
|
65
70
|
```bash
|
|
@@ -80,11 +85,16 @@ amxb init --deploy # + создать .env с заготовк
|
|
|
80
85
|
amxb init --plugin <name> # + создать amxmodx/scripting/<name>.sma
|
|
81
86
|
amxb init --workflow # + создать .github/workflows/ci.yml
|
|
82
87
|
amxb init --script # + создать build.bat / build.sh для быстрого запуска amxb build
|
|
88
|
+
amxb init --opencode # + создать .opencode/ (opencode.json с MCP-конфигом + мост скиллов)
|
|
89
|
+
amxb init --vscode # + создать .vscode/extensions.json с рекомендациями расширений (алиас: --vsc)
|
|
83
90
|
amxb init --force # перезаписать существующие файлы (по умолчанию пропускаются)
|
|
91
|
+
amxb init --force --with-manifest # + перезаписать и существующий amxbuild.yml (без --with-manifest манифест не трогается)
|
|
84
92
|
|
|
85
93
|
amxb clean # очистить build/ и кэш клонов
|
|
86
94
|
amxb clean --all # + кэш компилятора
|
|
87
95
|
amxb cache info # показать содержимое кэша
|
|
96
|
+
|
|
97
|
+
amxb opencode-skills # пути к материализованным скиллам (bundled + проект + deps/repos) для моста opencode
|
|
88
98
|
```
|
|
89
99
|
|
|
90
100
|
Кэш хранится в `%LOCALAPPDATA%\amxx-builder` (Windows) или `~/.cache/amxx-builder` (Unix).
|
|
@@ -145,27 +155,81 @@ my-server/
|
|
|
145
155
|
weapon.wav
|
|
146
156
|
```
|
|
147
157
|
|
|
148
|
-
## Управление
|
|
158
|
+
## Управление плагинами и INI
|
|
149
159
|
|
|
150
|
-
|
|
160
|
+
Секция `plugins:` описывает, какие плагины попадают в INI-файлы, как эти файлы называются и добавлять ли к строке плагина ` debug`. Она состоит из двух частей:
|
|
151
161
|
|
|
152
|
-
|
|
153
|
-
|
|
162
|
+
- `defaults:` — базовый слой, применяется ко **всем** плагинам (локальным и из репо);
|
|
163
|
+
- `rules:` — glob-правила **только для локальных** `.sma` из `amxmodx/scripting/`; первое совпадение побеждает.
|
|
154
164
|
|
|
165
|
+
```yaml
|
|
155
166
|
plugins:
|
|
156
|
-
|
|
157
|
-
ini:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
defaults:
|
|
168
|
+
ini: myserver # базовый INI для всех плагинов → plugins-myserver.ini
|
|
169
|
+
debug: false # true → к каждой строке добавляется " debug"
|
|
170
|
+
rules:
|
|
171
|
+
- match: "VipM/*.sma"
|
|
172
|
+
ini: vipm # → plugins-vipm.ini (переопределяет defaults)
|
|
173
|
+
debug: true # vip_core.amxx debug
|
|
174
|
+
- match: "utils/*.sma"
|
|
175
|
+
ini: false # компилировать, но не включать ни в один INI
|
|
176
|
+
- match: "wip/*.sma"
|
|
177
|
+
enabled: false # полностью пропустить (не компилировать, не деплоить)
|
|
162
178
|
```
|
|
163
179
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
180
|
+
Плагины из репозитория настраиваются на самом репо:
|
|
181
|
+
|
|
182
|
+
```yaml
|
|
183
|
+
repos:
|
|
184
|
+
- repo: Org/VipModular
|
|
185
|
+
plugins:
|
|
186
|
+
ini: vip # → plugins-vip.ini
|
|
187
|
+
debug: false
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Значения `ini`:**
|
|
191
|
+
|
|
192
|
+
| Значение | Результат |
|
|
193
|
+
| --- | --- |
|
|
194
|
+
| `false` | Скомпилировать, но не включать ни в один INI |
|
|
195
|
+
| `true` или `""` | Включить в `plugins.ini` |
|
|
196
|
+
| `"<postfix>"` | Включить в `plugins-<postfix>.ini` |
|
|
197
|
+
| не задано | Наследуется у более низкого слоя приоритета |
|
|
198
|
+
|
|
199
|
+
**Поля:**
|
|
200
|
+
|
|
201
|
+
| Поле | Где | По умолчанию | Описание |
|
|
202
|
+
| --- | --- | --- | --- |
|
|
203
|
+
| `defaults.ini` | `plugins` | — | Базовый INI для всех плагинов |
|
|
204
|
+
| `defaults.debug` | `plugins` | `false` | `true` — к строке плагина добавляется ` debug` |
|
|
205
|
+
| `rules[].match` | `plugins` | — | Glob-паттерн относительно `scripting/` |
|
|
206
|
+
| `rules[].enabled` | `plugins` | `true` | `false` — пропустить компиляцию и деплой |
|
|
207
|
+
| `rules[].ini` | `plugins` | `defaults.ini` | Значение `ini` для совпавших локальных плагинов |
|
|
208
|
+
| `rules[].debug` | `plugins` | `defaults.debug` | `debug` для совпавших локальных плагинов |
|
|
209
|
+
| `repos[].plugins.ini` | репо | `defaults.ini` | Значение `ini` для плагинов этого репо |
|
|
210
|
+
| `repos[].plugins.debug` | репо | `defaults.debug` | `debug` для плагинов этого репо |
|
|
211
|
+
|
|
212
|
+
**Приоритет:** `plugins.rules` → `repos[].plugins` → `plugins.defaults` → выключено (без INI). Правила `rules` действуют только на локальные плагины; `defaults` и `repos[].plugins` — на все.
|
|
213
|
+
|
|
214
|
+
Генерация INI включается сама, как только любое эффективное значение `ini` не `false` (задано в `defaults`, в правиле или на репо). Если `defaults.ini` при этом не задан, а INI включён только правилом или репо, все остальные плагины попадают в `plugins.ini`. Если `ini` не задано нигде — INI-файлы не создаются.
|
|
215
|
+
|
|
216
|
+
Старая форма `plugins:` — массив правил без `defaults` — ещё принимается. Поля `output.generate_ini`, верхнеуровневый `plugins_ini_postfix` и `repos[].plugins_ini_postfix` устарели: они продолжают работать, но при сборке пишут предупреждение. Используйте вместо них `plugins.defaults.ini` и `repos[].plugins`.
|
|
217
|
+
|
|
218
|
+
### Локальное переключение `debug` через `.env`
|
|
219
|
+
|
|
220
|
+
Рядом с манифестом можно положить `.env` (он в `.gitignore` и в репозиторий не попадает). Переменная `AMXB_PLUGINS_DEBUG` в этом файле принудительно включает или выключает суффикс ` debug` **у всех** плагинов в уже сгенерированных `plugins-*.ini`, независимо от манифеста:
|
|
221
|
+
|
|
222
|
+
```env
|
|
223
|
+
AMXB_PLUGINS_DEBUG=1
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
| Значение | Результат |
|
|
227
|
+
| --- | --- |
|
|
228
|
+
| `1` / `true` / `yes` / `on` | Принудительно добавить ` debug` каждому плагину в INI |
|
|
229
|
+
| `0` / `false` / `no` / `off` | Принудительно убрать ` debug` |
|
|
230
|
+
| пусто / не задано / другое | Без переопределения, решает манифест |
|
|
231
|
+
|
|
232
|
+
Значения регистронезависимы. Приоритет: `AMXB_PLUGINS_DEBUG` → `plugins.rules[].debug` / `repos[].plugins.debug` → `plugins.defaults.debug`. Переменная действует только на плагины, которые и так попадают в INI, и **не** включает генерацию INI сама по себе. Удобно для локальной отладки: включите ` debug` в `.env`, не коммитя правку в общий манифест.
|
|
169
233
|
|
|
170
234
|
## Удалённые ассеты
|
|
171
235
|
|
|
@@ -246,6 +310,8 @@ AMXB_DEPLOY_RCON_CMD=amxx load {plugin}
|
|
|
246
310
|
deploy:
|
|
247
311
|
path: /home/user/hlds/cstrike # корень сервера (где лежат addons/, models/)
|
|
248
312
|
amxmodx_path: addons/amxmodx # default: addons/amxmodx
|
|
313
|
+
assets_path: "" # default: "" = корень deploy.path (assets/models, assets/sound → models/, sound/)
|
|
314
|
+
# Задайте, например, "{name}", чтобы зеркалировать layout архива
|
|
249
315
|
watch_debounce_ms: 500 # мс стабильности файла перед ребилдом (default: 500)
|
|
250
316
|
exclude: # пути от deploy.path, которые не перезаписываются
|
|
251
317
|
- addons/amxmodx/configs/ # сохранить конфиги сервера
|
|
@@ -257,6 +323,13 @@ deploy:
|
|
|
257
323
|
command: "amxx load {plugin}" # {plugin} = имя без .amxx; пусто = не слать
|
|
258
324
|
```
|
|
259
325
|
|
|
326
|
+
> **Деплой аддитивен.** `amxb deploy` только копирует файлы из `build/` в `deploy.path` и
|
|
327
|
+
> никогда не удаляет на сервере то, чего нет в источнике — на сервере могут жить и другие
|
|
328
|
+
> плагины/файлы, не управляемые этим манифестом. Удаление с сервера происходит только в
|
|
329
|
+
> watch-режиме для файлов, удалённых локально во время слежения. Если нужно «вычистить»
|
|
330
|
+
> осиротевшие файлы (например, после переименования плагина) — удалите их вручную или
|
|
331
|
+
> очистите каталог перед `amxb deploy`.
|
|
332
|
+
|
|
260
333
|
`amxb watch` отслеживает изменения в `amxmodx/` и `assets/`:
|
|
261
334
|
|
|
262
335
|
- `.sma` → пересобрать плагин, задеплоить `.amxx`, послать RCON
|
|
@@ -291,6 +364,72 @@ github:
|
|
|
291
364
|
|
|
292
365
|
Мапа применяется ко всему: репозитории из `repos:`, зависимости (`deps`/`DEPS_LIST`/`deps_override`), GitHub release-ассеты в `assets.sources` и команда `amxb deps-tree`. Для транзитивных зависимостей токен подбирается по владельцу автоматически.
|
|
293
366
|
|
|
367
|
+
## Локальные источники (repos/deps)
|
|
368
|
+
|
|
369
|
+
Запись в `repos:` или `deps:` можно взять не с GitHub, а из локальной папки. Содержимое читается как есть, как соседние `amxmodx/` и `assets/`: локальный репозиторий собирается вместе с проектом (его `.sma` компилируются), а локальная зависимость отдаёт свои `.inc` в `build/_includes/`.
|
|
370
|
+
|
|
371
|
+
**Локальный репозиторий** (полноценная часть сборки):
|
|
372
|
+
|
|
373
|
+
```yaml
|
|
374
|
+
repos:
|
|
375
|
+
- source: local
|
|
376
|
+
path: ../ProjectA # относительно папки манифеста (или абсолютный)
|
|
377
|
+
name: projecta # необязательно; по умолчанию basename пути
|
|
378
|
+
# также поддерживаются amxmodx_dir, plugins (ini/debug),
|
|
379
|
+
# exclude, exclude_files, deps_override
|
|
380
|
+
# устаревший plugins_ini_postfix ещё принимается (с предупреждением)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
`path` обязателен, `name` необязателен. Внутренний id такой записи: `local/<name>`, по умолчанию `local/<basename пути>`. Поля `repo` и `ref` указывать нельзя. `DEPS_LIST` и `deps_override` локального репо продолжают работать.
|
|
384
|
+
|
|
385
|
+
**Локальная зависимость** (только `.inc` для компиляции):
|
|
386
|
+
|
|
387
|
+
```yaml
|
|
388
|
+
deps:
|
|
389
|
+
- source: local
|
|
390
|
+
path: ../Shared
|
|
391
|
+
name: shared # необязательно
|
|
392
|
+
include_path: scripting/include # необязательно
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
`path` обязателен, `name` и `include_path` необязательны. Поля `repo`, `ref`, `id`, `url`, `asset` запрещены. Строковая форма `owner/repo@ref[:include_path]` остаётся только для git, локальный dep задаётся объектом.
|
|
396
|
+
|
|
397
|
+
Все интерфейсы видят локальные источники одинаково: `amxb build`, `--dry-run`, `deps-tree`, `watch`, serve (`build.plan`) и MCP (`build_plan`, `get_dep_tree`, `validate_manifest`).
|
|
398
|
+
|
|
399
|
+
### Интеграция проектов через AMXB_LOCAL_SOURCES
|
|
400
|
+
|
|
401
|
+
Чтобы собрать проект B против локального чекаута проекта A (без релиза), манифест править не нужно. Переменная `AMXB_LOCAL_SOURCES` перенаправляет **уже объявленную** запись (`repos` или `deps`) на локальную папку по её логическому id `owner/repo` (регистр не важен). Новые записи она не создаёт.
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# один источник
|
|
405
|
+
AMXB_LOCAL_SOURCES='AmxxModularEcosystem/VipModular=../VipModular' amxb build
|
|
406
|
+
|
|
407
|
+
# несколько: через ; или перевод строки
|
|
408
|
+
AMXB_LOCAL_SOURCES=$'Org/A=../A\nOrg/B=/abs/B' amxb build
|
|
409
|
+
|
|
410
|
+
# JSON-объект (значение начинается с {)
|
|
411
|
+
AMXB_LOCAL_SOURCES='{"Org/A":"../A","Org/B":"/abs/B"}' amxb build
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Пути считаются от папки манифеста (абсолютные тоже принимаются). Так как `.env` рядом с манифестом читается до разбора, редирект можно положить туда и держать в `.gitignore`.
|
|
415
|
+
|
|
416
|
+
**Приоритет источников:**
|
|
417
|
+
|
|
418
|
+
| Источник | Приоритет (↑ выше) |
|
|
419
|
+
| --- | --- |
|
|
420
|
+
| `AMXB_LOCAL_SOURCES` (env) | 1 |
|
|
421
|
+
| манифест, `source: local` | 2 |
|
|
422
|
+
| манифест, GitHub (`repo`/`ref`) | 3 |
|
|
423
|
+
|
|
424
|
+
`AMXB_LOCAL_STRICT=1` (или `true`) делает ошибкой id из env, для которого нет репо/dep в манифесте. Без него такой id просто пишет предупреждение и игнорируется. Каждый применённый редирект пишет предупреждение. Кривой синтаксис env тоже предупреждение, не фатальная ошибка.
|
|
425
|
+
|
|
426
|
+
### Ограничения локальных источников
|
|
427
|
+
|
|
428
|
+
- Локальные источники **не версионируются**: рабочее дерево читается как есть, поэтому сборка не воспроизводима. Это годится для разработки и интеграции, но не для релизов.
|
|
429
|
+
- `amxb watch` следит только за `amxmodx/` и `assets/` манифеста и **не** следит за папками локальных зависимостей: правки в локальном dep не запускают пересборку автоматически.
|
|
430
|
+
- Папка должна существовать: отсутствующий `path` или опечатка в нём дают жёсткую ошибку, если для этого id не задан редирект в `AMXB_LOCAL_SOURCES` (редирект имеет приоритет и может перекрыть устаревший `path`).
|
|
431
|
+
- Внутренний id локальной записи должен быть уникальным: если два источника дают одинаковый `local/<name>` (например, у папок совпал basename), сборка останавливается с ошибкой. Задайте разные `name`.
|
|
432
|
+
|
|
294
433
|
## GitHub Actions
|
|
295
434
|
|
|
296
435
|
```yaml
|
|
@@ -450,6 +589,54 @@ repos:
|
|
|
450
589
|
ref: latest # автоматически берёт тег последнего GitHub release
|
|
451
590
|
```
|
|
452
591
|
|
|
592
|
+
## Кэш резолва `ref`: `ref_ttl`
|
|
593
|
+
|
|
594
|
+
Поле `ref_ttl` управляет временем жизни кэша резолва `ref → SHA` (файл
|
|
595
|
+
`.ref-heads.json` в кэше сборки). Оно относится только к git-записям `repos[]`
|
|
596
|
+
и `deps[]` и не действует на `source: release`, `source: fungun`,
|
|
597
|
+
`source: local`, `ref: latest` и `ref` без значения (default branch).
|
|
598
|
+
|
|
599
|
+
Допустимые значения:
|
|
600
|
+
|
|
601
|
+
| Значение | Смысл |
|
|
602
|
+
| --- | --- |
|
|
603
|
+
| `never` | Кэшировать резолв вечно (регистронезависимо) |
|
|
604
|
+
| `Ns` / `Nm` / `Nh` / `Nd` | Длительность с целым N ≥ 1: секунды, минуты, часы, дни (например, `30m`, `1h`, `7d`) |
|
|
605
|
+
| целое число `N` | То же в секундах (например, `3600` = 1 час) |
|
|
606
|
+
|
|
607
|
+
Если поле не задано, TTL выводится из типа ref:
|
|
608
|
+
|
|
609
|
+
- именованный ref, который GitHub подтвердил как **тег** → кэш вечный;
|
|
610
|
+
- ветка, а также default branch при отсутствии `ref` → перепроверка раз в **1 час**.
|
|
611
|
+
|
|
612
|
+
Если одно и то же имя существует и как тег, и как ветка, приоритет у тега: такой
|
|
613
|
+
ref классифицируется как тег и кэшируется как неизменяемый.
|
|
614
|
+
|
|
615
|
+
Явный `ref_ttl` переопределяет дефолт для конкретной записи. Протухание TTL
|
|
616
|
+
инвалидирует только связку `ref → SHA`: каталог клона ключуется по SHA, поэтому
|
|
617
|
+
неизменённый SHA ничего не перекачивает. Если тег force-push'нули, вечный кэш
|
|
618
|
+
этого не заметит: обновите явный `ref_ttl` или выполните `amxb clean`.
|
|
619
|
+
|
|
620
|
+
```yaml
|
|
621
|
+
repos:
|
|
622
|
+
- repo: Org/VipModular
|
|
623
|
+
ref: main
|
|
624
|
+
ref_ttl: 30m # ветку перепроверять раз в 30 минут
|
|
625
|
+
|
|
626
|
+
- repo: Org/Stable
|
|
627
|
+
ref: v2.1.0
|
|
628
|
+
ref_ttl: never # тег: закрепить резолв навсегда
|
|
629
|
+
|
|
630
|
+
deps:
|
|
631
|
+
- repo: Org/ParamsController
|
|
632
|
+
ref: 1.4.2
|
|
633
|
+
ref_ttl: 7d # git-dep: перепроверка раз в неделю
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Строковая форма deps (`owner/repo@ref[:include_path]`) и файл `DEPS_LIST` поле
|
|
637
|
+
`ref_ttl` не поддерживают: у них нет слота для этого поля. Используйте полную
|
|
638
|
+
(объектную) форму записи.
|
|
639
|
+
|
|
453
640
|
## deps: fungun.net
|
|
454
641
|
|
|
455
642
|
[fungun.net](https://fungun.net) — магазин закрытых AMXX-плагинов. Архивов и
|
|
@@ -500,9 +687,45 @@ MCP сервер предоставляет агенту opencode информа
|
|
|
500
687
|
}
|
|
501
688
|
```
|
|
502
689
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
690
|
+
Автоматически это настраивается командой `amxb init --opencode`: она создаёт
|
|
691
|
+
`.opencode/opencode.json` с этим MCP-конфигом и файл `.opencode/plugin/amxb-skills.js`,
|
|
692
|
+
тонкий мост, который при каждом старте opencode регистрирует скиллы из трёх источников:
|
|
693
|
+
собственные bundled-скиллы сборщика (`amxb skills-dir`), скиллы текущего проекта из его
|
|
694
|
+
`amxbuild.yml` (`skills:`) и скиллы всех `deps`/`repos`, прочитанные из их манифестов
|
|
695
|
+
(`amxb opencode-skills`; отсутствующие зависимости докачиваются из сети по требованию).
|
|
696
|
+
Абсолютных путей в `opencode.json` нет. Повторный запуск пропускает существующие файлы
|
|
697
|
+
(мержит конфиг), `--force` перезаписывает.
|
|
698
|
+
|
|
699
|
+
> Существующие файлы `.opencode/plugin/amxb-skills.js` автоматически не обновляются:
|
|
700
|
+
> чтобы получить версию с тремя источниками, пересоздайте плагин командой
|
|
701
|
+
> `amxb init --opencode --force` (или создайте файл заново).
|
|
702
|
+
|
|
703
|
+
**23 инструмента** — от просмотра `.inc` файлов до построения дерева зависимостей —
|
|
704
|
+
доступны через MCP. Каталог задокументированных инструментов (включая агент-доки и
|
|
705
|
+
скиллы) — в [`docs/mcp/INDEX.md`](docs/mcp/INDEX.md).
|
|
706
|
+
|
|
707
|
+
Агент-доки и скиллы теперь объявляются в самом манифесте: верхнеуровневые `docs:`
|
|
708
|
+
(справочная документация) и `skills:` (инструкции для агента). Они предназначены
|
|
709
|
+
**только агенту** — не попадают в `build/` и архив, и ничего не отдаётся по умолчанию,
|
|
710
|
+
пока автор не объявил запись явно. Пять инструментов обслуживают их: `get_dep_manifest`
|
|
711
|
+
возвращает сырой `amxbuild.yml` зависимости вместе со сводкой её `docs:`/`skills:`;
|
|
712
|
+
`list_agent_docs` / `get_agent_docs` и `list_agent_skills` / `get_agent_skills` читают
|
|
713
|
+
объявления как текущего проекта, так и зависимости (`dep`/`repo`). Содержимое,
|
|
714
|
+
полученное из зависимости, считается предоставленным её автором и непроверенным:
|
|
715
|
+
источник правды по API — `.inc` файлы. Подробнее — в
|
|
716
|
+
[`docs/mcp/INDEX.md`](docs/mcp/INDEX.md).
|
|
717
|
+
|
|
718
|
+
```yaml
|
|
719
|
+
docs:
|
|
720
|
+
- file: docs/API.md # путь внутри репо
|
|
721
|
+
name: API # по умолчанию — имя файла без расширения
|
|
722
|
+
description: Публичный API плагина
|
|
723
|
+
skills:
|
|
724
|
+
- file: skills/config.md # одиночный скилл-файл
|
|
725
|
+
name: config
|
|
726
|
+
- dir: skills/deep-config # скилл-папка (SKILL.md + references)
|
|
727
|
+
name: deep-config
|
|
728
|
+
```
|
|
506
729
|
|
|
507
730
|
## Скилл миграции для ИИ-агентов
|
|
508
731
|
|
|
@@ -510,6 +733,11 @@ MCP сервер предоставляет агенту opencode информа
|
|
|
510
733
|
он переводит репозиторий AMXX-плагинов на `amxbuild.yml`, подключает `deps`,
|
|
511
734
|
настраивает `.gitignore` / CI / MCP и заменяет старые скрипты сборки.
|
|
512
735
|
|
|
736
|
+
В проекте, созданном через `amxb init --opencode`, скиллы amxb (включая
|
|
737
|
+
`amxb-migration`) подхватываются opencode автоматически: мост-плагин
|
|
738
|
+
`.opencode/plugin/amxb-skills.js` при каждом старте регистрирует не только
|
|
739
|
+
bundled-скиллы сборщика, но и скиллы текущего проекта и его `deps`/`repos`.
|
|
740
|
+
|
|
513
741
|
Канонический файл скилла (можно подключать по прямой ссылке до установки самого amxb —
|
|
514
742
|
шаг 0 скилла ставит amxb при необходимости):
|
|
515
743
|
|
|
@@ -574,9 +802,10 @@ curl -fsSL https://raw.githubusercontent.com/AmxxModularEcosystem/amxx-builder/m
|
|
|
574
802
|
|
|
575
803
|
| Что | Порядок (↑ выше) |
|
|
576
804
|
| --- | --- |
|
|
577
|
-
| плагины `plugins
|
|
578
|
-
| `
|
|
805
|
+
| плагины (`plugins.rules`) | правила применяются по порядку, первое совпадение побеждает |
|
|
806
|
+
| INI плагинов | `plugins.rules` → `repos[].plugins` → `plugins.defaults` → выключено |
|
|
579
807
|
| зависимости | `manifest.deps` → `deps_override` → `DEPS_LIST` файл в репо |
|
|
808
|
+
| локальные источники | `AMXB_LOCAL_SOURCES` (env) → манифест `source: local` → GitHub |
|
|
580
809
|
| ассеты | порядок в `sources:` + `on_conflict` |
|
|
581
810
|
| версия компилятора | `amxmodx.version` → последний релиз |
|
|
582
811
|
| значения манифеста | `--set` → манифест проекта → `defaults/amxbuild.defaults.yml` |
|
|
@@ -597,3 +826,30 @@ sudo dpkg --add-architecture i386
|
|
|
597
826
|
sudo apt update
|
|
598
827
|
sudo apt install libc6:i386 libstdc++6:i386
|
|
599
828
|
```
|
|
829
|
+
|
|
830
|
+
### Сборка падает на `/mnt/...` в WSL
|
|
831
|
+
|
|
832
|
+
`amxxpc` — 32-битный Linux-бинарник, но под WSL он **не читает** файлы на
|
|
833
|
+
Windows-дисках, смонтированных в `/mnt/*` (DrvFs/9p: `/mnt/c`, `/mnt/d`, `/mnt/j`, …).
|
|
834
|
+
Node/bash эти файлы видят, поэтому ошибка выглядит «мистической»:
|
|
835
|
+
|
|
836
|
+
- локальный `.sma` на `/mnt/*` → `fatal error 100: cannot read from file: ".../plugin.sma"`;
|
|
837
|
+
- локальная папка `include/` на `/mnt/*` (идёт как `-i`) → `std::bad_alloc` / `Aborted` (SIGABRT).
|
|
838
|
+
|
|
839
|
+
Плагины из `repos:` при этом собираются нормально — их исходники amxb кладёт в
|
|
840
|
+
нативный кэш `~/.cache/amxx-builder`. Запись `.amxx` на `/mnt/*`, наоборот, работает.
|
|
841
|
+
|
|
842
|
+
**Решение:** собирать из нативной Linux-файловой системы. Скопируйте проект в `~` —
|
|
843
|
+
кэш компилятора и зависимостей общий, заново ничего не скачивается:
|
|
844
|
+
|
|
845
|
+
```bash
|
|
846
|
+
mkdir -p ~/amxb-build && cp -r amxmodx assets amxbuild.yml ~/amxb-build/
|
|
847
|
+
cd ~/amxb-build && amxb build
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
Альтернативы: выполнять сборку на Windows (`build.bat` или `amxb build` в PowerShell)
|
|
851
|
+
либо в CI. Команды без запуска компилятора (`amxb validate`, `amxb deps-tree`,
|
|
852
|
+
`amxb build --dry-run`) под `/mnt/*` работают.
|
|
853
|
+
|
|
854
|
+
> `amxb build --build-dir <нативный путь>` **не** решает проблему: локальные `.sma`
|
|
855
|
+
> компилируются по месту, из папки проекта, а не из `build/`.
|
package/action.yml
CHANGED
|
@@ -34,7 +34,7 @@ inputs:
|
|
|
34
34
|
Override any manifest field. One entry per line:
|
|
35
35
|
version=1.2.3
|
|
36
36
|
output.archive_name={name}-{version}.zip
|
|
37
|
-
|
|
37
|
+
plugins.defaults.ini=myserver
|
|
38
38
|
github.tokens.MyOrg=GITHUB_TOKEN_MYORG
|
|
39
39
|
required: false
|
|
40
40
|
github-token:
|
|
@@ -21,12 +21,14 @@ output:
|
|
|
21
21
|
amxmodx_path: "{name}/addons/amxmodx"
|
|
22
22
|
assets_path: "{name}"
|
|
23
23
|
readme: true
|
|
24
|
-
generate_ini: false
|
|
25
24
|
pack: true
|
|
26
25
|
on_conflict: last_wins
|
|
27
26
|
|
|
28
27
|
plugins: []
|
|
29
28
|
|
|
29
|
+
docs: []
|
|
30
|
+
skills: []
|
|
31
|
+
|
|
30
32
|
assets:
|
|
31
33
|
on_conflict: last_wins
|
|
32
34
|
sources:
|
|
@@ -34,6 +36,10 @@ assets:
|
|
|
34
36
|
|
|
35
37
|
deploy:
|
|
36
38
|
amxmodx_path: addons/amxmodx
|
|
39
|
+
# Empty assets path = deploy root (server root), matching the schema default:
|
|
40
|
+
# local assets/ land where the game reads them, NOT under a {name}/ subfolder
|
|
41
|
+
# (output.assets_path '{name}' only shapes the distribution archive).
|
|
42
|
+
assets_path: ""
|
|
37
43
|
watch_debounce_ms: 500
|
|
38
44
|
exclude: []
|
|
39
45
|
rcon:
|