@nitra/cursor 12.8.3 → 12.8.4

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/rules/js/docs/index.md +3 -3
  4. package/rules/js/docs/main.md +6 -6
  5. package/rules/js/js/docs/check.md +12 -17
  6. package/rules/js/js/docs/index.md +4 -4
  7. package/rules/js/js/docs/tooling.md +8 -8
  8. package/rules/js/js/docs/utils_imports.md +21 -200
  9. package/rules/npm-module/js/docs/index.md +5 -5
  10. package/rules/npm-module/js/docs/rule_meta.md +13 -13
  11. package/rules/npm-module/js/docs/skill_meta.md +19 -9
  12. package/rules/npm-module/js/rule_meta.mjs +9 -9
  13. package/rules/npm-module/js/skill_meta.mjs +6 -6
  14. package/rules/test/js/docs/index.md +7 -7
  15. package/rules/test/js/docs/stryker_config.md +18 -35
  16. package/rules/test/js/docs/vitest-config-pool-forks.md +14 -12
  17. package/schemas/v8r-catalog.json +4 -4
  18. package/scripts/docs/index.md +16 -16
  19. package/scripts/docs/sync-setup-bun-deps-action.md +13 -14
  20. package/scripts/lib/check-mdc-template-refs.mjs +2 -2
  21. package/scripts/lib/docs/check-mdc-template-refs.md +12 -214
  22. package/scripts/lib/docs/index.md +36 -36
  23. package/scripts/lib/docs/mirror-parity.md +18 -157
  24. package/scripts/lib/docs/rule-meta.md +19 -22
  25. package/scripts/lib/docs/run-rule.md +11 -11
  26. package/scripts/lib/docs/skill-meta.md +17 -19
  27. package/scripts/lib/docs/timing-summary.md +6 -6
  28. package/scripts/lib/mirror-parity.mjs +1 -1
  29. package/scripts/lib/rule-meta.mjs +1 -1
  30. package/scripts/lib/run-rule.mjs +4 -4
  31. package/scripts/lib/skill-meta.mjs +1 -1
  32. package/scripts/utils/docs/index.md +14 -14
  33. package/scripts/utils/docs/resolve-js-root.md +12 -13
  34. /package/rules/abie/{meta.json → main.json} +0 -0
  35. /package/rules/abie/{abie.mdc → main.mdc} +0 -0
  36. /package/rules/adr/{meta.json → main.json} +0 -0
  37. /package/rules/adr/{adr.mdc → main.mdc} +0 -0
  38. /package/rules/bun/{meta.json → main.json} +0 -0
  39. /package/rules/bun/{bun.mdc → main.mdc} +0 -0
  40. /package/rules/capacitor/{meta.json → main.json} +0 -0
  41. /package/rules/capacitor/{capacitor.mdc → main.mdc} +0 -0
  42. /package/rules/changelog/{meta.json → main.json} +0 -0
  43. /package/rules/changelog/{changelog.mdc → main.mdc} +0 -0
  44. /package/rules/ci4/{meta.json → main.json} +0 -0
  45. /package/rules/ci4/{ci4.mdc → main.mdc} +0 -0
  46. /package/rules/doc-files/{meta.json → main.json} +0 -0
  47. /package/rules/doc-files/{doc-files.mdc → main.mdc} +0 -0
  48. /package/rules/docker/{meta.json → main.json} +0 -0
  49. /package/rules/docker/{docker.mdc → main.mdc} +0 -0
  50. /package/rules/efes/{meta.json → main.json} +0 -0
  51. /package/rules/efes/{efes.mdc → main.mdc} +0 -0
  52. /package/rules/feedback/{meta.json → main.json} +0 -0
  53. /package/rules/feedback/{feedback.mdc → main.mdc} +0 -0
  54. /package/rules/ga/{meta.json → main.json} +0 -0
  55. /package/rules/ga/{ga.mdc → main.mdc} +0 -0
  56. /package/rules/graphql/{meta.json → main.json} +0 -0
  57. /package/rules/graphql/{graphql.mdc → main.mdc} +0 -0
  58. /package/rules/hasura/{meta.json → main.json} +0 -0
  59. /package/rules/hasura/{hasura.mdc → main.mdc} +0 -0
  60. /package/rules/image-avif/{meta.json → main.json} +0 -0
  61. /package/rules/image-avif/{image-avif.mdc → main.mdc} +0 -0
  62. /package/rules/image-compress/{meta.json → main.json} +0 -0
  63. /package/rules/image-compress/{image-compress.mdc → main.mdc} +0 -0
  64. /package/rules/js/{meta.json → main.json} +0 -0
  65. /package/rules/js/{js.mdc → main.mdc} +0 -0
  66. /package/rules/js-bun-db/{meta.json → main.json} +0 -0
  67. /package/rules/js-bun-db/{js-bun-db.mdc → main.mdc} +0 -0
  68. /package/rules/js-bun-redis/{meta.json → main.json} +0 -0
  69. /package/rules/js-bun-redis/{js-bun-redis.mdc → main.mdc} +0 -0
  70. /package/rules/js-mssql/{meta.json → main.json} +0 -0
  71. /package/rules/js-mssql/{js-mssql.mdc → main.mdc} +0 -0
  72. /package/rules/js-run/{meta.json → main.json} +0 -0
  73. /package/rules/js-run/{js-run.mdc → main.mdc} +0 -0
  74. /package/rules/k8s/{meta.json → main.json} +0 -0
  75. /package/rules/k8s/{k8s.mdc → main.mdc} +0 -0
  76. /package/rules/nginx-default-tpl/{meta.json → main.json} +0 -0
  77. /package/rules/nginx-default-tpl/{nginx-default-tpl.mdc → main.mdc} +0 -0
  78. /package/rules/npm-module/{meta.json → main.json} +0 -0
  79. /package/rules/npm-module/{npm-module.mdc → main.mdc} +0 -0
  80. /package/rules/php/{meta.json → main.json} +0 -0
  81. /package/rules/php/{php.mdc → main.mdc} +0 -0
  82. /package/rules/python/{meta.json → main.json} +0 -0
  83. /package/rules/python/{python.mdc → main.mdc} +0 -0
  84. /package/rules/rego/{meta.json → main.json} +0 -0
  85. /package/rules/rego/{rego.mdc → main.mdc} +0 -0
  86. /package/rules/release/{meta.json → main.json} +0 -0
  87. /package/rules/release/{release.mdc → main.mdc} +0 -0
  88. /package/rules/rust/{meta.json → main.json} +0 -0
  89. /package/rules/rust/{rust.mdc → main.mdc} +0 -0
  90. /package/rules/security/{meta.json → main.json} +0 -0
  91. /package/rules/security/{security.mdc → main.mdc} +0 -0
  92. /package/rules/style/{meta.json → main.json} +0 -0
  93. /package/rules/style/{style.mdc → main.mdc} +0 -0
  94. /package/rules/tauri/{meta.json → main.json} +0 -0
  95. /package/rules/tauri/{tauri.mdc → main.mdc} +0 -0
  96. /package/rules/test/{meta.json → main.json} +0 -0
  97. /package/rules/test/{test.mdc → main.mdc} +0 -0
  98. /package/rules/text/{meta.json → main.json} +0 -0
  99. /package/rules/text/{text.mdc → main.mdc} +0 -0
  100. /package/rules/tool-surface/{meta.json → main.json} +0 -0
  101. /package/rules/tool-surface/{tool-surface.mdc → main.mdc} +0 -0
  102. /package/rules/vue/{meta.json → main.json} +0 -0
  103. /package/rules/vue/{vue.mdc → main.mdc} +0 -0
  104. /package/rules/worktree/{meta.json → main.json} +0 -0
  105. /package/rules/worktree/{worktree.mdc → main.mdc} +0 -0
  106. /package/skills/adr-normalize/{meta.json → main.json} +0 -0
  107. /package/skills/coverage-fix/{meta.json → main.json} +0 -0
  108. /package/skills/doc-aggregate/{meta.json → main.json} +0 -0
  109. /package/skills/doc-files/{meta.json → main.json} +0 -0
  110. /package/skills/lint/{meta.json → main.json} +0 -0
  111. /package/skills/llm-patch/{meta.json → main.json} +0 -0
  112. /package/skills/publish-telegram/{meta.json → main.json} +0 -0
  113. /package/skills/start-check/{meta.json → main.json} +0 -0
  114. /package/skills/taze/{meta.json → main.json} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [12.8.4] - 2026-06-22
