amxx-builder 1.6.1 → 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/mcp/registry.js CHANGED
@@ -135,7 +135,7 @@ const TOOLS = [
135
135
  'into sub-dependencies. Detects cycles and handles deps_override.\n\n' +
136
136
  'Provide either "manifest" (path to amxbuild.yml) or "deps" (array of dep entries).\n\n' +
137
137
  'Each dep entry can be a string ("owner/repo@ref") or an object ' +
138
- '({ repo, ref, source?, include_path?, asset? }).',
138
+ '({ repo, ref, source?, include_path?, asset?, ref_ttl? }).',
139
139
  inputSchema: {
140
140
  type: 'object',
141
141
  properties: {
@@ -161,6 +161,13 @@ const TOOLS = [
161
161
  source: { type: 'string', enum: ['git', 'release'] },
162
162
  include_path: { type: 'string' },
163
163
  asset: { oneOf: [{ type: 'string' }, { type: 'number' }] },
164
+ ref_ttl: {
165
+ description:
166
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration ' +
167
+ 'like "30m"/"1h"/"7d", or an integer number of seconds. Default: tags ' +
168
+ 'cached forever, branches 1h.',
169
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
170
+ },
164
171
  },
165
172
  required: ['repo', 'ref'],
166
173
  },
@@ -582,6 +589,12 @@ const TOOLS = [
582
589
  asset: {
583
590
  description: 'For source=release: asset selector (glob pattern or index).',
584
591
  },
592
+ ref_ttl: {
593
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
594
+ description:
595
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
596
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
597
+ },
585
598
  pattern: {
586
599
  type: 'string',
587
600
  description: 'Glob pattern, e.g. "**/*.sma", "amxmodx/**", "**/*".',
@@ -640,6 +653,12 @@ const TOOLS = [
640
653
  asset: {
641
654
  description: 'For source=release: asset selector (glob pattern or index).',
642
655
  },
656
+ ref_ttl: {
657
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
658
+ description:
659
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
660
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
661
+ },
643
662
  file: {
644
663
  type: 'string',
645
664
  description: 'Relative path inside the repo/asset root, e.g. "amxmodx/scripting/my_plugin.sma".',
@@ -709,6 +728,12 @@ const TOOLS = [
709
728
  asset: {
710
729
  description: 'For source=release: asset selector (glob pattern or index).',
711
730
  },
731
+ ref_ttl: {
732
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
733
+ description:
734
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
735
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
736
+ },
712
737
  token: {
713
738
  type: 'string',
714
739
  description: 'GitHub PAT override. Defaults to GITHUB_TOKEN env.',
@@ -759,6 +784,12 @@ const TOOLS = [
759
784
  asset: {
760
785
  description: 'For source=release: asset selector (glob pattern or index).',
761
786
  },
787
+ ref_ttl: {
788
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
789
+ description:
790
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
791
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
792
+ },
762
793
  manifest: {
763
794
  type: 'string',
764
795
  description: 'Local mode: path to amxbuild.yml. Auto-detected in cwd when no dep/repo is given.',
@@ -814,6 +845,12 @@ const TOOLS = [
814
845
  asset: {
815
846
  description: 'For source=release: asset selector (glob pattern or index).',
816
847
  },
848
+ ref_ttl: {
849
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
850
+ description:
851
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
852
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
853
+ },
817
854
  manifest: {
818
855
  type: 'string',
819
856
  description: 'Local mode: path to amxbuild.yml. Auto-detected in cwd when no dep/repo is given.',
@@ -894,6 +931,12 @@ const TOOLS = [
894
931
  asset: {
895
932
  description: 'For source=release: asset selector (glob pattern or index).',
896
933
  },
934
+ ref_ttl: {
935
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
936
+ description:
937
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
938
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
939
+ },
897
940
  manifest: {
898
941
  type: 'string',
899
942
  description: 'Local mode: path to amxbuild.yml. Auto-detected in cwd when no dep/repo is given.',
@@ -949,6 +992,12 @@ const TOOLS = [
949
992
  asset: {
950
993
  description: 'For source=release: asset selector (glob pattern or index).',
951
994
  },
995
+ ref_ttl: {
996
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
997
+ description:
998
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration like ' +
999
+ '"30m"/"1h"/"7d", or an integer number of seconds. Default: tags cached forever, branches 1h.',
1000
+ },
952
1001
  manifest: {
953
1002
  type: 'string',
954
1003
  description: 'Local mode: path to amxbuild.yml. Auto-detected in cwd when no dep/repo is given.',
@@ -976,7 +1025,17 @@ const TOOLS = [
976
1025
  'Run amxxpc on a local .sma file without a full build and return the compiler output ' +
977
1026
  '(status, errors, warnings). Resolves the compiler version and include dirs ' +
978
1027
  '(stdlib + manifest deps) the same way a real build would. ' +
979
- 'Use it to iterate on code until it compiles clean.',
1028
+ 'Use it to iterate on code until it compiles clean.\n\n' +
1029
+ 'WSL / Windows-mounted paths: amxxpc is a 32-bit Linux binary and cannot READ ' +
1030
+ 'files on WSL DrvFs/9p mounts (e.g. /mnt/c, /mnt/d, /mnt/j). If sma_file — or any ' +
1031
+ 'include dir — lives under /mnt/*, compilation fails with "fatal error 100: ' +
1032
+ 'cannot read from file" (a directory used as an include path can abort it with ' +
1033
+ 'std::bad_alloc / SIGABRT), even though the file exists and Node can read it. ' +
1034
+ 'Writing output to /mnt/* is fine; only reads fail. This is an environment ' +
1035
+ 'limitation, not a code error. Alternative: compile from the Linux-native ' +
1036
+ 'filesystem — copy the .sma and its local include/ dir to e.g. ~/proj/ (the ' +
1037
+ '~/.cache/amxx-builder cache is shared, nothing re-downloads) and pass that path, ' +
1038
+ 'or run the build on Windows.',
980
1039
  inputSchema: {
981
1040
  type: 'object',
982
1041
  properties: {
@@ -1093,6 +1152,13 @@ const TOOLS = [
1093
1152
  source: { type: 'string', enum: ['git', 'release'] },
1094
1153
  include_path: { type: 'string' },
1095
1154
  asset: { oneOf: [{ type: 'string' }, { type: 'number' }] },
1155
+ ref_ttl: {
1156
+ description:
1157
+ 'TTL of the cached ref→SHA resolution for git deps: "never", a duration ' +
1158
+ 'like "30m"/"1h"/"7d", or an integer number of seconds. Default: tags ' +
1159
+ 'cached forever, branches 1h.',
1160
+ oneOf: [{ type: 'string' }, { type: 'integer' }],
1161
+ },
1096
1162
  },
1097
1163
  required: ['repo', 'ref'],
1098
1164
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amxx-builder",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "author": {
5
5
  "name": "ArKaNeMaN"
6
6
  },
@@ -244,6 +244,13 @@ deps:
244
244
  - Owner/Repo@tag
245
245
  - Owner/Repo@tag:нестандартный/путь/до/include
246
246
 
247
+ # git-репо полной формой: ref_ttl задаёт TTL кэша резолва ref → SHA
248
+ # (never | 30m | 1h | 7d | целое число секунд; дефолт: тег — вечно,
249
+ # ветка/default branch — 1ч). Строковая форма выше ref_ttl не принимает.
250
+ # - repo: Owner/Repo
251
+ # ref: main
252
+ # ref_ttl: 30m
253
+
247
254
  # модуль из release-архива; ref: latest резолвится в последний релиз,
248
255
  # но в манифест пишем конкретный тег (см. «Выбор версии» ниже)
249
256
  - repo: Owner/Repo
@@ -257,8 +264,42 @@ deps:
257
264
  id: 106
258
265
  ```
259
266
 
260
- Источников у deps три: `git` (по умолчанию), `release` (GitHub release-архив)
261
- и `fungun` (публичный `.inc` со страницы закрытого плагина на fungun.net).
267
+ Источников у deps четыре: `git` (по умолчанию), `release` (GitHub release-архив),
268
+ `fungun` (публичный `.inc` со страницы закрытого плагина на fungun.net) и
269
+ `local` (папка рядом с манифестом, см. ниже).
270
+
271
+ ### Локальные источники (`source: local`)
272
+
273
+ Репозиторий или зависимость можно взять не с GitHub, а из локальной папки. Удобно
274
+ для интеграционной сборки вместе с соседним чекаутом.
275
+
276
+ ```yaml
277
+ # зависимость: только .inc для компиляции (объект, строковая форма не поддерживается)
278
+ deps:
279
+ - source: local
280
+ path: ../Shared # относительно папки манифеста (или абсолютный)
281
+ name: shared # необязательно, id = local/<name>
282
+ include_path: scripting/include # необязательно
283
+
284
+ # репозиторий: часть сборки, его .sma тоже компилируются
285
+ repos:
286
+ - source: local
287
+ path: ../ProjectA
288
+ name: projecta
289
+ ```
290
+
291
+ `path` обязателен, `name` и `include_path` необязательны. Уже объявленную запись
292
+ можно временно перенаправить на локальную папку без правки манифеста переменной
293
+ `AMXB_LOCAL_SOURCES` по её id `owner/repo`:
294
+
295
+ ```bash
296
+ AMXB_LOCAL_SOURCES='Org/Repo=../Repo' amxb build
297
+ ```
298
+
299
+ Значение: пары `id=path` через `;` или перевод строки, либо JSON-объект
300
+ `{"id":"path"}`. Редирект можно держать в `.env` (он в `.gitignore`). Локальные
301
+ источники не версионируются (рабочее дерево читается как есть), поэтому подходят
302
+ для разработки и интеграции, а не для релизной сборки.
262
303
 
263
304
  **Что даёт `deps:` и чего не даёт.** `deps:` — это **только заголовочные
264
305
  файлы (`.inc`) для компиляции**. amxb **не компилирует и не упаковывает**
@@ -312,7 +353,8 @@ deps:
312
353
  # archive → /abs/path/./{name}.zip
313
354
  # amxmodx path in archive: {name}/addons/amxmodx/
314
355
  # assets path: {name}/
315
- # generate_ini: false | on_conflict: last_wins
356
+ # plugins ini: enabled | default: plugins-core.ini | debug: false
357
+ # on_conflict: last_wins
316
358
  ```
317
359
  Вопросы пользователю про структуру задаём **только если** фактическая
318
360
  раскладка отличается от дефолтной и это принципиально (серверная сборка,
@@ -347,23 +389,48 @@ deps:
347
389
  deps:
348
390
  - Owner/Repo@tag
349
391
 
350
- # plugins-*.ini: по умолчанию НЕ генерируется (generate_ini: false).
351
- # Если старой сборке ini не нужен — ничего добавлять не надо.
352
- # Если нужен (как в старой сборке) — включить генерацию и постфикс:
353
- # plugins_ini_postfix: core # → plugins-core.ini
354
- # output:
355
- # generate_ini: true
392
+ # INI плагинов (plugins-*.ini) по умолчанию НЕ генерируется: пока нигде
393
+ # не задано значение ini, файлов нет. Если старой сборке ini не нужен —
394
+ # ничего добавлять не надо. Если нужен (как в старой сборке) — одна секция:
395
+ # plugins:
396
+ # defaults:
397
+ # ini: core # → plugins-core.ini для всех плагинов
356
398
  ```
357
- 6. **Правила `plugins:`** — фильтрация локальных плагинов (к репо-плагинам
358
- не применяются). Первое совпадение побеждает. Например, исключить из
359
- сборки тестовые/легаси `.sma`:
399
+ 6. **Секция `plugins`** — единая настройка INI. `defaults` применяется ко
400
+ **всем** плагинам (локальным и из репо) как базовый слой; `rules` —
401
+ glob-правила **только для локальных** `.sma` (`amxmodx/scripting/`),
402
+ первое совпадение побеждает. Например, исключить тестовые/легаси исходники
403
+ и развести остальные по INI:
360
404
  ```yaml
361
405
  plugins:
362
- - match: "*Test*.sma"
363
- enabled: false
364
- - match: "utils/*.sma"
365
- ini: false # компилировать, но не включать ни в один INI
406
+ defaults:
407
+ ini: core # базовый INI → plugins-core.ini
408
+ debug: false # true → к строке плагина добавляется " debug"
409
+ rules:
410
+ - match: "*Test*.sma"
411
+ enabled: false # полностью пропустить (не компилировать, не деплоить)
412
+ - match: "utils/*.sma"
413
+ ini: false # компилировать, но не включать ни в один INI
414
+ - match: "VipM/*.sma"
415
+ ini: vipm # → plugins-vipm.ini
416
+ debug: true
417
+ ```
418
+ Значения `ini`: `false` — не включать в INI; `true` или `""` — `plugins.ini`;
419
+ `"<postfix>"` — `plugins-<postfix>.ini`. Приоритет:
420
+ `rules` → `repos[].plugins` → `plugins.defaults` → выключено. У плагинов из
421
+ `repos:` INI настраивается на самом репо:
422
+ ```yaml
423
+ repos:
424
+ - repo: Owner/Repo
425
+ plugins:
426
+ ini: vip # → plugins-vip.ini
427
+ debug: false
366
428
  ```
429
+ Генерация INI включается автоматически, как только любое эффективное `ini`
430
+ не `false`. Старая форма `plugins:` — массив правил без `defaults` — ещё
431
+ принимается; поля `output.generate_ini`, `plugins_ini_postfix` и
432
+ `repos[].plugins_ini_postfix` устарели (продолжают работать, но пишут
433
+ предупреждение при сборке).
367
434
  7. Помнить особенности amxb:
368
435
  - локальная папка `amxmodx/` всегда выигрывает у файлов из репо
369
436
  (намеренный слой переопределения, предупреждений нет);
@@ -375,7 +442,13 @@ deps:
375
442
  (файлы) и `skills:` (одиночный файл либо папка с `SKILL.md` +
376
443
  справочниками): они читаются агентом через MCP/serve и **не попадают**
377
444
  в `build/` и архив, а по умолчанию не отдаётся ничего — только явно
378
- объявленные записи.
445
+ объявленные записи;
446
+ - `ref_ttl` (только git-записи `repos`/`deps` в объектной форме) задаёт TTL
447
+ кэша резолва `ref → SHA`: `never` / `30m` / `1h` / `7d` / целое число
448
+ секунд. По умолчанию тег кэшируется вечно, ветка (и default branch)
449
+ перепроверяется раз в час; контент ключуется по SHA, поэтому неизменённый
450
+ SHA не перекачивается. На `source: release`/`fungun`/`local`,
451
+ `ref: latest` и пустой `ref` поле не действует.
379
452
 
380
453
  ## Шаг 5. Приватные репозитории
381
454
 
@@ -434,7 +507,8 @@ plugins-*.ini
434
507
  # инструменты / редактор
435
508
  .omo/
436
509
  .codegraph/
437
- .vscode/
510
+ .vscode/*
511
+ !.vscode/extensions.json
438
512
  .claude/
439
513
  node_modules/
440
514
  ```
@@ -450,6 +524,13 @@ node_modules/
450
524
  `amxb build`) — только если файлов ещё нет. Если `build.bat`/`build.sh`
451
525
  уже существуют — **заменяем их вручную** тонкими (init их не тронет без
452
526
  `--force`).
527
+ - `amxb init --vscode` (алиас `--vsc` — сокращение, не отдельный флаг)
528
+ создаёт `.vscode/extensions.json` с рекомендациями расширений
529
+ (`Faktor.amxx-pawn-all-in`, `amxx-modular-ecosystem.amxb-vscode`).
530
+ Существующий файл **не перезаписывается**: рекомендации проекта
531
+ сохраняются, недостающие amxb-расширения добавляются. Файл коммитим
532
+ (`extensions.json` — единственный отслеживаемый файл в `.vscode/`,
533
+ см. Шаг 6).
453
534
  - Старые скрипты сборки (`config.bat`, `build-debug.bat`,
454
535
  `build-release.bat`, `.build-config`, `deps.txt` после переноса данных в
455
536
  манифест, старые `*.zip`, `.build/`) — удаляем.
@@ -526,13 +607,17 @@ amxb build # полная сборка
526
607
  2. файл **не пустой** — пустой `.sma` (0 байт) даёт ровно ту же ошибку.
527
608
  Пустые `.sma` не должны попадать в сборку: `amxb init --plugin` создаёт
528
609
  пустую заготовку, и если она осталась в `scripting/` — это ложный след.
529
- Такие файлы удаляем или исключаем (`plugins:` → `enabled: false`).
610
+ Такие файлы удаляем или исключаем (`plugins.rules:` → `enabled: false`).
530
611
  3. Если файлы на месте и непустые, а ошибка **для всех** файлов при верных
531
612
  путях → проблема окружения, не манифеста (например, WSL: amxxpc
532
- 32-битный и не читает `/mnt/c`).
533
- - **WSL (`/mnt/c`) — готовый рецепт полной проверки.** В WSL из `/mnt/c`
613
+ 32-битный и не читает `/mnt/*` — DrvFs/9p — хотя Node/bash файл видят;
614
+ локальная папка `include/` на `/mnt/*` даёт вместо этого
615
+ `std::bad_alloc`/SIGABRT).
616
+ - **WSL (`/mnt/*`) — готовый рецепт полной проверки.** В WSL из `/mnt/*`
534
617
  работают `validate`, `deps-tree`, `--dry-run` (компилятор не запускается),
535
- но полный `amxb build` падает на 32-битном amxxpc. Полную сборку выполняем
618
+ но полный `amxb build` падает на 32-битном amxxpc (не читает исходники;
619
+ запись `.amxx` на `/mnt/*`, наоборот, работает). Плагины из `repos` не
620
+ страдают — их исходники amxb кладёт в нативный кэш. Полную сборку выполняем
536
621
  из нативной Linux-папки — кэш общий, повторно ничего не качается:
537
622
  ```bash
538
623
  mkdir -p ~/amxb-build-check && cp -r amxmodx assets amxbuild.yml README.md ~/amxb-build-check/
@@ -556,7 +641,7 @@ amxb build # полная сборка
556
641
  - [ ] Внешние include сопоставлены с источниками; не найденные после разбора CI/скриптов — согласованы с пользователем
557
642
  - [ ] При «репо не найден» (404): сначала проверены токены из `.env`, затем у пользователя запрошен токен/уточнение имени — вывод «репо не существует» без подтверждения не делался
558
643
  - [ ] Дефолтная раскладка проверена `amxb build --dry-run`; вопросы про структуру — только при отличии от дефолта
559
- - [ ] `amxbuild.yml`: name, deps, ini/постфикс при необходимости; `amxmodx.version` не указан (последний компилятор), кроме AMXX <= 1.8.3
644
+ - [ ] `amxbuild.yml`: name, deps, INI (`plugins.defaults` / `plugins.rules`, при необходимости); `amxmodx.version` не указан (последний компилятор), кроме AMXX <= 1.8.3
560
645
  - [ ] Версии deps: последняя проверена сборкой → иначе версия из проекта/CI → иначе вопрос; в манифесте конкретные теги, не «latest»
561
646
  - [ ] Приватные deps: 404 обработан как «приватный/опечатка» → `github.tokens` + `.env` (в .gitignore)
562
647
  - [ ] `.gitignore`: шаблон amxb + сохранены специфичные строки проекта