@nitra/cursor 5.3.4 → 5.4.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.
Files changed (151) hide show
  1. package/.claude-template/settings.template.json +2 -2
  2. package/.pi-template/extensions/n-cursor-adr/docs/index.md +13 -24
  3. package/CHANGELOG.md +11 -0
  4. package/bin/n-cursor.js +43 -22
  5. package/lib/docs/models.md +29 -18
  6. package/lib/docs/omlx-trace.md +51 -0
  7. package/lib/docs/omlx.md +31 -15
  8. package/lib/omlx.mjs +2 -5
  9. package/package.json +1 -1
  10. package/rules/abie/docs/fix.md +17 -11
  11. package/rules/adr/docs/fix.md +25 -140
  12. package/rules/bun/docs/fix.md +18 -151
  13. package/rules/capacitor/docs/fix.md +16 -13
  14. package/rules/capacitor/js/docs/platforms.md +31 -43
  15. package/rules/changelog/docs/fix.md +25 -169
  16. package/rules/ci4/docs/fix.md +11 -14
  17. package/rules/doc-files/doc-files.mdc +60 -0
  18. package/rules/doc-files/docs/fix.md +31 -0
  19. package/rules/doc-files/fix.mjs +19 -0
  20. package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
  21. package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
  22. package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
  23. package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
  24. package/{skills → rules}/doc-files/js/docs/docgen-extract-anchors.md +1 -1
  25. package/{skills → rules}/doc-files/js/docs/docgen-extract.md +2 -2
  26. package/{skills → rules}/doc-files/js/docs/docgen-files-batch.md +1 -1
  27. package/{skills → rules}/doc-files/js/docs/docgen-gen.md +1 -1
  28. package/{skills → rules}/doc-files/js/docs/docgen-ignore.md +4 -4
  29. package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
  30. package/rules/doc-files/js/docs/docgen-scan.md +54 -0
  31. package/rules/doc-files/js/docs/lint.md +36 -0
  32. package/rules/doc-files/js/docs/units-js.md +31 -0
  33. package/rules/doc-files/js/docs/units-rs.md +35 -0
  34. package/rules/doc-files/js/docs/units.md +30 -0
  35. package/rules/doc-files/js/lint.mjs +96 -0
  36. package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
  37. package/rules/doc-files/lint/docs/lint.md +37 -0
  38. package/rules/doc-files/lint/lint.mjs +105 -0
  39. package/rules/doc-files/meta.json +1 -0
  40. package/rules/docker/docs/fix.md +21 -161
  41. package/rules/efes/docs/fix.md +23 -194
  42. package/rules/feedback/docs/fix.md +10 -8
  43. package/rules/ga/docs/fix.md +10 -5
  44. package/rules/graphql/docs/fix.md +23 -119
  45. package/rules/hasura/docs/fix.md +19 -5
  46. package/rules/hasura/js/docs/internal_urls.md +34 -307
  47. package/rules/image-avif/docs/fix.md +16 -127
  48. package/rules/image-compress/docs/fix.md +20 -141
  49. package/rules/image-compress/js/docs/package_setup.md +22 -182
  50. package/rules/js-bun-db/docs/fix.md +23 -139
  51. package/rules/js-bun-db/js/docs/safety.md +33 -221
  52. package/rules/js-bun-redis/docs/fix.md +25 -114
  53. package/rules/js-bun-redis/js/docs/imports.md +18 -166
  54. package/rules/js-lint/docs/fix.md +30 -108
  55. package/rules/js-lint/js/docs/lint-findings.md +37 -17
  56. package/rules/js-lint/js/docs/lint.md +22 -238
  57. package/rules/js-lint/js/docs/tooling.md +34 -331
  58. package/rules/js-lint-ci/docs/fix.md +16 -149
  59. package/rules/js-lint-ci/js/docs/lint.md +16 -136
  60. package/rules/js-mssql/docs/fix.md +18 -123
  61. package/rules/js-mssql/js/docs/deps.md +28 -251
  62. package/rules/js-run/docs/fix.md +23 -138
  63. package/rules/js-run/js/docs/runtime.md +24 -378
  64. package/rules/k8s/docs/fix.md +18 -123
  65. package/rules/nginx-default-tpl/docs/fix.md +22 -118
  66. package/rules/nginx-default-tpl/js/docs/template.md +38 -360
  67. package/rules/npm-module/docs/fix.md +27 -89
  68. package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
  69. package/rules/npm-module/js/docs/package_structure.md +36 -258
  70. package/rules/npm-module/js/docs/rule_meta.md +25 -127
  71. package/rules/npm-module/js/docs/skill_meta.md +18 -180
  72. package/rules/php/docs/fix.md +21 -98
  73. package/rules/php/js/docs/tooling.md +20 -143
  74. package/rules/python/docs/fix.md +25 -157
  75. package/rules/python/js/docs/applies.md +20 -98
  76. package/rules/python/js/docs/tooling.md +27 -144
  77. package/rules/rego/docs/fix.md +24 -112
  78. package/rules/rego/js/docs/applies.md +20 -164
  79. package/rules/rego/js/docs/lint.md +15 -110
  80. package/rules/release/docs/fix.md +16 -114
  81. package/rules/rust/docs/fix.md +24 -119
  82. package/rules/rust/js/docs/applies.md +20 -129
  83. package/rules/security/docs/fix.md +21 -78
  84. package/rules/security/js/docs/sample_secret.md +23 -182
  85. package/rules/security/js/docs/trufflehog.md +19 -128
  86. package/rules/style-lint/docs/fix.md +16 -150
  87. package/rules/style-lint/js/docs/lint.md +21 -172
  88. package/rules/style-lint/js/docs/tooling.md +19 -184
  89. package/rules/tauri/docs/fix.md +26 -152
  90. package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
  91. package/rules/tauri/js/docs/tooling.md +20 -217
  92. package/rules/test/docs/fix.md +19 -127
  93. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
  94. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
  95. package/rules/test/js/docs/cargo_mutants_config.md +24 -164
  96. package/rules/test/js/docs/location.md +24 -126
  97. package/rules/test/js/docs/no-process-chdir.md +20 -151
  98. package/rules/test/js/docs/no-relative-fs-path.md +24 -261
  99. package/rules/test/js/docs/stryker_config.md +48 -148
  100. package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
  101. package/rules/text/docs/fix.md +25 -113
  102. package/rules/text/js/docs/forbidden-prettier.md +21 -132
  103. package/rules/text/js/docs/formatting.md +60 -251
  104. package/rules/text/js/docs/lint.md +17 -114
  105. package/rules/vue/docs/fix.md +25 -118
  106. package/rules/vue/js/docs/packages.md +25 -323
  107. package/rules/worktree/docs/fix.md +31 -150
  108. package/scripts/coverage-classify/docs/index.md +23 -209
  109. package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
  110. package/scripts/dispatcher/docs/trace.md +35 -0
  111. package/scripts/docs/auto-rules.md +37 -361
  112. package/scripts/docs/lint-cli.md +12 -13
  113. package/scripts/docs/post-tool-use-fix.md +16 -15
  114. package/scripts/docs/skills-cli.md +26 -23
  115. package/scripts/docs/sync-claude-config.md +94 -34
  116. package/scripts/docs/worktree-cli.md +11 -34
  117. package/scripts/lib/docs/assert-project-root.md +14 -16
  118. package/scripts/lib/docs/changed-files.md +24 -139
  119. package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
  120. package/scripts/lib/docs/rule-predicates.md +20 -17
  121. package/scripts/lib/docs/run-rule-cli.md +14 -18
  122. package/scripts/lib/docs/run-rule.md +13 -20
  123. package/scripts/lib/docs/run-standard-rule.md +12 -15
  124. package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
  125. package/scripts/lib/rule-predicates.mjs +1 -1
  126. package/scripts/sync-claude-config.mjs +4 -1
  127. package/scripts/utils/docs/with-lock.md +19 -12
  128. package/scripts/utils/with-lock.mjs +4 -2
  129. package/skills/doc-aggregate/SKILL.md +2 -2
  130. package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
  131. package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
  132. package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
  133. package/skills/doc-files/.changes/260612-0031.md +5 -0
  134. package/skills/doc-files/.changes/260612-0036.md +5 -0
  135. package/skills/doc-files/.changes/260612-0114.md +5 -0
  136. package/skills/doc-files/SKILL.md +6 -6
  137. package/skills/fix/js/docs/llm-worker.md +17 -15
  138. package/skills/fix/js/docs/orchestrator.md +30 -23
  139. package/skills/fix/js/docs/t0.md +26 -16
  140. package/skills/start-check/js/docs/check.md +26 -22
  141. package/skills/taze/js/docs/diff.md +44 -20
  142. package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
  143. package/skills/doc-files/js/docs/docgen-scan.md +0 -25
  144. package/skills/doc-files/js/docs/units-rs.md +0 -35
  145. /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
  146. /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
  147. /package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +0 -0
  148. /package/{skills → rules}/doc-files/js/docgen-gen.mjs +0 -0
  149. /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
  150. /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
  151. /package/{skills → rules}/doc-files/js/units.mjs +0 -0