4
+
5
+ ### Changed
6
+
7
+ - ♻️ refactor(npm): Перехід з `style-lint` на `style` у правил та конфігах
8
+
3
9
  ## [12.8.3] - 2026-06-22
4
10
 
5
11
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "12.8.3",
3
+ "version": "12.8.4",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -6,7 +6,7 @@ resource: npm/rules/js/
6
6
 
7
7
  # npm/rules/js
8
8
 
9
- | Файл | Тип |
10
- | ------------------- | --------- |
11
- | [fix.mjs](fix.md) | JS Module |
9
+ | Файл | Тип |
10
+ |---|---|
11
+ | [fix.mjs](fix.md) | JS Module |
12
12
  | [main.mjs](main.md) | JS Module |
@@ -3,26 +3,26 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: npm/rules/js/main.mjs
5
5
  docgen:
6
- crc: 4f68b557
6
+ crc: 00294e8e
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль надає інструменти для аналізу кодової бази. Функція `run` ініціює повну перевірку проєкту. Функція `filterJsFiles` відбирає файли з розширенням JavaScript. Функція `lint` запускає лінтинг для виявлення порушень у коді.
13
+ Дозволяє запускати повний аналіз проєкту за допомогою `run`, виконувати лінтинг за допомогою `lint` або фільтрувати файли з розширенням JavaScript за допомогою `filterJsFiles`.
14
14
 
15
15
  ## Поведінка
16
16
 
17
17
  run виконує стандартну перевірку проєкту.
18
18
  filterJsFiles відбирає з наданого списку лише файли, що мають розширення, характерне для JavaScript.
19
- lint запускає лінтинг для вказаних файлів або всього проєкту, залежно від аргументів, і класифікує знайдені порушення.
19
+ lint запускає перевірку проєкту: або повний аналіз усіх файлів, або класифікований аналіз лише змінених файлів.
20
20
 
21
21
  ## Публічний API
22
22
 
23
- run — головна точка входу для виконання правил, що включає перевірку логіки (JS-завдання → політика → посилання MDC) та запуск лінтера.
24
- filterJsFiles — відбирає лише файли, що відповідають формату JavaScript.
25
- lint — виконує аналіз коду за допомогою oxlint та eslint, з можливістю автоматичного виправлення або лише виявлення проблем.
23
+ run — виконує повний цикл перевірки: аналіз конфігурації, перевірку логіки та посилання на метадані.
24
+ filterJsFiles — відбирає лише файли з розширенням JavaScript.
25
+ lint — запускає інструменти для форматування та стилізації коду (oxlint, eslint, jscpd, knip).
26
26
 
27
27
  ## Гарантії поведінки
28
28
 
@@ -3,34 +3,29 @@ type: JS Module
3
3
  title: check.mjs
4
4
  resource: npm/rules/js/js/check.mjs
5
5
  docgen:
6
- crc: f61768f2
6
+ crc: 7ad4aa59
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
- score: 100
8
+ score: 90
9
9
  ---
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль виконує перевірку конфігураційних файлів проєкту, забезпечуючи їхню відповідність встановленим стандартам. Він читає та аналізує конфігураційні файли, включаючи `package.json`, `.oxlintrc.json`, `knip.json`, `knip-canonical.json` та `.eslintrc.json`. Перевірка ґрунтується на логіці, визначеній у (js.mdc) та (text.mdc). Функціонал реалізований у режимі лише читання, що означає відсутність змін у файловій системі чи базах даних. При виявленні проблем, система перехоплює помилки, працюючи у режимі fail-safe. Свідомо ігноруються шляхи `.github` та `.git`.
13
+ Модуль перевіряє відповідність структури та конфігураційних файлів проєкту встановленим стандартам. Він валідує файли, такі як `package.json`, `.oxlintrc.json`, `.eslintrc.json` та файли робочих процесів GitHub, відповідно до вимог (js.mdc). Перевірка свідомо ігнорує шляхи `.github` та `.git`. Модуль забезпечує перехоплення помилок (fail-safe) під час виконання перевірок.
14
14
 