@@ -1,118 +1,23 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/rego/js/lint.mjs
4
+ crc: 8c033173
5
+ score: 100
6
+ ---
7
+
1
8
  # lint.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Файл `npm/rules/rego/js/lint.mjs` — це тонкий ESM-адаптер, що виконує роль CI-кроку (`lint`) для правила `rego` в монорепо. Він не містить власної логіки перевірки чи парсингу, а лише делегує виклик у вже існуючий CLI-модуль правила `../lint/lint.mjs`. Файл існує задля відповідності уніфікованому контракту CI-кроків (`lint(files?)`), де очікується експорт функції `lint` з певною сигнатурою.
6
-
7
- Ключова особливість: режим перевірки **per-file** для правила `rego` не підтримується — аналіз завжди виконується на всьому репозиторії (whole-repo). Тому параметр `files`, який зазвичай передається CI-фреймворком у крок `lint`, тут навмисно ігнорується (на що вказує префікс `_` у назві аргументу — `_files`). Це маркер для лінтерів та читачів коду, що значення параметра не використовується.
8
-
9
- Файл є частиною інфраструктури правил (`.cursor/rules/n-rego.mdc`, `.cursor/rules/n-ci4.mdc`) і служить мостом між уніфікованою CI-сигнатурою кроків та конкретною реалізацією перевірки Rego-файлів.
10
-
11
- ## Експорти / API
12
-
13
- Файл експортує одну іменовану асинхронну функцію:
14
-
15
- | Експорт | Тип | Призначення |
16
- | ------- | --------------------------------------------------- | ---------------------------------------------------- |
17
- | `lint` | `async function(files?: string[]): Promise<number>` | CI-крок для лінтингу Rego-файлів; повертає exit code |
18
-
19
- Default-експорт відсутній. Експорт іменований, що відповідає конвенції CI-кроків у проєкті (де runner імпортує саме `{ lint }`).
20
-
21
- ## Функції
22
-
23
- ### `lint(_files)`
24
-
25
- #### Сигнатура
26
-
27
- ```js
28
- export async function lint(_files)
29
- ```
30
-
31
- #### Параметри
32
-
33
- | Параметр | Тип | Обов'язковий | Опис |
34
- | -------- | ----------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
35
- | `_files` | `string[] \| undefined` | ні | Список файлів для перевірки. **Ігнорується** — `rego`-лінтер не має per-file режиму та виконує whole-repo аналіз. Префікс `_` сигналізує, що параметр свідомо не використовується. |
36
-
37
- #### Повертає
38
-
39
- `Promise<number>` — exit code від `runLintRego()`:
40
-
41
- - `0` — лінтинг пройшов без помилок;
42
- - ненульове значення — виявлено порушення або стався збій під час перевірки.
43
-
44
- Конкретні значення коду визначає реалізація `runLintRego` у `../lint/lint.mjs` — цей файл лише транслює його далі.
45
-
46
- #### Side effects
47
-
48
- Сама функція `lint` не має прямих побічних ефектів — вона не пише у файлову систему, не звертається до мережі, не модифікує глобальний стан і не виводить нічого у консоль. Усі побічні ефекти (виклики `opa`/`regal`, читання Rego-файлів, друк діагностики, можливі тимчасові файли тощо) реалізовані всередині `runLintRego` із сусіднього модуля `../lint/lint.mjs` та повністю інкапсульовані там.
49
-
50
- #### Винятки
51
-
52
- Функція не має власних `try`/`catch`. Якщо `runLintRego()` відхилить проміс (`reject`) або викине синхронну помилку, виняток прозоро прокинеться вгору до викликача (зазвичай — CI-runner, який очікує саме на exit code).
53
-
54
- ## Залежності
55
-
56
- ### Внутрішні (relative)
57
-
58
- | Імпорт | Шлях | Призначення |
59
- | ------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
60
- | `runLintRego` | `../lint/lint.mjs` | Реалізація whole-repo лінтингу Rego-файлів — фактично виконує перевірку та повертає exit code. Цей файл є єдиною залежністю модуля. |
61
-
62
- ### Зовнішні
63
-
64
- Зовнішніх npm-залежностей файл напряму не використовує. Усі сторонні інструменти (наприклад, `opa`, `regal` тощо) транзитивно підключаються через `runLintRego`.
65
-
66
- ### Runtime
67
-
68
- ESM-модуль (`.mjs`), потребує Node.js / Bun з підтримкою native ESM та `async/await`.
69
-
70
- ## Потік виконання / Використання
71
-
72
- ### Послідовність дій
73
-
74
- 1. CI-runner (наприклад, фреймворк CI-кроків `n-ci4`) виявляє файл як крок `lint` правила `rego`.
75
- 2. Runner викликає `lint(files)` — передає або список змінених файлів, або `undefined`, залежно від режиму запуску.
76
- 3. Функція ігнорує аргумент `_files` і одразу викликає `runLintRego()` без параметрів.
77
- 4. `runLintRego()` повертає `Promise<number>` із exit code; `lint` повертає цей самий проміс (через `return` в `async`-функції — фактично awaits та віддає значення).
78
- 5. Runner отримує exit code і інтерпретує його як результат CI-кроку.
79
-
80
- ### Контрактна позиція в системі правил
81
-
82
- Файл реалізує уніфікований інтерфейс CI-кроку `lint(files?)`, очікуваний фреймворком правил репозиторію (`n-ci4`). Завдяки тонкому шару адаптації:
83
-
84
- - сам runner може бути неуважним до особливостей правила (per-file vs whole-repo);
85
- - логіка перевірки залишається інкапсульованою у `../lint/lint.mjs` і може використовуватися як з CI, так і з CLI напряму;
86
- - зміна реалізації `runLintRego` не вимагає правок цього файла.
87
-
88
- ### Приклад використання
89
-
90
- ```js
91
- import { lint } from './npm/rules/rego/js/lint.mjs'
92
-
93
- // CI-режим: список файлів є, але буде проігнорований
94
- const exitCode = await lint(['policy/a.rego', 'policy/b.rego'])
95
- process.exit(exitCode)
96
-
97
- // Або без аргументів — поведінка ідентична
98
- const code2 = await lint()
99
- process.exit(code2)
100
- ```
101
-
102
- ### Що НЕ робить цей файл
12
+ Файл виконує передачу перевірок у наявні CLI правила. Функція повертає Promise з кодом виходу.
103
13
 
104
- - Не парсить аргументи командного рядка — це не CLI-entrypoint.
105
- - Не фільтрує файли за розширенням — фільтрація (за потреби) — справа `runLintRego`.
106
- - Не агрегує помилки кількох інструментів — повертає лише підсумковий exit code.
107
- - Не пише у `stdout`/`stderr` — увесь вивід походить із `runLintRego`.
14
+ ## Поведінка
108
15
 
109
- ## Rebuild Test
16
+ 1. lint приймає масив рядків або undefined
17
+ 2. lint делегує виконання у CLI правила
18
+ 3. lint повертає Promise з кодом виходу
110
19
 
111
- Документація достатня, щоб переписати файл з нуля без перегляду оригіналу:
20
+ ## Гарантії поведінки
112
21
 
113
- - Модуль ESM (`.mjs`).
114
- - Імпорт: `runLintRego` із `../lint/lint.mjs`.
115
- - Один іменований експорт — `async function lint(_files)`.
116
- - Тіло: `return runLintRego()` (виклик без аргументів).
117
- - JSDoc: параметр `_files` — `string[] | undefined`, описаний як ігнорований (whole-repo аналіз); повертає `Promise<number>` (exit code).
118
- - Коментар верхнього рівня: пояснює, що це CI-крок `rego`, делегує у CLI правила, per-file режиму немає, `files` ігнорується.
22
+ - Read-only: файл не виконує операцій запису у файлову систему.
23
+ - Не звертається до мережі.
@@ -1,128 +1,30 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/rules/release/fix.mjs
4
- crc: 0508fb5e
4
+ crc: 22936815
5
+ score: 100
5
6
  ---
6
7
 
7
- # fix.mjs — точка входу правила `release`
8
+ # fix.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Файл `npm/rules/release/fix.mjs` це **точка входу (entry-point)** для правила `release` у системі правил репозиторію. Він виконує дві ролі:
12
+ Файл ініціює виконання визначеного правила. Правило виконує необхідні дії з наданим контекстом. Виконане правило повертає отриманий результат.
12
13
 
13
- 1. **Library mode** — експортує асинхронну функцію `run(ctx)`, яку викликають інші скрипти/оркестратори через `import + run(ctx)`. Делегує виконання у стандартний раннер правил `runStandardRule`.
14
- 2. **CLI mode** — якщо файл запущено напряму як standalone-скрипт (`node fix.mjs` або через bun), він викликає `runRuleCli` й завершує процес кодом виходу (`process.exit`), щоб CI/IDE могли орієнтуватися на exit-code.
14
+ ## Поведінка
15
15
 