15
15
  ## Поведінка
16
16
 
17
- 1. Викликає `check` для початку перевірки.
18
- 2. Перевіряє наявність та відповідність конфігурації ESLint.
19
- 3. Перевіряє конфігурацію `package.json` для всіх робочих просторів:
20
- а. Перевіряє, чи має `package.json` `"type": "module"`.
21
- б. Перевіряє, чи містить `package.json` `engines.node` з версією не менше 24.
22
- в. Перевіряє, чи містить `package.json` `engines.bun` з версією не менше 1.3.
23
- 4. Перевіряє конфігураційний файл `.oxlintrc.json` на відповідність канонічному шаблону.
24
- 5. Перевіряє файли робочих процесів у `.github/workflows/`:
25
- а. Перевіряє наявність `lint-js.yml`.
26
- б. Перевіряє, чи не дублює `lint.yml` кроки лінтінгу JS.
27
- 6. Перевіряє наявність файлу `knip.json` у корені проєкту. Якщо він відсутній, копіює канонічний шаблон.
28
- 7. Перевіряє наявність застарілих конфігурацій ESLint (`.eslintrc`, `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`) та повідомляє про їхнє існування.
29
- 8. Повертає код виходу, що відображає загальний статус перевірки.
17
+ 1. Викликати `check` для запуску перевірок конфігурації проєкту.
18
+ 2. Перевірити наявність конфігурацій ESLint (flat config) та валідувати їх вміст відповідно до вимог (js.mdc).
19
+ 3. Перевірити `package.json` у корені та у всіх пакетах workspace на відповідність вимогам: наявність `"type": "module"` та мінімальні версії `engines.node` (>=24) та `engines.bun` (>=1.3) (js.mdc).
20
+ 4. Перевірити конфігураційний файл `.oxlintrc.json` на відповідність канонічному шаблону (js.mdc).
21
+ 5. Перевірити файли робочих процесів (`.github/workflows/lint-js.yml` та `.github/workflows/lint.yml`) на відповідність політикам лінтингу (js.mdc).
22
+ 6. Перевірити наявність конфігурацій Knip (`knip.json`). Якщо відсутній, створити його, скопіювавши канонічний шаблон (js.mdc).
23
+ 7. Перевірити наявність застарілих конфігурацій ESLint (наприклад, `.eslintrc.*`) та повідомити про їхнє використання.
24
+ 8. Ігнорувати перевірки у каталогах `.github` та `.git`.
30
25
 
31
26
  ## Публічний API
32
27
 
33
- check — забезпечує відповідність проєкту вимогам, описаним у js.mdc.
28
+ check — перевіряє відповідність проєкту стандартам js.mdc
34
29
 
35
30
  ## Гарантії поведінки
36
31
 
@@ -6,9 +6,9 @@ resource: npm/rules/js/js/
6
6
 
7
7
  # npm/rules/js/js
8
8
 
9
- | Файл | Тип |
10
- | ------------------------------------- | --------- |
11
- | [check.mjs](check.md) | JS Module |
9
+ | Файл | Тип |
10
+ |---|---|
11
+ | [check.mjs](check.md) | JS Module |
12
12
  | [lint-findings.mjs](lint-findings.md) | JS Module |
13
- | [tooling.mjs](tooling.md) | JS Module |
13
+ | [tooling.mjs](tooling.md) | JS Module |
14
14
  | [utils_imports.mjs](utils_imports.md) | JS Module |
@@ -3,26 +3,26 @@ type: JS Module
3
3
  title: tooling.mjs
4
4
  resource: npm/rules/js/js/tooling.mjs
5
5
  docgen:
6
- crc: 7ead48ee
6
+ crc: 101a5230
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 95
9
9
  ---
10
10
 
11
11
  ## Огляд
12
12
 
13
- Визначає шляхи до канонічних конфігураційних файлів для oxlint та knip за допомогою OXLINT_CANONICAL_JSON_PATH та KNIP_CANONICAL_JSON_PATH. Дозволяє перевіряти відповідність конфігураційного файлу .oxlintrc.json до канонічного файлу oxlint-canonical.json за допомогою verifyOxlintRcAgainstCanonical.
13
+ Модуль визначає шляхи до канонічних JSON-файлів для інструментів oxlint та knip через функції OXLINT_CANONICAL_JSON_PATH та KNIP_CANONICAL_JSON_PATH. Він також надає функцію verifyOxlintRcAgainstCanonical для валідації конфігурацій, перевіряючи, чи відповідає `.oxlintrc.json` правилам, визначеним у oxlint-canonical.json.
14
14
 
15
15
  ## Поведінка
16
16
 
17
- OXLINT_CANONICAL_JSON_PATH — Вказує шлях до канонічного JSON-файлу oxlint у цьому пакеті.
18
- KNIP_CANONICAL_JSON_PATH — Вказує шлях до канонічного JSON-файлу knip у цьому пакеті.
19
- verifyOxlintRcAgainstCanonical — Перевіряє конфігураційний файл `.oxlintrc.json` на відповідність канонічному файлу oxlint-canonical.json, виявляючи відхилення у правилах та інших полях.
17
+ OXLINT_CANONICAL_JSON_PATH — Вказує на шлях до канонічного JSON-файлу для oxlint у цьому пакеті.
18
+ KNIP_CANONICAL_JSON_PATH — Вказує на шлях до канонічного JSON-файлу для knip у цьому пакеті.
19
+ verifyOxlintRcAgainstCanonical — Перевіряє конфігурацію `.oxlintrc.json` на відповідність канонічному файлу oxlint-canonical.json, виявляючи відхилення у правилах та інших полях.
20
20
 
21
21
  ## Публічний API
22
22
 
23
- OXLINT_CANONICAL_JSON_PATH — Вказує розташування стандартного конфігураційного файлу oxlint для валідації.
24
- KNIP_CANONICAL_JSON_PATH — Вказує розташування стандартного конфігураційного файлу knip, який копіюється у кореневий каталог проєкту, якщо його там немає.
25
- verifyOxlintRcAgainstCanonical — Порівнює конфігураційний файл `.oxlintrc.json` з канонічним файлом пакета, вимагаючи збігу всіх полів, крім додаткових ключів у секції `rules`.
23
+ OXLINT_CANONICAL_JSON_PATH — вказує на файл з еталонними налаштуваннями oxlint у пакеті.
24
+ KNIP_CANONICAL_JSON_PATH — вказує на файл з еталонними налаштуваннями knip, який копіюється у корінь проєкту, якщо його там немає.
25
+ verifyOxlintRcAgainstCanonical — порівнює конфігураційний файл `.oxlintrc.json` з еталоном, перевіряючи, чи всі правила з еталону присутні, а інші поля збігаються з `oxlint-canonical.json`.
26
26
 
27
27
  ## Гарантії поведінки
28
28
 
@@ -3,210 +3,31 @@ type: JS Module
3
3
  title: utils_imports.mjs
4
4
  resource: npm/rules/js/js/utils_imports.mjs
5
5
  docgen:
6
- crc: 7eaeaf96
6
+ crc: 3fc9bf1b
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
7
9
  ---
8
10
 
9
- Модуль `npm/rules/js/js/utils_imports.mjs` реалізує одну з перевірок правила `js.mdc`: жоден файл усередині будь-якого каталогу з ім'ям `utils/` не має імпортувати щось за межами цього самого каталогу через відносні шляхи з префіксом `..`.
11
+ ## Огляд
10
12
 
11
- Філософія перевірки:
13
+ Модуль сканує файли у монорепозиторії. Він зчитує вміст JavaScript/TypeScript файлів та витягує всі рядкові імпорти. На основі конфігурації `.n-cursor.json` він перевіряє, чи не містять імпорти заборонених відносних шляхів, реєструючи відповідний статус у логіці (js.mdc). Публічна функція `check` виконує цю перевірку, свідомо пропускаючи шляхи `.git` та `node_modules`.
12
14
 
13
- - Каталог `utils/` за конвенцією тримає **generic helpers** — функції без бізнес-логіки, без знання про домен, без залежностей від конфігів конкретного проєкту.
14
- - Якщо файлу треба сусідній модуль (наприклад, `lib/foo.mjs` чи cross-rule helper) — він мусить переїхати у `lib/`, а не отримувати доступ через `../lib/foo.mjs`.
15
- - Дозволені імпорт-джерела: `./X`, `./sub/X` (свій каталог чи глибше), bare-package (`oxc-parser`, `@scope/pkg`), Node-builtin (`node:fs`, `fs`).
16
- - Заборонено будь-який `..`-шлях (`../X`, `../../X`, ...).
15
+ ## Поведінка
17
16
 
18
- Перевірка проходить по всьому monorepo: знаходить package-roots, у кожному рекурсивно шукає каталоги `utils/`, з кожного збирає не-тестові джерела (без `tests/` і `__fixtures__/`), парсить їх через `oxc-parser`, витягає всі імпорти (статичні, динамічні, `require(...)`) і логує fail-репорт для кожного імпорту з `..`-префіксом.
17
+ 1. Визначає корінь проекту.
18
+ 2. Зчитує список шляхів, які слід ігнорувати, на основі конфігурації .n-cursor.json.
19
+ 3. Визначає кореневі каталоги пакетів у монорепозиторії.
20
+ 4. Для кожного кореневого каталогу пакета рекурсивно шукає каталоги з назвою `utils`, ігноруючи типові артефакти (наприклад, node_modules, .git, dist).
21
+ 5. Якщо знайдено каталоги `utils`, для кожного з них рекурсивно збирає всі файли з розширеннями `.js`, `.jsx`, `.ts`, `.tsx`, які не є тестовими.
22
+ 6. Для кожного зібраного файлу зчитує його вміст.
23
+ 7. Витягує з вмісту файлу всі рядкові імпорти (статичні, динамічні та виклики `require`).
24
+ 8. Для кожного витягнутого імпорту перевіряє, чи відповідає він шаблону забороненого відносного шляху, що вказує на імпорт з іншого каталогу, який не є загальним.
25
+ 9. Якщо заборонений імпорт знайдено, реєструє помилку, посилаючись на файл та заборонений імпорт (js.mdc).
26
+ 10. Якщо жодних порушень не знайдено, реєструє успіх (js.mdc).
27
+ 11. Повертає код виходу, що відображає статус перевірки.
19
28
 
20
- Файл є точкою входу check-runner-а (CI-чи-локальний прогон): експортує одну async-функцію `check()`, яка повертає exit-code.
29
+ ## Гарантії поведінки
21
30
 