16
- Сам файл не містить жодної бізнес-логіки правила: всі перевірки (`applies → JS-concerns → policy → mdc-refs`) живуть у супровідних модулях каталогу `npm/rules/release/`, а оркестрацію виконує `runStandardRule`. Це — лише тонкий адаптер між іменем правила (визначається як ім'я каталогу через `import.meta.dirname`) і загальним механізмом запуску правил.
16
+ 1. Запуск правила.
17
+ 2. Виконання правила.
18
+ 3. Передача контексту прогону.
19
+ 4. Повернення результату.
17
20
 
18
- ## Експорти / API
21
+ ## Публічний API
19
22
 
20
- | Експорт | Тип | Призначення |
21
- | ------- | --------------------------------- | --------------------------------------------------------------------------------------- |
22
- | `run` | `function(ctx?): Promise<number>` | Library-mode запуск правила. Повертає exit-code: `0` — без порушень, `1` — є порушення. |
23
+ run запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
24
+ Library mode викликається CLI orchestration через `import + run`.
23
25
 
24
- Інших публічних експортів (типів, констант, default-експорту) файл не оголошує.
26
+ ## Гарантії поведінки
25
27
 
26
- ## Функції
27
-
28
- ### `run(ctx)`
29
-
30
- ```js
31
- /**
32
- *
33
- */
34
- export function run(ctx) {
35
- return runStandardRule(import.meta.dirname, ctx)
36
- }
37
- ```
38
-
39
- - **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
40
- - **Параметри:**
41
- - `ctx` (необов'язковий) — об'єкт типу `RuleContext`, імпортований із `../../scripts/lib/run-standard-rule.mjs`. Передається через виклик і несе спільний стан прогону (наприклад, `walkCache` для повторного використання обходу файлової системи між декількома правилами в одному прогоні). Якщо `ctx` не передано, стандартний раннер працює без зовнішнього кешу.
42
- - **Повертає:** `Promise<number>` — exit-code правила:
43
- - `0` — порушень не знайдено;
44
- - `1` — знайдені порушення (їх вже надруковано/зібрано раннером).
45
- - **Side effects:** Безпосередньо у тілі `run` сайд-ефектів немає — функція просто проксує виклик у `runStandardRule`. Усі реальні ефекти (читання файлів, обчислення `applies`, друк звітів, mdc-refs-перевірки) залежать від реалізації `runStandardRule` і відповідних check-модулів каталогу правила.
46
- - **Як визначає ім'я правила:** через `import.meta.dirname` — абсолютний шлях до каталогу `npm/rules/release/`. `runStandardRule` сам витягне з нього базове ім'я (`release`), знайде сусідні check-модулі (`check-*.mjs`, `applies.mjs`, `policy.*` тощо) й оркеструє конвеєр.
47
-
48
- ### CLI-блок (модульний top-level код)
49
-
50
- ```js
51
- if (isRunAsCli(import.meta.url)) {
52
- // eslint-disable-next-line n/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
53
- process.exit(await runRuleCli(import.meta.dirname))
54
- }
55
- ```
56
-
57
- - **Не є функцією**, але це частина public-API файлу як CLI-скрипта.
58
- - **Умова виконання:** `isRunAsCli(import.meta.url)` повертає `true` лише коли файл є точкою входу процесу (а не імпортований як модуль). Це класичний еквівалент Node-патерна `require.main === module` для ESM.
59
- - **Дія:** Дочекатися `runRuleCli(import.meta.dirname)` (top-level `await`) і завершити процес із отриманим exit-code через `process.exit`.
60
- - **ESLint:** Спеціально дозволено `n/no-process-exit` і `unicorn/no-process-exit` — standalone-entry-point має повертати CI-сумісний код.
61
- - **Side effects:** Завершує Node-процес. Через top-level `await` блокує закриття модульного завантаження, поки CLI-прогін не завершиться.
62
-
63
- ## Залежності
64
-
65
- Файл імпортує **дві** утиліти з локальної бібліотеки скриптів репозиторію (відносні шляхи до `npm/scripts/lib/`):
66
-
67
- - `../../scripts/lib/run-rule-cli.mjs`
68
- - **`isRunAsCli(metaUrl: string): boolean`** — перевіряє, чи модуль викликано як CLI, а не як `import`.
69
- - **`runRuleCli(ruleDir: string): Promise<number>`** — CLI-обгортка над раннером: парсить аргументи, налаштовує оточення прогону як standalone і повертає exit-code.
70
- - `../../scripts/lib/run-standard-rule.mjs`
71
- - **`runStandardRule(ruleDir: string, ctx?: RuleContext): Promise<number>`** — стандартний конвеєр правила: дізнається, до яких файлів воно застосовується (`applies`), запускає JS-concerns (зазвичай файли `check-*.mjs`), policy-перевірки і `mdc-refs` (узгодженість з `.mdc`-документами), збирає й виводить порушення.
72
- - **Тип `RuleContext`** — структура контексту прогону. Цей файл лише re-references його в JSDoc-`@param`.
73
-
74
- Жодних інших імпортів (зовнішніх npm-пакетів, Node core-модулів, динамічних `import()`) немає. Глобально використовується лише `process` (Node-built-in) — у CLI-блоці для `process.exit`.
75
-
76
- ## Потік виконання / Використання
77
-
78
- ### Library mode (виклик з іншого модуля)
79
-
80
- ```js
81
- import { run } from './npm/rules/release/fix.mjs'
82
-
83
- const exitCode = await run(ctx) // ctx — опційний
84
- if (exitCode !== 0) {
85
- // знайдено порушення правила release
86
- }
87
- ```
88
-
89
- Послідовність:
90
-
91
- 1. Викликач робить `import { run } from '.../release/fix.mjs'`.
92
- 2. Виклик `run(ctx)` → `runStandardRule(import.meta.dirname, ctx)`.
93
- 3. `runStandardRule` визначає каталог правила (`release`), знаходить і запускає сусідні модулі правила (`applies` → JS-concerns → policy → mdc-refs), обмінюючись із викликачем кешем через `ctx` (за наявності).
94
- 4. Повертається числовий exit-code (`0`/`1`).
95
-
96
- ### CLI mode (запуск файлу як скрипта)
97
-
98
- ```bash
99
- node npm/rules/release/fix.mjs
100
- # або через bun
101
- bun run npm/rules/release/fix.mjs
102
- ```
103
-
104
- Послідовність:
105
-
106
- 1. Node/Bun стартує файл як точку входу — `isRunAsCli(import.meta.url)` повертає `true`.
107
- 2. `await runRuleCli(import.meta.dirname)` запускає CLI-обгортку правила: парсить можливі аргументи/прапорці, ініціалізує стандартне середовище правила, всередині сам викликає аналог `runStandardRule` і повертає exit-code.
108
- 3. `process.exit(<exitCode>)` завершує процес: CI-конвеєр або IDE-runner отримує `0` (успіх) або `1` (порушення).
109
-
110
- ### Типове місце у системі правил
111
-
112
- Файл є членом сім'ї однотипних entry-point'ів `npm/rules/<rule-name>/fix.mjs`: кожне правило репозиторію має такий-самий шаблон («тонкий fix.mjs + сусідні check-модулі»). Це уніфікує запуск як з оркестратора (`bun run lint`, агрегатори, `runStandardRule`-цикли), так і з окремих CI-кроків чи дебагу через IDE.
113
-
114
- ### Контракт повернення (exit-code)
115
-
116
- | Значення | Семантика |
117
- | -------- | ------------------------------------------------------------------------- |
118
- | `0` | Правило `release` не знайшло порушень для файлів, до яких воно `applies`. |
119
- | `1` | Принаймні одне порушення (вже зафіксоване й виведене раннером). |
120
-
121
- Інших кодів файл не вводить — будь-яка деталізація залежить від `runStandardRule` / `runRuleCli`.
122
-
123
- ## Примітки щодо реалізації
124
-
125
- - **Чому `import.meta.dirname`, а не явне ім'я правила:** Це дає змогу шаблону `fix.mjs` бути ідентичним для всіх правил без захардкоджування рядкового імені — раннер сам ідентифікує правило за каталогом.
126
- - **Чому `await` на top-level:** Файл — ESM (`.mjs`), top-level `await` дозволений. У CLI-режимі потрібен синхронно-доступний exit-code до виклику `process.exit`.
127
- - **Чому виключені два ESLint-правила:** Обидва (`n/no-process-exit`, `unicorn/no-process-exit`) у проєкті заборонені для бібліотечного коду, але для standalone-entry-points exit-code — це і є контракт. Інлайн-коментар із поясненням обов'язковий за стилем репозиторію.
128
- - **Що файл свідомо не робить:** не парсить CLI-аргументи самостійно, не читає файли, не звертається до мережі, не імпортує бізнес-логіку правила напряму — все це делеговано в `run-standard-rule.mjs` та `run-rule-cli.mjs`.
28
+ - Read-only: файл не виконує операцій запису у файлову систему.
29
+ - Кешує результати в межах одного прогону.
30
+ - Не звертається до мережі.
@@ -1,129 +1,34 @@
1
- # `fix.mjs` — entry-point правила `rust`
1
+ ---
2
+ docgen:
3
+ source: npm/rules/rust/fix.mjs
4
+ crc: 38cf876b
5
+ score: 100
6
+ ---
2
7
 
3
- ## Огляд
4
-
5
- Файл `npm/rules/rust/fix.mjs` — мінімальний adapter, який реєструє правило `rust` у двох ролях одночасно:
6
-
7
- - **library mode** — модуль експортує функцію `run(ctx)`, яку викликає CLI-оркестратор пакета `@nitra/cursor` (через `import + run(ctx)`), передаючи спільний контекст прогону (наприклад, `walkCache` для шерингу обходу файлів між правилами).
8
- - **standalone mode** — якщо файл запущено напряму (`bun npm/rules/rust/fix.mjs`), він поводиться як повний еквівалент команди `npx @nitra/cursor fix rust`: підвантажує конфіг, застосовує whitelist, друкує summary та повертає процесу exit-code.
9
-
10
- Уся реальна логіка правила (порядок фаз: `applies → JS-concerns → policy → mdc-refs`) інкапсульована у двох helper-модулях зі спільної бібліотеки `npm/scripts/lib/`. Цей файл — лише тонкий wrapper, що з'єднує конвенцію розташування (`npm/rules/<id>/fix.mjs`) із цими helpers і не містить власної бізнес-логіки правила `rust`.
11
-
12
- Файл слідує усталеному в репозиторії патерну "двох ролей `fix.mjs`": library + standalone — тому самий код використовується і коли правило виконується як частина мульти-rule прогону, і коли його запускають окремо для дебагу/CI.
13
-
14
- ## Експорти / API
15
-
16
- Модуль експортує одну іменовану функцію:
17
-
18
- | Експорт | Тип | Призначення |
19
- | ------- | ---------------------------------------- | ------------------------------------------------------------------ |
20
- | `run` | `(ctx?: RuleContext) => Promise<number>` | Library-mode entry: запуск правила `rust` зі стандартним pipeline. |
21
-
22
- Default-експорту немає. Імпортний шлях для зовнішніх споживачів — `@nitra/cursor/rules/rust/fix.mjs` (або еквівалентний relative-шлях усередині монорепо).
23
-
24
- Тип `RuleContext` визначений у `npm/scripts/lib/run-standard-rule.mjs` і реекспортується через JSDoc-`import('...')`-тип у сигнатурі `run`.
25
-
26
- ## Функції
27
-
28
- ### `run(ctx)`
29
-
30
- ```js
31
- export function run(ctx)
32
- ```
33
-
34
- - **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
35
- - **Параметри:**
36
- - `ctx` — _(опційний)_ контекст прогону, який передає CLI-оркестратор. Структура задана в `run-standard-rule.mjs` (`RuleContext`); типове поле — `walkCache`, що дозволяє декільком правилам розділяти один обхід файлової системи в межах однієї сесії. Якщо `ctx` не передано (наприклад, у standalone), `runStandardRule` сам ініціалізує внутрішні структури.
37
- - **Повертає:** `Promise<number>`
38
- - `0` — правило завершилось успішно, порушень не знайдено.
39
- - `1` — знайдено порушення (стандартний exit-code для CI/IDE).
40
- - **Алгоритм:** делегує виконання у `runStandardRule(import.meta.dirname, ctx)`. Перший аргумент — абсолютний шлях до каталогу правила (`npm/rules/rust/`), завдяки якому `runStandardRule` сам читає `meta.json`, виявляє підкаталоги `js/`, `policy/`, `coverage/`, `lib/` і відповідний `.mdc`-файл (`rust.mdc`) для розв'язання refs.
41
- - **Side effects:**
42
- - Власних side effects не має; усі ефекти (I/O, лог, walk-cache) виникають усередині `runStandardRule`.
43
- - Не модифікує `process.exit`, не пише в `process.stderr/stdout` напряму — це робить уже helper або стандартний CLI summary.
8
+ # fix.mjs
44
9
 
45
- ### Standalone entry-block
46
-
47
- ```js
48
- if (isRunAsCli(import.meta.url)) {
49
- process.exit(await runRuleCli(import.meta.dirname))
50
- }
51
- ```
52
-
53
- - **Тип:** top-level side-effect блок (виконується при імпорті модуля).
54
- - **Умова входу:** `isRunAsCli(import.meta.url)` повертає `true`, тобто файл виконано як головний модуль (`bun fix.mjs` / `node fix.mjs`), а не імпортовано з іншого модуля.
55
- - **Що робить:** викликає `runRuleCli(import.meta.dirname)` — повний CLI-pipeline пакета `@nitra/cursor` для одного правила: завантаження конфіга, застосування whitelist, друк summary, повернення числового exit-code. Результат передається у `process.exit(...)`, щоб процес завершився з відповідним кодом для CI/IDE.
56
- - **Чому два eslint-disable:**
57
- - `n/no-process-exit` (плагін `eslint-plugin-n`) — забороняє виклик `process.exit` у бібліотечному коді.
58
- - `unicorn/no-process-exit` (плагін `eslint-plugin-unicorn`) — теж забороняє `process.exit`.
59
- Тут вони відключені свідомо: standalone entry-point має повертати exit-code, інакше неможливо коректно інтегруватися з CI/IDE runners (вони чекають саме на код виходу процесу).
60
- - **Side effects:** завершує процес викликом `process.exit(code)`.
61
-
62
- ## Залежності
63
-
64
- ### Внутрішні (relative imports)
65
-
66
- | Шлях | Що використовується | Роль |
67
- | ----------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
68
- | `../../scripts/lib/run-rule-cli.mjs` | `isRunAsCli`, `runRuleCli` | Helpers для standalone-режиму: детекція "запущено як CLI" та повний CLI-pipeline одного правила. |
69
- | `../../scripts/lib/run-standard-rule.mjs` | `runStandardRule` | Стандартний рантайм правила: оркестрація фаз `applies → JS-concerns → policy → mdc-refs`. JSDoc-тип `RuleContext` теж імпортується звідси. |
70
-
71
- ### Зовнішні
72
-
73
- Прямих залежностей від npm-пакетів немає. Усі external-залежності (наприклад, `fast-glob`, ESLint API тощо) інкапсульовані всередині `runStandardRule` / `runRuleCli` і сюди не "протікають".
74
-
75
- ### Runtime/Node API
76
-
77
- - `import.meta.dirname` — стандартний Node.js / Bun API; використовується для передачі абсолютного шляху до каталогу правила в helpers.
78
- - `import.meta.url` — використовується `isRunAsCli` для порівняння з `process.argv[1]`.
79
- - `process.exit(code)` — завершення процесу в standalone-режимі.
80
- - `await` на top level — потребує Node ≥ 14.8 (ESM top-level await) або Bun (підтримує з коробки).
81
-
82
- ### Конвенції розташування
83
-
84
- Файл лежить за конвенцією `npm/rules/<id>/fix.mjs`, де `<id> = rust`. Поряд із ним мають існувати:
85
-
86
- - `meta.json` — метадані правила (читається `runStandardRule`/`runRuleCli`).
87
- - `rust.mdc` — людинозрозумілий опис правила (для mdc-refs).
88
- - Підкаталоги `js/`, `policy/`, `coverage/`, `lib/` — фази правила.
89
- - `docs/` — каталог із згенерованою документацією (включно з цим файлом).
90
-
91
- ## Потік виконання / Використання
10
+ ## Огляд
92
11
 
93
- ### Сценарій A: виклик з CLI-оркестратора (library mode)
12
+ Огляд
13
+ Файл надає механізм для виконання стандартних правил. Використовується для запуску правил через функцію runStandardRule та для запуску правил у режимі командного рядка через runRuleCli.
94
14
 
95
- 1. Оркестратор `@nitra/cursor` сканує `npm/rules/*/fix.mjs`.
96
- 2. Для правила `rust` виконує `import('npm/rules/rust/fix.mjs')`.
97
- 3. Викликає `run(ctx)`, передаючи спільний `RuleContext` (включно з `walkCache`).
98
- 4. `run` повертає `runStandardRule(import.meta.dirname, ctx)`, який послідовно виконує фази:
99
- - **applies** — фільтрує файли, до яких правило застосовне.
100
- - **JS-concerns** — запускає JS-аспекти правила (`js/`-фолдер).
101
- - **policy** — застосовує policy-checks (`policy/`-фолдер).
102
- - **mdc-refs** — валідує посилання в `rust.mdc`.
103
- 5. Результуючий `Promise<number>` (`0` або `1`) повертається оркестратору.
104
- 6. Оркестратор агрегує exit-коди всіх правил і повертає єдиний summary.
15
+ ## Поведінка
105
16
 
106
- ### Сценарій B: standalone-запуск
17
+ 1. Запуск правила.
18
+ * Виклик runStandardRule з контекстом.
19
+ * Повернення результату.
107
20
 
108
- 1. Користувач/CI виконує `bun npm/rules/rust/fix.mjs` (або `node npm/rules/rust/fix.mjs`).
109
- 2. Модуль завантажується; `isRunAsCli(import.meta.url)` повертає `true`.
110
- 3. Виконується `await runRuleCli(import.meta.dirname)`:
111
- - читає конфіг проєкту,
112
- - застосовує whitelist шляхів,
113
- - усередині сам викликає `runStandardRule` (або еквівалент),
114
- - друкує summary в stdout.
115
- 4. Отриманий числовий exit-code передається в `process.exit(code)`.
116
- 5. Процес завершується кодом `0` (ok) або `1` (порушення) — CI/IDE підхоплюють статус.
21
+ 2. Запуск у режимі CLI.
22
+ * Виклик runRuleCli з директорією.
23
+ * Вихід з процесом залежно від результату.
117
24
 
118
- ### Як додавати/змінювати поведінку
25
+ ## Публічний API
119
26
 
120
- - **НЕ** додавати бізнес-логіку правила прямо в цей файл він має лишатись тонким wrapper'ом.
121
- - Зміни порядку фаз або їх складу — у `runStandardRule` (спільно для всіх стандартних правил).
122
- - Зміни CLI-флагів / summary / whitelist — у `runRuleCli`.
123
- - Зміни специфічні для правила `rust` — у відповідних підкаталогах (`js/`, `policy/`, `coverage/`, `lib/`) і файлі `rust.mdc`.
27
+ run запускає правило: applies JS-concerns policy mdc-refs (через runStandardRule).
28
+ Library mode викликається CLI orchestration через `import + run`.
124
29
 
125
- ### Контракт із оркестратором
30
+ ## Гарантії поведінки
126
31
 
127
- - Експорт `run` повинен бути **функцією** (не stream/generator) і повертати `Promise<number>`.
128
- - Не повинен викидати unhandled rejections — усі помилки обгортаються всередині `runStandardRule`.
129
- - Exit-коди суворо `0` або `1` (інші значення оркестратор може інтерпретувати як збій).
32
+ - Read-only: файл не виконує операцій запису у файлову систему.
33
+ - Кешує результати в межах одного прогону.
34
+ - Не звертається до мережі.
@@ -1,140 +1,31 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/rust/js/applies.mjs
4
+ crc: 4cc601f5
5
+ score: 100
6
+ ---
7
+
1
8
  # applies.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль `applies.mjs` реалізує **applies-гейт** для правила `rust` у системі правил `n-cursor`. Його завдання — швидко відповісти на питання: «чи має взагалі сенс прогонити це правило в поточному репозиторії?». Якщо репозиторій не містить жодного Rust-кореня (тобто немає `Cargo.toml` ані в корені, ані в жодному вкладеному робочому каталозі), функція повертає `false`, і ранер `runStandardRule` пропускає всі концерни цього правила — як JS-перевірки, так і policy-концерни. Це уникає зайвої роботи в репозиторіях без Rust-коду.
6
-
7
- Маркером застосовності є файл `Cargo.toml`:
8
-
9
- - спершу швидка перевірка в `cwd` через `existsSync` (синхронно, без I/O-обходу);
10
- - якщо в корені маркера немає — рекурсивний обхід дерева через `hasCargoTomlInTree`, який ігнорує штучні / службові директорії (`node_modules`, `.git`, `.next`, `.turbo`).
11
-
12
- Окремо експортується функція `check()` — це **context-pass** репортер: коли applies повернув `true`, ранер усе одно очікує, що файл правила розрукує хоча б один контекст. `check()` просто друкує повідомлення «знайдено Cargo.toml — застосовуємо правила rust.mdc» і повертає exit-код `0`. Жодної реальної логіки лінтування / перевірок у цьому файлі немає — вся робота винесена в **policy-концерни** правила `rust`.
13
-
14
- Файл написаний у форматі ESM (`.mjs`) та сумісний з Bun і Node.js (≥ модулів з підтримкою ESM та `node:` префіксу).
15
-
16
- ## Експорти / API
17
-
18
- | Експорт | Тип | Призначення |
19
- | --------- | ------------------------------------ | ------------------------------------------------------------------------ |
20
- | `applies` | `(cwd?: string) => Promise<boolean>` | Гейт-функція: чи активувати правило `rust` для заданого `cwd`. |
21
- | `check` | `() => number` | Context-pass репортер: друкує позитивне повідомлення, повертає exit-код. |
22
-
23
- Інших публічних експортів немає. Константа `IGNORED_DIR_NAMES` — внутрішня (module-level), назовні не експортується.
24
-
25
- ## Функції
26
-
27
- ### `applies(cwd = process.cwd())`
28
-
29
- **Сигнатура:** `applies(cwd?: string): Promise<boolean>`
30
-
31
- **Параметри:**
32
-
33
- - `cwd` _(string, опційний)_ — абсолютний (або відносний від процесу) шлях до кореня репозиторію, який треба перевірити. За замовчуванням — `process.cwd()` (поточний робочий каталог процесу Node/Bun).
34
-
35
- **Повертає:** `Promise<boolean>`
36
-
37
- - `true` — правило `rust` застосовне (знайдено хоча б один `Cargo.toml` у корені або десь у дереві);
38
- - `false` — застосовувати правило не треба (Rust у репозиторії не знайдено).
39
-
40
- **Алгоритм:**
41
-
42
- 1. Складає шлях `join(cwd, 'Cargo.toml')` і синхронно перевіряє його існування через `existsSync`.
43
- 2. Якщо файл є — одразу повертає `Promise.resolve(true)` (швидкий вихід; решта дерева не сканується).
44
- 3. Якщо в корені маркера немає — викликає `hasCargoTomlInTree(cwd, IGNORED_DIR_NAMES)` і повертає його результат, загорнутий у промісі (значення може бути проміс або bool — у будь-якому разі `Promise.resolve` нормалізує до `Promise<boolean>`).
45
-
46
- **Side effects:**
47
-
48
- - Один синхронний виклик `existsSync` (file-system stat) для шляху `<cwd>/Cargo.toml`.
49
- - За потреби — рекурсивний обхід директорії `cwd` (виконує `hasCargoTomlInTree`); у межах цього обходу директорії з `IGNORED_DIR_NAMES` пропускаються.
50
- - Не модифікує файлову систему, не пише в `stdout`/`stderr`, не виконує мережевих запитів.
51
-
52
- **Не кидає винятків** у нормальних умовах: `existsSync` повертає `false` для неіснуючих/недоступних шляхів. Виняткові ситуації можуть прилетіти лише з глибин `hasCargoTomlInTree` (наприклад, помилка `readdir`), але це поведінка залежного модуля, а не самого `applies`.
53
-
54
- ### `check()`
55
-
56
- **Сигнатура:** `check(): number`
57
-
58
- **Параметри:** немає.
59
-
60
- **Повертає:** `number` — exit-код:
61
-
62
- - `0` — все OK (стандартний шлях; функція завжди йде цим шляхом, бо вона лише друкує `pass`);
63
- - `1` — порушення (теоретично можливо, якщо репортер у майбутньому почне накопичувати помилки; зараз цей кейс не використовується).
64
-
65
- **Алгоритм:**
66
-
67
- 1. Створює інстанс репортера через `createCheckReporter()`.
68
- 2. Викликає `reporter.pass('Знайдено Cargo.toml — застосовуємо правила rust.mdc')` — реєструє позитивний context-pass.
69
- 3. Повертає `reporter.getExitCode()`.
70
-
71
- **Side effects:**
72
-
73
- - Друкує повідомлення про `pass` у stdout у форматі, заданому `createCheckReporter` (зазвичай — рядок з префіксом / маркером).
74
- - Не торкається файлової системи й мережі.
75
-
76
- **Контракт із ранером:** `runStandardRule` викликає `check()` лише після того, як `applies()` повернув `true`. Тому повідомлення в стилі «знайдено Cargo.toml» завжди коректне на момент друку — applies-гейт уже відпрацював перед цим.
77
-
78
- ## Залежності
79
-
80
- ### Зовнішні (стандартна бібліотека Node.js)
81
-
82
- - `node:fs` → `existsSync` — синхронна перевірка існування файлу.
83
- - `node:path` → `join` — крос-платформне склеювання сегментів шляху.
84
-
85
- ### Внутрішні (відносні до файлу)
86
-
87
- - `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера для context-pass / помилок із підрахунком exit-коду.
88
- - `../lib/has-cargo-toml.mjs` → `hasCargoTomlInTree` — рекурсивний обхід дерева директорій з пошуком `Cargo.toml` і пропуском ігнор-папок.
89
-
90
- ### Module-level константи
91
-
92
- - `IGNORED_DIR_NAMES: Set<string>` — `{ 'node_modules', '.git', '.next', '.turbo' }`. Передається в `hasCargoTomlInTree` як набір імен директорій, у які заходити не треба під час рекурсивного пошуку.
93
-
94
- ## Потік виконання / Використання
95
-
96
- ### Типовий сценарій (ранер правил)
97
-
98
- 1. `runStandardRule` для правила `rust` спершу імпортує модуль `applies.mjs`.
99
- 2. Викликає `await applies()` (без аргументів — буде використано `process.cwd()`).
100
- 3. Якщо результат `false` — ранер пропускає правило цілком: ні JS-концерни (`check`), ні policy-концерни не виконуються; правило вважається «not applicable».
101
- 4. Якщо результат `true` — ранер послідовно виконує всі концерни правила:
102
- - викликає експортований `check()` як «context-pass» — щоб у звіті був видимий маркер «правило застосовано»;
103
- - запускає policy-концерни (фактичні перевірки коду / структури), які живуть в інших файлах модуля `rust`.
104
-
105
- ### Приклад прямого виклику
106
-
107
- ```js
108
- import { applies, check } from './npm/rules/rust/js/applies.mjs'
109
-
110
- const ok = await applies('/path/to/some/repo')
111
- if (ok) {
112
- const code = check()
113
- process.exit(code)
114
- }
115
- ```
12
+ Огляд
13
+ Файл виконує перевірку наявності файлу Cargo.toml у кореневому репозиторії та підкаталогах. Функція check генерує звіт про порушення конфігураційних правил.
116
14
 
117
- ### Ребра (edge cases)
15
+ ## Поведінка
118
16
 
119
- - **`cwd` не існує / недоступний:** `existsSync` поверне `false`; далі `hasCargoTomlInTree` обходитиме неіснуючий шлях (поведінка визначається ним).
120
- - **`Cargo.toml` лежить глибоко під ігнор-папкою** (наприклад, всередині `node_modules/.../Cargo.toml`): його **не** знайдуть `IGNORED_DIR_NAMES` свідомо пропускає такі директорії, бо це не «справжній» Rust-корінь репозиторію.
121
- - **`Cargo.toml` у корені `cwd`:** виконується лише `existsSync` — рекурсивний обхід не запускається (оптимізація).
122
- - **Множинні `Cargo.toml` глибоко в дереві:** достатньо знайти хоча б один — `hasCargoTomlInTree` має повернути `true` при першому ж збігу.
17
+ applies
18
+ Перевіряє наявність Cargo.toml у корені репозиторію або в його підкаталогах, і повертає булеве значення.
123
19
 
124
- ### Інваріанти
20
+ check
21
+ Генерує звіт про застосування правил і повертає код виходу.
125
22
 
126
- - `applies()` завжди повертає `Promise<boolean>` — навіть для синхронного fast-path через `Promise.resolve(true)`.
127
- - `check()` синхронна — не повертає Promise; завжди повертає число (exit-код).
128
- - `applies()` ідемпотентна та не має станy між викликами (немає кешу).
23
+ ## Публічний API
129
24
 
130
- ## Rebuild Test
25
+ applies формує файл
131
26
 
132
- Якщо видалити файл `applies.mjs` і відновлювати його з нуля по цій документації, реалізація має:
27
+ ## Гарантії поведінки
133
28
 
134
- - бути ESM-модулем (`.mjs`) з ES-імпортами `node:fs` / `node:path`;
135
- - імпортувати `createCheckReporter` із `../../../scripts/lib/check-reporter.mjs` і `hasCargoTomlInTree` із `../lib/has-cargo-toml.mjs`;
136
- - містити module-level `Set` з рівно цими іменами: `'node_modules'`, `'.git'`, `'.next'`, `'.turbo'`;
137
- - експортувати **named** функцію `applies(cwd = process.cwd())` з логікою «`existsSync(join(cwd, 'Cargo.toml'))` → інакше делегат у `hasCargoTomlInTree(cwd, IGNORED_DIR_NAMES)`», результати загорнуті в `Promise.resolve`;
138
- - експортувати **named** синхронну функцію `check()`, яка створює репортер, реєструє `pass('Знайдено Cargo.toml — застосовуємо правила rust.mdc')` і повертає `reporter.getExitCode()`;
139
- - не мати default-експорту;
140
- - не мати побічних ефектів на рівні модуля (тільки декларація `Set` — допустимо).
29
+ - Read-only: файл не виконує операцій запису у файлову систему.
30
+ - Свідомо пропускає шляхи: `.git`, `node_modules`.
31
+ - Не звертається до мережі.