22
- ## Експорти / API
23
-
24
- | Експорт | Тип | Призначення |
25
- | ------- | ----------------------- | ----------------------------------------------------------------------------------------------------- |
26
- | `check` | `() => Promise<number>` | named export; запускає перевірку від `process.cwd()` і повертає `0` (OK) або `1` (знайдено порушення) |
27
-
28
- Усе інше — приватні helpers модуля без `export`.
29
-
30
- ## Функції
31
-
32
- ### `isIgnored(dir, ignorePaths)`
33
-
34
- Перевіряє, чи каталог входить у список ignore (точний збіг або префіксне співпадіння).
35
-
36
- - **Сигнатура:** `function isIgnored(dir: string, ignorePaths: string[]): boolean`
37
- - **Параметри:**
38
- - `dir` — абсолютний posix-шлях каталогу.
39
- - `ignorePaths` — масив абсолютних posix-шляхів, отриманих з `.n-cursor.json` через `loadCursorIgnorePaths`.
40
- - **Повертає:** `true`, якщо `dir` дорівнює якомусь елементу `ignorePaths` або починається з нього + `/`; інакше `false`.
41
- - **Side effects:** немає.
42
-
43
- ### `findUtilsDirs(root, ignorePosix)`
44
-
45
- Рекурсивно шукає всі каталоги з ім'ям `utils` під `root`.
46
-
47
- - **Сигнатура:** `async function findUtilsDirs(root: string, ignorePosix: string[]): Promise<string[]>`
48
- - **Параметри:**
49
- - `root` — абсолютний шлях кореня обходу (зазвичай корінь package).
50
- - `ignorePosix` — список абсолютних posix-шляхів, які пропускати.
51
- - **Повертає:** масив абсолютних шляхів знайдених `utils/`-каталогів. Порядок — результат DFS у тому ж порядку, в якому повертає `readdir`.
52
- - **Алгоритм:**
53
- - Вкладена рекурсивна функція `walk(dir)` читає `readdir(dir, { withFileTypes: true })`.
54
- - Помилка `readdir` (наприклад, нема прав чи каталог зник) проглинається через `try/catch` і дає ранній `return`.
55
- - Для кожного запису-каталогу:
56
- - якщо ім'я входить у `SKIP_DIR_NAMES` (`node_modules`, `.git`, `dist`, `coverage`, `.turbo`, `.next`, `__fixtures__`) — скіп;
57
- - повний шлях конвертується у posix і перевіряється через `isIgnored` — скіп якщо так;
58
- - якщо ім'я — рівно `utils`, додається у `found` і **не** заходить глибше (вкладені `utils/utils/` не очікуються; навіть якщо є — внутрішній `utils/` усе одно під самим `utils/` і його файли все одно пройдуть як файли зовнішнього `utils/`);
59
- - інакше — рекурсивно `walk(full)`.
60
- - **Side effects:** filesystem-чтення.
61
-
62
- ### `collectUtilsSources(utilsDir)`
63
-
64
- Збирає всі не-тестові source-файли під `utilsDir`.
65
-
66
- - **Сигнатура:** `async function collectUtilsSources(utilsDir: string): Promise<string[]>`
67
- - **Параметри:** `utilsDir` — абсолютний шлях каталогу `utils/`.
68
- - **Повертає:** масив абсолютних шляхів файлів-джерел.
69
- - **Фільтри:**
70
- - Каталоги `tests/`, `__fixtures__/` і будь-що з `SKIP_DIR_NAMES` — пропускаються (тести легально мають імпорти `../X` до свого модуля).
71
- - Файли мають матчити `JS_SOURCE_RE` (`.mjs`, `.mts`, `.cjs`, `.cts`, `.js`, `.ts`, `.jsx`, `.tsx`).
72
- - Файли, що матчать `TEST_FILE_RE` (`*.test.*`), — виключаються.
73
- - **Алгоритм:** аналогічний DFS через вкладену `walk(dir)` з тим самим проглинанням помилок `readdir`.
74
- - **Side effects:** filesystem-чтення.
75
-
76
- ### `extractImportSources(source, filePath)`
77
-
78
- Витягає всі рядкові імпорт-source з тексту файлу.
79
-
80
- - **Сигнатура:** `function extractImportSources(source: string, filePath: string): string[]`
81
- - **Параметри:**
82
- - `source` — текст файлу (UTF-8).
83
- - `filePath` — шлях до файлу, потрібен для визначення мови парсингу через `langFromPath`.
84
- - **Повертає:** масив рядків — значення source кожного імпорту в тому вигляді, в якому вони записані в коді (`'./foo'`, `'../bar'`, `'oxc-parser'`, ...).
85
- - **Що збирає:**
86
- - **Статичні імпорти** — з `parsed.module.staticImports[*].moduleRequest.value` (oxc-parser API).
87
- - **Динамічні імпорти** (`import('...')`) — через `dynamicImportModule(node)` під час обходу AST.
88
- - **CommonJS `require('...')`** — через `requireCallModule(node)`.
89
- - **Обробка помилок парсингу:** `try/catch` на `parseSync` повертає порожній масив і **не** падає, бо синтаксична помилка — окремий концерн іншої перевірки; ця має запуститись чисто і не блокувати решту.
90
- - **Side effects:** немає (виклик `parseSync` — CPU-only).
91
-
92
- ### `check()` (named export)
93
-
94
- Точка входу. Виконує всю перевірку від поточного робочого каталогу.
95
-
96
- - **Сигнатура:** `export async function check(): Promise<number>`
97
- - **Параметри:** немає; використовує `process.cwd()` як корінь monorepo.
98
- - **Повертає:** `0` — порушень немає; `1` — є хоча б одне (реальний exit-code обчислює `reporter.getExitCode()`).
99
- - **Покроковий алгоритм:**
100
- 1. Створити `reporter` через `createCheckReporter()`.
101
- 2. `root = process.cwd()`.
102
- 3. Завантажити `ignorePaths` з `.n-cursor.json` (`loadCursorIgnorePaths`) і перевести у posix-варіант (`ignorePosix`).
103
- 4. Отримати relative-paths package-roots monorepo через `getMonorepoPackageRootDirs(root)`.
104
- 5. Для кожного package-root знайти всі `utils/`-каталоги (`findUtilsDirs`) і покласти у `Set` (`utilsDirSet`) для де-дуплікації.
105
- 6. Якщо `utils/`-каталогів немає взагалі — `reporter.pass(...)` з повідомленням про пропуск і повернути exit-code.
106
- 7. Інакше пройти кожен `utils/`-каталог:
107
- - зібрати джерела (`collectUtilsSources`);
108
- - для кожного файлу прочитати контент, витягти імпорти (`extractImportSources`);
109
- - кожен import з префіксом `..` — `reporter.fail(...)` з relative-шляхом файлу та порушеним import-source, інкремент `violations`;
110
- - `checkedFiles` рахує всі перевірені файли.
111
- 8. Якщо `violations === 0` — `reporter.pass(...)` зі статистикою (кількість utils-каталогів і файлів).
112
- 9. Повернути `reporter.getExitCode()`.
113
- - **Side effects:**
114
- - filesystem-чтення (рекурсивне сканування + `readFile`);
115
- - запис у `reporter` (виводить рядки у stdout/stderr, залежно від реалізації);
116
- - читає `process.cwd()`.
117
-
118
- ## Залежності
119
-
120
- ### Node-builtin
121
-
122
- - `node:fs/promises` — `readdir`, `readFile`.
123
- - `node:path` — `join`, `relative`, `sep`.
124
-
125
- ### npm-пакет
126
-
127
- - `oxc-parser` — `parseSync` для парсингу JS/TS у AST з достовірною підтримкою сучасних синтаксисів (zero-config).
128
-
129
- ### Внутрішні модулі проєкту
130
-
131
- - `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера; має методи `pass`, `fail`, `getExitCode`. Уніфікований API для всіх check-функцій.
132
- - `../../../scripts/lib/load-cursor-config.mjs` → `loadCursorIgnorePaths` — читає `.n-cursor.json` (чи аналог) і повертає масив абсолютних шляхів, які треба пропустити.
133
- - `../../../scripts/lib/workspaces.mjs` → `getMonorepoPackageRootDirs` — повертає relative-paths коренів пакетів у monorepo (включно з `.`-коренем, якщо це теж пакет).
134
- - `../../../scripts/utils/ast-scan-utils.mjs`:
135
- - `langFromPath(filePath)` — мапить розширення файлу у `lang`-параметр для `oxc-parser`.
136
- - `walkAstWithAncestors(program, ancestors, visitor)` — обхід AST з трекінгом предків.
137
- - `dynamicImportModule(node)` — повертає рядок source для `import('...')`, або `null`.
138
- - `requireCallModule(node)` — повертає рядок source для `require('...')`, або `null`.
139
-
140
- ### Константи модуля
141
-
142
- | Ім'я | Значення | Призначення |
143
- | -------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
144
- | `JS_SOURCE_RE` | `/\.(?:[cm]?[jt]sx?)$/u` | матчить `.mjs`, `.mts`, `.cjs`, `.cts`, `.js`, `.ts`, `.jsx`, `.tsx` |
145
- | `TEST_FILE_RE` | `/\.test\.[cm]?[jt]sx?$/u` | матчить `*.test.{js,ts,...}` для виключення тестів |
146
- | `PARENT_RELATIVE_RE` | `/^\.\.(?:\/ | $)/u` | матчить `..` як цілий сегмент (`..` або `../*`); відсіює false-positive типу `..foo` |
147
- | `SKIP_DIR_NAMES` | `Set(['node_modules', '.git', 'dist', 'coverage', '.turbo', '.next', '__fixtures__'])` | каталоги, які скіпаємо при обходах |
148
-
149
- ## Потік виконання / Використання
150
-
151
- ### Інтеграція в перевірочний рантайм
152
-
153
- Модуль викликається check-runner-ом правила `js.mdc` (зазвичай із `npm/rules/js/js/`). Runner імпортує named export `check` і чекає на її resolved-значення як на process exit-code. Сам файл **не** має top-level executable коду — лише визначення; це дозволяє безпечно імпортувати його у тестах.
154
-
155
- Типовий виклик (псевдокод):
156
-
157
- ```mjs
158
- import { check } from './utils_imports.mjs'
159
-
160
- const exitCode = await check()
161
- process.exit(exitCode)
162
- ```
163
-
164
- ### Сценарій "усе чисто"
165
-
166
- 1. Runner запускається з кореня monorepo.
167
- 2. `check()` знаходить `utils/` каталоги в усіх package-roots.
168
- 3. Для кожного non-test source файлу витягає імпорти.
169
- 4. Жоден імпорт не починається з `..`.
170
- 5. `reporter.pass('utils-каталогів: N, перевірено M файлів — domain-bound імпортів немає (js.mdc)')`.
171
- 6. `getExitCode() → 0`.
172
-
173
- ### Сценарій "є порушення"
174
-
175
- 1. Знайдено файл `packages/foo/utils/helper.mjs`.
176
- 2. У ньому є `import bar from '../lib/bar.mjs'`.
177
- 3. `PARENT_RELATIVE_RE` матчить `../lib/bar.mjs`.
178
- 4. `reporter.fail('packages/foo/utils/helper.mjs: заборонений імпорт \'../lib/bar.mjs\' — utils/-файли мають бути generic (js.mdc)')`.
179
- 5. `violations` інкрементується.
180
- 6. По завершенню `getExitCode() → 1`.
181
-
182
- ### Сценарій "немає utils/"
183
-
184
- 1. У жодному package немає каталогу `utils/`.
185
- 2. `utilsDirSet.size === 0`.
186
- 3. `reporter.pass('utils-каталогів немає — перевірку пропущено (js.mdc)')`.
187
- 4. `getExitCode() → 0`.
188
-
189
- ### Сценарій "файл із синтаксичною помилкою"
190
-
191
- 1. `parseSync` кидає виключення.
192
- 2. `extractImportSources` ловить його у `try/catch` і повертає `[]`.
193
- 3. Цей файл не дає порушень. Проблему синтаксису ловить інша перевірка.
194
-
195
- ### Сценарій "ignore-шлях"
196
-
197
- 1. У `.n-cursor.json` зазначено абсолютний шлях, що покриває певний `utils/`-каталог.
198
- 2. `findUtilsDirs` через `isIgnored` пропускає його ще на стадії обходу — той `utils/` навіть не потрапляє у `utilsDirSet`.
199
-
200
- ### Особливості/edge cases
201
-
202
- - **Тести**: каталог `tests/` усередині `utils/` ігнорується повністю; також ігноруються файли `*.test.{js,ts,...}` будь-де всередині `utils/`. Це свідомо: тести легально імпортують свій модуль через `../X`.
203
- - **`__fixtures__/`**: ігнорується і в `findUtilsDirs`, і в `collectUtilsSources` — фікстури можуть бути будь-якими.
204
- - **Bare-imports** (`oxc-parser`, `node:fs`): не відсіюються спеціально, бо просто не матчать `PARENT_RELATIVE_RE`.
205
- - **Same-dir імпорти** (`./X`): дозволені автоматично з тієї ж причини.
206
- - **POSIX-шляхи для ignore**: під Windows `sep` — `\\`, тому шляхи нормалізуються у `/`-формат перед порівнянням з ignore-конфігом.
207
- - **De-duplication** через `Set`: якщо monorepo-структура повертає однаковий `utils/`-шлях двічі (наприклад, `.`-root і назва вкладеного пакета перетинаються), він обробиться лише раз.
208
- - **Помилки `readdir`** глушаться — недоступний каталог просто пропускається без падіння всієї перевірки.
209
-
210
- ### Залежність від конвенцій правила `js.mdc`
211
-
212
- Файл є технічною реалізацією одного з пунктів правила `js.mdc`. Усі повідомлення `reporter.pass/fail` посилаються на `(js.mdc)`, щоб користувач знав, де читати про сам принцип розділу `utils/` ↔ `lib/`.
31
+ - Read-only: не виконує операцій запису (ФС/БД).
32
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
33
+ - Свідомо пропускає шляхи: `.git`, `node_modules`.
@@ -6,9 +6,9 @@ resource: npm/rules/npm-module/js/
6
6
 
7
7
  # npm/rules/npm-module/js
8
8
 
9
- | Файл | Тип |
10
- | ----------------------------------------------- | --------- |
9
+ | Файл | Тип |
10
+ |---|---|
11
11
  | [header_doc_pointer.mjs](header_doc_pointer.md) | JS Module |
12
- | [package_structure.mjs](package_structure.md) | JS Module |
13
- | [rule_meta.mjs](rule_meta.md) | JS Module |
14
- | [skill_meta.mjs](skill_meta.md) | JS Module |
12
+ | [package_structure.mjs](package_structure.md) | JS Module |
13
+ | [rule_meta.mjs](rule_meta.md) | JS Module |
14
+ | [skill_meta.mjs](skill_meta.md) | JS Module |
@@ -3,31 +3,31 @@ type: JS Module
3
3
  title: rule_meta.mjs
4
4
  resource: npm/rules/npm-module/js/rule_meta.mjs
5
5
  docgen:
6
- crc: 938ccd0a
6
+ crc: 84394694
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль перевіряє конфігурацію правил, розташованих у каталозі `npm/rules`. Він забезпечує наявність обов'язкового файлу `scripts.mdc` для кожного правила. Крім того, він валідує структуру метаданих у `meta.json`, перевіряючи відповідність полів, таких як `auto` та `lint`, визначеним контрактам. У процесі перевірки використовуються маркери повідомлень (scripts.mdc).
13
+ Модуль перевіряє конфігурації правил, розташованих у каталозі `npm/rules`. Він гарантує, що кожен підкаталог правила містить необхідні файли, включаючи маркери повідомлень (`scripts.mdc`), та коректно структурований конфігураційний файл, що базується на `main.json` та `meta.json`. Перевірка включає валідацію визначених предикатів та експортованих функцій відповідно до очікуваного контракту.
14
14
 
15
15
  ## Поведінка
16
16
 
17
- 1. Викликати `check` для початку валідації.
18
- 2. Перевірити наявність каталогу `npm/rules` у корені репозиторію. Якщо каталог відсутній, валідація завершується успішно.
19
- 3. Для кожного підкаталогу у `npm/rules` (який представляє правило):
20
- а. Перевірити наявність файлу `auto.md`. Якщо він присутній, реєструється помилка, оскільки метадані тепер знаходяться у `meta.json`.
21
- б. Перевірити наявність файлу `<id>.mdc` у каталозі правила. Якщо він відсутній, реєструється помилка, оскільки це обов'язковий файл (scripts.mdc).
22
- в. Зчитати вміст `meta.json` правила. Якщо файл відсутній або невалідний, реєструється помилка, і перевірка цього правила припиняється.
23
- г. Перевірити поле `auto` у `meta.json`. Якщо поле `auto` присутнє, воно повинно бути валідним (відповідати одному з визначених форматів, або бути відсутнім). Якщо поле `auto` містить невідомий предикат, реєструється помилка.
24
- ґ. Перевірити поле `lint` у `meta.json`. Якщо поле `lint` присутнє, воно повинно бути валідним (відповідати "per-file" або "full"). Також перевіряється, чи експортує файл `main.mjs` у каталозі правила функцію `lint` відповідно до зазначеного значення `lint`.
25
- і. Якщо всі перевірки для правила пройшли успішно, реєструється повідомлення про валідність `meta.json`.
26
- 4. Після обробки всіх правил, повертається код виходу, що відображає загальний статус валідації.
17
+ 1. Перевіряє наявність каталогу `npm/rules` у корені репозиторію. Якщо каталог відсутній, завершує роботу, повідомляючи про відсутність правил для валідації.
18
+ 2. Ітерує по всім підкаталогах у `npm/rules`, ігноруючи приховані каталоги.
19
+ 3. Для кожного каталогу виконує перевірку правила:
20
+ а. Перевіряє відсутність файлу `auto.md`. Якщо знайдено, повідомляє про залишковий файл.
21
+ б. Перевіряє наявність файлу `main.mdc`. Якщо відсутній, повідомляє про відсутність обов'язкового файлу (scripts.mdc).
22
+ в. Зчитує вміст `main.json` каталогу правила. Якщо файл відсутній або невалідний, повідомляє про це та пропускає подальшу валідацію цього правила.
23
+ г. Перевіряє поле `auto` у `main.json`. Якщо поле присутнє, валідує його структуру та перевіряє, чи всі використані предикати визначені.
24
+ ґ. Перевіряє поле `lint` у `main.json`. Якщо поле присутнє, валідує його структуру та перевіряє, чи експортує файл `main.mjs` відповідну функцію `lint`.
25
+ і. Якщо всі перевірки для правила пройдені успішно, повідомляє про валідність `main.json`.
26
+ 4. Після обробки всіх правил повертає код виходу, що відображає загальний статус валідації.
27
27
 
28
28
  ## Публічний API
29
29
 
30
- check — перевіряє відповідність усіх файлів `npm/rules/<id>/meta.json` встановленим критеріям.
30
+ check — перевіряє відповідність усіх `npm/rules/<id>/meta.json` вимогам.
31
31
 
32
32
  ## Гарантії поведінки
33
33
 
@@ -3,24 +3,34 @@ type: JS Module
3
3
  title: skill_meta.mjs
4
4
  resource: npm/rules/npm-module/js/skill_meta.mjs
5
5
  docgen:
6
- crc: a069397b
6
+ crc: d02dd00d
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
7
8
  score: 100
8
9
  ---
9
10
 
10
- Перевірка стану конфігурації. Файл перевіряє відповідність між полями worktree та requireRoot. Перевірка спирається на конфіги meta.json.
11
+ ## Огляд
12
+
13
+ Перевіряє структуру та конфігурацію скілів у каталозі `npm/skills`, використовуючи правила, визначені в `meta.json`. Валідує, що кожен скіл не містить файлу `auto.md`. Перевіряє валідність полів `worktree`, `auto` та `requireRoot` у `main.json` кожного скіла.
11
14
 
12
15
  ## Поведінка
13
16
 
14
- 1. Перевірка поля worktree
15
- 2. Перевірка поля auto
16
- 3. Перевірка поля requireRoot
17
- 4. Перевірка суперечності between worktree та requireRoot
17
+ 1. Перевіряє наявність каталогу `npm/skills` у поточному робочому каталозі. Якщо каталог відсутній, операція завершується успішно.
18
+ 2. Ітерує по всіх підкаталогах у `npm/skills`.
19
+ 3. Для кожного підкаталогу виконується перевірка метаданих скіла:
20
+ а. Перевіряється наявність файлу `auto.md` у каталозі скіла. Якщо він присутній, це вважається порушенням.
21
+ б. Зчитується вміст `main.json` скіла. Якщо файл відсутній або невалідний, перевірка для цього скіла припиняється.
22
+ в. Виконується перевірка полів `main.json` скіла:
23
+ i. `worktree` має бути булевим значенням.
24
+ ii. Якщо поле `auto` визначене, його вміст має бути розпізнаним як "завжди" або непорожній масив правил.
25
+ iii. `requireRoot` має бути булевим значенням, якщо визначений.
26
+ iv. Якщо `worktree` встановлено як `true`, а `requireRoot` як `false`, це вважається порушенням.
27
+ г. Якщо всі поля `main.json` валідні, це вважається успішним результатом для скіла.
28
+ 4. Після перевірки всіх скілів повертається код виходу, що відображає загальний статус (0 — успіх, 1 — порушення).
18
29
 
19
30
  ## Публічний API
20
31
 
21
- check — Валідує всі `npm/skills/<id>/meta.json`.
32
+ check — перевіряє відповідність усіх файлів `meta.json` у каталозі `npm/skills/<id>/` заданим критеріям.
22
33
 
23
34
  ## Гарантії поведінки
24
35
 
25
- - Read-only: файл не виконує операцій запису у файлову систему.
26
- - Не звертається до мережі.
36
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -17,11 +17,11 @@ function checkAutoField(id, raw, reporter) {
17
17
  if (raw.auto === undefined) return true
18
18
  const spec = parseRuleAutoSpec(raw.auto)
19
19
  if (spec === null) {
20
- reporter.fail(`rules/${id}: meta.json.auto нерозпізнане (очікується "завжди" / масив / {glob} / {predicate})`)
20
+ reporter.fail(`rules/${id}: main.json.auto нерозпізнане (очікується "завжди" / масив / {glob} / {predicate})`)
21
21
  return false
22
22
  }
23
23
  if ('predicate' in spec && !Object.hasOwn(RULE_PREDICATES, spec.predicate)) {
24
- reporter.fail(`rules/${id}: невідомий predicate "${spec.predicate}" (немає в RULE_PREDICATES)`)
24
+ reporter.fail(`rules/${id}: main.json — невідомий predicate "${spec.predicate}" (немає в RULE_PREDICATES)`)
25
25
  return false
26
26
  }
27
27
  return true
@@ -38,7 +38,7 @@ function checkAutoField(id, raw, reporter) {
38
38
  function checkLintField(id, ruleDir, raw, reporter) {
39
39
  if (raw.lint === undefined) return true
40
40
  if (parseRuleLintSpec(raw.lint) === null) {
41
- reporter.fail(`rules/${id}: meta.json.lint нерозпізнане (очікується "per-file"|"full")`)
41
+ reporter.fail(`rules/${id}: main.json.lint нерозпізнане (очікується "per-file"|"full")`)
42
42
  return false
43
43
  }
44
44
  const mainPath = join(ruleDir, 'main.mjs')
@@ -63,19 +63,19 @@ function checkRule(id, ruleDir, reporter) {
63
63
  let ruleOk = true
64
64
 
65
65
  if (existsSync(join(ruleDir, 'auto.md'))) {
66
- reporter.fail(`rules/${id}: залишковий auto.md — видали (метадані тепер у meta.json)`)
66
+ reporter.fail(`rules/${id}: залишковий auto.md — видали (метадані тепер у main.json)`)
67
67
  ruleOk = false
68
68
  }
69
69
 
70
- // Канон (scripts.mdc): {rule}.mdc — ОБОВ'ЯЗКОВИЙ у кожному npm/rules/<id>/.
71
- if (!existsSync(join(ruleDir, `${id}.mdc`))) {
72
- reporter.fail(`rules/${id}: відсутній ${id}.mdc — обов'язковий (scripts.mdc)`)
70
+ // Канон (scripts.mdc): main.mdc — ОБОВ'ЯЗКОВИЙ у кожному npm/rules/<id>/.
71
+ if (!existsSync(join(ruleDir, 'main.mdc'))) {
72
+ reporter.fail(`rules/${id}: відсутній main.mdc — обов'язковий (scripts.mdc)`)
73
73
  ruleOk = false
74
74
  }
75
75
 
76
76
  const raw = readRuleMetaRaw(ruleDir)
77
77
  if (!raw) {
78
- reporter.fail(`rules/${id}: відсутній або невалідний meta.json`)
78
+ reporter.fail(`rules/${id}: відсутній або невалідний main.json`)
79
79
  return
80
80
  }
81
81
 
@@ -83,7 +83,7 @@ function checkRule(id, ruleDir, reporter) {
83
83
  if (!checkLintField(id, ruleDir, raw, reporter)) ruleOk = false
84
84
 
85
85
  if (ruleOk) {
86
- reporter.pass(`rules/${id}: meta.json валідний`)
86
+ reporter.pass(`rules/${id}: main.json валідний`)
87
87
  }
88
88
  }
89
89