@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,153 +1,36 @@
1
- # tooling.mjs — FS-перевірка вимог правила `python.mdc`
1
+ ---
2
+ docgen:
3
+ source: npm/rules/python/js/tooling.mjs
4
+ crc: f4dc22e2
5
+ score: 95
6
+ ---
2
7
 
3
- ## Огляд
4
-
5
- Модуль `npm/rules/python/js/tooling.mjs` — це **check-частина** правила `python.mdc` для Python-проєктів, які перейшли на пакет-менеджер [uv](https://github.com/astral-sh/uv). Його єдина відповідальність — перевірити **наявність/відсутність файлів** у корені репозиторію, які не може покрити декларативний шар (`conftest`, `Rego`-policies для `fix`-команди).
6
-
7
- Модуль експортує функцію `check(cwd)`, що повертає exit-code (0/1) і друкує діагностику через спільний `check-reporter`. Викликається CLI `@nitra/cursor` після того, як `applies.mjs` вирішив, що правило застосовується до поточного workspace.
8
-
9
- Розподіл відповідальностей між шарами правила `python`:
10
-
11
- | Шар | Що перевіряє |
12
- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
13
- | `applies.mjs` | Чи це Python-проєкт узагалі (наявність `pyproject.toml` як вхідний гейт). |
14
- | `tooling.mjs` (цей файл) | FS-existence: `uv.lock`, `package.json`, `.github/workflows/lint-python.yml`, відсутність `poetry.lock` / `poetry.toml`. |
15
- | `python/pyproject_toml/` (Rego, `fix`) | Заборона `[tool.poetry]`, вимога `PEP 621` `[project].name` / `[project].version`. |
16
- | `python/package_json/` (Rego, `fix`) | Наявність скрипта `lint-python` у кореневому `package.json`. |
17
- | `python/lint_python_yml/` (Rego, `fix`) | Канонічна структура `uses`/`run`-кроків у `.github/workflows/lint-python.yml`. |
18
-
19
- Свідомо **не перевіряється** наявність `.venv/`: uv теж створює `.venv/`, тож сам по собі цей каталог не є ознакою Poetry й давав би хибнопозитивні спрацювання.
20
-
21
- ## Експорти / API
22
-
23
- | Символ | Тип | Призначення |
24
- | ------- | -------------- | ----------------------------------------------------------------------------------- |
25
- | `check` | named function | Головна (і єдина) точка входу — FS-перевірка проєкту на відповідність `python.mdc`. |
26
-
27
- Default-експорт відсутній. Усі імпорти модуля повинні використовувати іменований імпорт:
28
-
29
- ```js
30
- import { check } from './tooling.mjs'
31
- ```
32
-
33
- ## Функції
34
-
35
- ### `check(cwd = process.cwd())`
36
-
37
- **Сигнатура**
38
-
39
- ```js
40
- export function check(cwd = process.cwd()): number
41
- ```
42
-
43
- **Параметри**
44
-
45
- | Імʼя | Тип | Значення за замовч. | Опис |
46
- | ----- | -------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
47
- | `cwd` | `string` | `process.cwd()` | Абсолютний шлях до кореня репозиторію, який перевіряється. У звичайному CLI-прогоні передається з runtime; у тестах та standalone-сценаріях — явним аргументом для ізоляції від реального CWD. |
48
-
49
- **Повертає**
50
-
51
- `number` — exit-code, отриманий від `reporter.getExitCode()`:
52
-
53
- - `0` — усі очікувані файли на місці, заборонених артефактів немає.
54
- - `1` — щонайменше один `fail(...)` був викликаний (відсутня обовʼязкова сутність або присутній заборонений артефакт).
55
-
56
- **Side effects**
57
-
58
- - Виклик `createCheckReporter()` створює репортер, який пише форматовану діагностику в `stdout` / `stderr` через зареєстровані `pass(message)` та `fail(message)`. Кожен виклик `pass` / `fail` усередині `check()` — потенційний рядок у виведенні CLI.
59
- - Виконує синхронні `existsSync(...)` для серії шляхів (читання FS — read-only).
60
- - **Жодних мутацій FS, мережі чи процесу** функція не робить (не пише файли, не виходить через `process.exit`).
8
+ # tooling.mjs
61
9
 
62
- **Алгоритм (покроково)**
63
-
64
- 1. Створює репортер: `const reporter = createCheckReporter()` і деструктурує `{ pass, fail }`.
65
- 2. **Захисний гейт.** Якщо у `cwd` немає `pyproject.toml` — повертає поточний exit-code репортера (на цей момент `0`, оскільки жодних `fail` ще не було). Це дублює гейт `applies.mjs` і потрібне лише для прямого виклику `check()` поза CLI (тести/standalone).
66
- 3. **Перевірка `uv.lock`** (uv-проєкт коммітить lock-файл):
67
- - є → `pass('uv.lock є')`,
68
- - немає → ``fail('uv.lock не знайдено — згенеруй `uv lock` (python.mdc, без Poetry)')``.
69
- 4. **Заборона Poetry-артефактів.** Для кожного імені з масиву `['poetry.lock', 'poetry.toml']`:
70
- - файл існує → `fail('<file> знайдено — прибери Poetry, мігруй на uv (python.mdc)')`,
71
- - файла немає → `pass('<file> відсутній')`.
72
- 5. **Наявність кореневого `package.json`** (для запуску `bun run lint-python`):
73
- - є → `pass('package.json є (наявність lint-python перевіряє fix → python.package_json)')`,
74
- - немає → ``fail('package.json не знайдено в корені — додай для `bun run lint-python` (python.mdc)')``.
75
- 6. **Наявність `.github/workflows/lint-python.yml`** (CI workflow для lint):
76
- - є → `pass('<wfPath> є (структуру перевіряє fix → python.lint_python_yml)')`,
77
- - немає → `fail('<wfPath> не існує — створи згідно python.mdc')`.
78
- 7. Повертає `reporter.getExitCode()`.
79
-
80
- **Інваріанти**
81
-
82
- - Послідовність перевірок фіксована й важить для читабельності виводу. Гейт `pyproject.toml` — обовʼязково першим (інакше для не-Python репо посипалися б `fail`-и).
83
- - Жодна перевірка не «короткозамикає» наступні: навіть якщо `uv.lock` відсутній, далі будуть зроблені перевірки Poetry, `package.json` і workflow — це дозволяє за один прогін побачити повний список проблем.
84
-
85
- ## Залежності
86
-
87
- ### Зовнішні (Node.js standard library)
88
-
89
- | Імпорт | Звідки | Використання |
90
- | ------------ | ----------- | ---------------------------------------------------------------------------- |
91
- | `existsSync` | `node:fs` | Синхронна перевірка існування файлу за абсолютним шляхом. |
92
- | `join` | `node:path` | Кросплатформне склеювання `cwd` із відносним шляхом файла, що перевіряється. |
93
-
94
- ### Внутрішні (проєкт)
95
-
96
- | Імпорт | Звідки | Використання |
97
- | --------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
- | `createCheckReporter` | `../../../scripts/lib/check-reporter.mjs` | Фабрика репортера для check-скриптів. Очікувані поля результату: `pass(msg: string)`, `fail(msg: string)`, `getExitCode(): number` (0 поки не було `fail`, 1 після першого `fail`). |
99
-
100
- ### Зовнішні сутності (контекст правила)
101
-
102
- Файл логічно повʼязаний (але **не імпортує** їх) із:
103
-
104
- - `npm/rules/python/python.mdc` — текстове формулювання правила.
105
- - `npm/rules/python/applies.mjs` — гейт, який вирішує, чи запускати `check()`.
106
- - Rego-полісі `python/pyproject_toml/`, `python/package_json/`, `python/lint_python_yml/` — покривають структурні (а не FS-existence) аспекти, які цей файл свідомо **не** перевіряє.
107
-
108
- ## Потік виконання / Використання
109
-
110
- ### Типовий запуск через CLI
111
-
112
- ```bash
113
- npx @nitra/cursor check python
114
- ```
115
-
116
- CLI послідовно:
117
-
118
- 1. Резолвить правило `python`.
119
- 2. Викликає `applies(cwd)` — якщо `false`, правило пропускається повністю.
120
- 3. Якщо `true`, викликає `check(cwd)` із цього файла.
121
- 4. Друкує зібрану діагностику й завершується з отриманим exit-code.
122
-
123
- ### Прямий виклик (тест / standalone)
124
-
125
- ```js
126
- import { check } from '@nitra/cursor/rules/python/js/tooling.mjs'
127
-
128
- const code = check('/abs/path/to/repo')
129
- // code === 0 → проєкт відповідає python.mdc
130
- // code === 1 → у виводі репортера є помилки, треба полагодити
131
- process.exitCode = code
132
- ```
10
+ ## Огляд
133
11
 
134
- ### Виправлення виявлених проблем
12
+ Файл виконує перевірку наявності конфігураційних та залежностей у кореневому каталозі репозиторію. Він перевіряє структуру проекту відповідно до вимог, визначених у package.json.
135
13
 
136
- Файл лише **діагностує** — нічого не змінює. Виправлення:
14
+ ## Поведінка
137
15
 
138
- | Проблема (`fail`-message) | Що зробити |
139
- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
140
- | `uv.lock не знайдено` | Запустити `uv lock` у корені проєкту й закомітити результат. |
141
- | `poetry.lock знайдено` / `poetry.toml знайдено` | Завершити міграцію з Poetry: видалити файл, перенести залежності в `pyproject.toml` під `[project]` (PEP 621) і згенерувати `uv.lock`. |
142
- | `package.json не знайдено в корені` | Створити `package.json` з полем `scripts.lint-python`. Структуру скрипта перевіряє Rego `python.package_json`. |
143
- | `.github/workflows/lint-python.yml не існує` | Створити workflow за шаблоном з `python.mdc`. Канонічну структуру кроків перевіряє Rego `python.lint_python_yml`. |
16
+ 1. Перевірити наявність `pyproject.toml` у корені репозиторію.
17
+ 2. Перевірити наявність `uv.lock` у корені репозиторію.
18
+ 3. Якщо `uv.lock` відсутній, повернути код виходу.
19
+ 4. Перевірити наявність `poetry.lock` у корені репозиторію.
20
+ 5. Якщо `poetry.lock` знайдено, повернути помилку.
21
+ 6. Якщо `poetry.lock` відсутній, пропустити.
22
+ 7. Перевірити наявність `package.json` у корені репозиторію.
23
+ 8. Якщо `package.json` відсутній, повернути помилку.
24
+ 9. Перевірити наявність файлу `.github/workflows/lint-python.yml` у корені репозиторію.
25
+ 10. Якщо файлу `.github/workflows/lint-python.yml` немає, повернути помилку.
26
+ 11. Повернути код виходу.
144
27
 
145
- ### Граничні випадки
28
+ ## Публічний API
146
29
 
147
- - **Не-Python репо** (немає `pyproject.toml`) `check()` повертає `0` без виводу. Безпечно викликати в монорепо корені.
148
- - **Рівно один `fail`** — exit-code усе одно `1`. Репортер не накопичує «вагу» помилок, лише факт.
149
- - **Усі `pass`** — exit-code `0`, але всі повідомлення `pass` усе одно потрапляють у вивід (для прозорості та CI-логів).
30
+ checkПеревіряє відповідність проєкту правилам python.mdc.
150
31
 
151
- ## Rebuild Test
32
+ ## Гарантії поведінки
152
33
 
153
- Документ описує модуль розміром 70 рядків з єдиним експортом `check`, кореневим гейтом по `pyproject.toml`, чотирма блоками перевірок (`uv.lock`, заборона Poetry, `package.json`, workflow `lint-python.yml`), залежністю від `node:fs`, `node:path` та `../../../scripts/lib/check-reporter.mjs`. На основі цього опису можна відтворити функціональний еквівалент: створити фабрику репортера, повернути `getExitCode()` без перевірок при відсутності `pyproject.toml`, інакше — викликати `pass`/`fail` для кожного шляху в наведеному порядку зі вказаними повідомленнями (українська локалізація, посилання на `python.mdc`). Сигнатура `check(cwd = process.cwd()): number`, side effects обмежені виводом репортера й читанням FS.
34
+ - Read-only: файл не виконує операцій запису у файлову систему.
35
+ - Свідомо пропускає шляхи: `.github`, `.git`.
36
+ - Не звертається до мережі.
@@ -1,121 +1,33 @@
1
- # fix.mjs — точка входу правила `rego`
1
+ ---
2
+ docgen:
3
+ source: npm/rules/rego/fix.mjs
4
+ crc: 38cf876b
5
+ score: 100
6
+ ---
2
7
 
3
- ## Огляд
4
-
5
- Файл `npm/rules/rego/fix.mjs` — це **entry-point правила `rego`** з кодової бази `@nitra/cursor`. Він є тонкою (thin) обгорткою навколо стандартного пайплайну виконання правила і виконує **дві ролі одночасно**:
6
-
7
- 1. **Library mode** — експортує функцію `run(ctx)`, яку CLI-оркестратор (`@nitra/cursor fix <id>`) викликає через динамічний `import`, передаючи спільний контекст прогону (наприклад, `walkCache`).
8
- 2. **Standalone mode** — якщо файл запущено напряму як CLI (наприклад, `bun npm/rules/rego/fix.mjs`), він виконує **повний еквівалент** команди `npx @nitra/cursor fix rego`: завантажує конфіг, застосовує whitelist, друкує summary та повертає процесові exit-code.
9
-
10
- Внутрішня логіка правила (що саме перевіряється/виправляється у файлах `.rego`, OPA-політиках тощо) **не реалізована в цьому файлі** — вся послідовність кроків (`applies → JS-concerns → policy → mdc-refs`) інкапсульована у спільному хелпері `runStandardRule`. Сам `fix.mjs` лише делегує виконання, передаючи `import.meta.dirname` як точку відліку для конвенційного пошуку файлів-супутників правила (наприклад, `applies.mjs`, `check-*.mjs`, `policy/`, `mdc/`).
11
-
12
- Така структура повторюється для кожного правила в `npm/rules/<id>/fix.mjs` — це шаблонний стандартний boilerplate, у якому індивідуальною є лише тека `<id>` (тут — `rego`).
13
-
14
- ## Експорти / API
15
-
16
- | Назва | Тип | Опис |
17
- | ----- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
18
- | `run` | `function(ctx?): Promise<number>` | Named-експорт. Library-точка входу для оркестратора. Запускає стандартний пайплайн правила `rego` у директорії цього файлу. |
19
-
20
- Файл **не має default-експорту** і **не експортує** жодних інших символів. Side-effect на верхньому рівні модуля — перевірка `isRunAsCli(import.meta.url)`; якщо вона істинна, виконується `process.exit(await runRuleCli(...))`.
21
-
22
- ### Сигнатура `run`
23
-
24
- ```js
25
- export function run(ctx)
26
- ```
27
-
28
- - **Параметр `ctx`** — необов'язковий об'єкт типу `RuleContext` (тип імпортується через JSDoc із `../../scripts/lib/run-standard-rule.mjs`). У контексті, зокрема, передається `walkCache` — кеш обходу файлів, який дозволяє багаторазовим прогонам різних правил не дублювати дискові операції під час однієї сесії `@nitra/cursor fix`.
29
- - **Повертає** — `Promise<number>`, де `0` означає **OK** (порушень не знайдено / усе виправлено), а `1` означає **наявність порушень** (failure). Це класична CLI-конвенція exit-code, узгоджена з типами в `runStandardRule`.
30
- - **Прив'язка до директорії правила** — `import.meta.dirname` (нативне Node.js property для ESM, доступне у сучасних рантаймах) дає абсолютний шлях до теки, де лежить сам `fix.mjs`. Цей шлях передається у `runStandardRule` як «корінь правила», аби той знаходив супровідні файли (`applies.mjs`, `check-*.mjs`, `policy/*.rego`, `mdc/*` тощо) за конвенцією.
31
-
32
- ## Функції
33
-
34
- ### `run(ctx)`
35
-
36
- - **Сигнатура:** `function run(ctx?: RuleContext): Promise<number>`
37
- - **Параметри:**
38
- - `ctx` (опційний) — контекст прогону правила. Передається оркестратором (`runRuleCli` / `runMany`), коли правило запускається не самостійно, а в складі батча; містить, серед іншого, спільний `walkCache`. У standalone-режимі (див. нижче) `ctx` не передається — використовується дефолт, який сконструює `runStandardRule` самостійно.
39
- - **Повертає:** `Promise<number>` — exit-code:
40
- - `0` — правило пройшло (`OK`).
41
- - `1` — правило виявило порушення (`violation`).
42
- - **Side effects:**
43
- - Не має жодних побічних ефектів на рівні самої функції-обгортки.
44
- - Усі побічні ефекти (читання файлів, запис виправлень, друк у `stdout`/`stderr`, доступ до `walkCache`, мережа/диск) делеговані у `runStandardRule` і виконуються вже в його реалізації.
45
- - **Чому така тонка обгортка?** Оркестратор `@nitra/cursor fix` під час батчового прогону **динамічно імпортує** `fix.mjs` кожного правила й викликає `run(ctx)`. Якби логіка пайплайну дублювалася в кожному `fix.mjs`, її було б неможливо змінювати централізовано — `runStandardRule` забезпечує єдину точку зміни поведінки для всіх правил.
8
+ # fix.mjs
46
9
 
47
- ### Standalone-блок (не функція, top-level код)
48
-
49
- ```js
50
- if (isRunAsCli(import.meta.url)) {
51
- process.exit(await runRuleCli(import.meta.dirname))
52
- }
53
- ```
54
-
55
- - **Умова входу:** `isRunAsCli(import.meta.url)` повертає `true`, якщо модуль запущений як головний (а не імпортований іншим). Реалізація хелпера — у `npm/scripts/lib/run-rule-cli.mjs`.
56
- - **Що виконує:** `runRuleCli(import.meta.dirname)` запускає **повний CLI** для цього правила — еквівалент `npx @nitra/cursor fix rego`. На відміну від `run(ctx)`, цей шлях додатково завантажує конфіг репозиторію, застосовує whitelist (ігнорування файлів/паттернів за конфігом), друкує summary прогону тощо.
57
- - **`process.exit(...)`** — потрібен, щоб standalone-запуск повертав **коректний exit-code** у виклик shell/CI (інакше `bun` міг би завершитися з `0` навіть за провалу).
58
- - **ESLint-винятки:** `n/no-process-exit` і `unicorn/no-process-exit` локально відключені коментарем — це свідома відмова на користь правильного CI/IDE-поведінки (standalone entry-point **зобов'язаний** повертати exit-code).
59
- - **`await` на top-level:** використовується top-level `await`, що в ESM-модулях Node 20+ є штатною можливістю.
60
-
61
- ## Залежності
62
-
63
- Файл імпортує лише **два внутрішніх модулі** (relative imports), зовнішніх npm-пакетів не використовує безпосередньо.
64
-
65
- | Імпорт | Звідки | Призначення |
66
- | ----------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
67
- | `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Предикат: повертає `true`, якщо файл запущено напряму (а не імпортовано). Використовується у standalone-блоці. |
68
- | `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Запуск **повного CLI** для одного правила (config-loading + whitelist + summary). Викликається в standalone-режимі. |
69
- | `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Запуск **стандартного пайплайну** правила: `applies → JS-concerns → policy → mdc-refs`. Викликається з library-функції `run(ctx)`. |
70
-
71
- Додатково через JSDoc підтягується **тип** `RuleContext` (для типізації `ctx`) із того ж `../../scripts/lib/run-standard-rule.mjs`.
72
-
73
- Інші **неявні залежності** (через `runStandardRule` / `runRuleCli`):
74
-
75
- - файлова система — для пошуку файлів за конвенцією правила;
76
- - сам `import.meta.dirname` — як спосіб самоідентифікації правила без хардкоду шляху.
77
-
78
- ## Потік виконання / Використання
79
-
80
- ### Сценарій 1: Library mode (виклик з оркестратора)
81
-
82
- 1. Користувач виконує `bun cursor fix` або `npx @nitra/cursor fix`.
83
- 2. Оркестратор знаходить усі активні правила (зокрема `rego`) і динамічно імпортує `npm/rules/rego/fix.mjs`.
84
- 3. Оркестратор викликає `run(ctx)`, де `ctx` містить, зокрема, `walkCache`.
85
- 4. `run(ctx)` повертає `runStandardRule(import.meta.dirname, ctx)`.
86
- 5. `runStandardRule` послідовно виконує стандартні етапи правила:
87
- - **applies** — визначає, до яких файлів застосовується правило (через супровідний `applies.mjs`);
88
- - **JS-concerns** — перевірки/виправлення, що стосуються JS-коду навколо правила;
89
- - **policy** — застосування полісі/політик (для `rego` це конкретні OPA-rego-фрагменти);
90
- - **mdc-refs** — звірка з посиланнями на правила в `.mdc`-документах.
91
- 6. Результат — `Promise<number>` (`0` або `1`) — повертається оркестратору, який агрегує підсумок по всіх правилах.
92
-
93
- ### Сценарій 2: Standalone mode (прямий запуск)
94
-
95
- 1. Розробник виконує, наприклад, `bun npm/rules/rego/fix.mjs` (або еквівалентно `node npm/rules/rego/fix.mjs`).
96
- 2. Виконується top-level код модуля; `isRunAsCli(import.meta.url)` повертає `true`.
97
- 3. Викликається `await runRuleCli(import.meta.dirname)` — це **повний CLI-флоу** для одного правила (включно з config-loading, whitelist та summary).
98
- 4. Результат — `number` (exit-code) — передається у `process.exit(...)`, який негайно завершує процес із цим кодом.
99
- 5. Shell / IDE / CI отримує exit-code: `0` (OK) або `1` (violations) — і може відповідно сигналізувати про результат.
10
+ ## Огляд
100
11
 
101
- ### Як викликати `run` із зовнішнього коду (приклад)
12
+ Огляд: Функція run виконує перевірку правила. Повертає число, що інформує про успішність або порушення. Виконання правила через командний рядок повертає код виходу, який встановлює статус процесу.
102
13
 
103
- ```js
104
- import { run } from './npm/rules/rego/fix.mjs'
14
+ ## Поведінка
105
15
 
106
- const code = await run() // або: await run({ walkCache: myCache })
107
- if (code !== 0) {
108
- // правило знайшло порушення
109
- }
110
- ```
16
+ 1. Запуск правила.
17
+ - Вхід: контекст прогону.
18
+ - Вихід: обіцянка, що повертає число. 0 означає успіх, 1 означає порушення.
19
+ 2. Виконання правила у режимі CLI.
20
+ - Умова: виконання через командний рядок.
21
+ - Дія: повернення коду виходу з функції.
22
+ - Вихід: встановлення коду виходу процесу.
111
23
 
112
- ### Як викликати у standalone
24
+ ## Публічний API
113
25
 
114
- ```sh
115
- bun npm/rules/rego/fix.mjs
116
- echo $? # 0 — OK, 1 — violations
117
- ```
26
+ run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
27
+ Library mode — викликається CLI orchestration через `import + run`.
118
28
 
119
- ### Подвійна роль файлу
29
+ ## Гарантії поведінки
120
30
 
121
- Дві ролі — `library` (іменований експорт `run`) та `standalone` (top-level CLI з `process.exit`) — навмисно поєднані в одному файлі: це дозволяє оркестратору не дублювати code path для одного й того самого правила, а розробнику — швидко прогнати окреме правило без запуску всього батча. Конвенція повторюється для всіх правил у `npm/rules/<id>/fix.mjs`, тож структура файлу `rego/fix.mjs` ідентична іншим правилам у каталозі — змінюється лише імпліцитна тека-«корінь» (`import.meta.dirname`).
31
+ - Read-only: файл не виконує операцій запису у файлову систему.
32
+ - Кешує результати в межах одного прогону.
33
+ - Не звертається до мережі.
@@ -1,174 +1,30 @@
1
- # applies.mjs — applies-гейт правила `rego`
1
+ ---
2
+ docgen:
3
+ source: npm/rules/rego/js/applies.mjs
4
+ crc: 059e378c
5
+ score: 100
6
+ ---
2
7
 
3
- ## Огляд
4
-
5
- Модуль `applies.mjs` реалізує **rule-level applies-гейт** для правила `rego` (див. `rego.mdc`). Призначення модуля — відповісти на запитання: «Чи має CLI взагалі застосовувати правило `rego` до цього репозиторію?»
6
-
7
- Логіка гейту проста: правило **застосовне лише тоді**, коли в дереві репозиторію (з урахуванням типових skip-каталогів і ігнор-патернів із `.n-cursor.json:ignore`) існує хоча б один `.rego`-файл. Якщо таких файлів немає — CLI пропускає правило **цілком**, включно з усіма його полісі-концернами (`package_json`, `vscode_extensions`, `vscode_settings`), оскільки вимоги rego-tooling стають неактуальними для проєкту без OPA/rego-коду.
8
-
9
- Чому це не виражено декларативно через `target.json`-маніфести? Бо це **cross-file** гейт: вирішення базується на пошуку файлу по дереву (`walkDir`), а не на перевірці властивостей одного конкретного файлу. Декларативна модель `target.json` для цього не підходить, тому залишається імперативний JS.
10
-
11
- Окрім самого гейта, файл також експортує невелику функцію `check()`, яка лише друкує контекстне pass-повідомлення (фактичні порушення вже повертають окремі policy-концерни).
12
-
13
- ## Експорти / API
14
-
15
- Модуль експортує два public-символи:
16
-
17
- | Символ | Тип | Призначення |
18
- | --------------- | ---------------- | ---------------------------------------------------------------------- |
19
- | `applies(cwd?)` | `async function` | Rule-level applies-гейт: чи застосовне правило `rego` до репозиторію. |
20
- | `check()` | `function` | Друкує короткий context-pass; повертає exit-code від `check-reporter`. |
21
-
22
- Внутрішня (не експортована) допоміжна функція:
23
-
24
- | Символ | Тип | Призначення |
25
- | ---------------------------------------- | ---------------- | ------------------------------------------------------------------ |
26
- | `projectHasRegoFiles(root, ignorePaths)` | `async function` | Чи є хоча б один `.rego` у дереві від `root` (зупинка на першому). |
27
-
28
- ## Функції
29
-
30
- ### `projectHasRegoFiles(root, ignorePaths)` (internal)
31
-
32
- **Сигнатура**
33
-
34
- ```js
35
- async function projectHasRegoFiles(root: string, ignorePaths: string[]): Promise<boolean>
36
- ```
37
-
38
- **Параметри**
39
-
40
- - `root` — абсолютний шлях до кореня репозиторію, від якого починати обхід.
41
- - `ignorePaths` — масив шляхів каталогів, повністю виключених з обходу (зазвичай результат `loadCursorIgnorePaths(cwd)`).
42
-
43
- **Повертає**
44
-
45
- - `Promise<boolean>` — `true`, якщо в дереві знайдено принаймні один `.rego`-файл; інакше `false`.
46
-
47
- **Side effects / нотатки**
48
-
49
- - Виконує файлову систему-операцію через `walkDir`.
50
- - **Не короткозамикається** ранньо у сенсі «зупинити walk» — `walkDir` тут не отримує сигнал на дострокове припинення, але всередині callback просто переписує локальну змінну `found = true` при першому матчі (подальші зустрічі залишають значення тим самим). Таким чином, фактично функція **проходить усе дерево**, проте семантично відповідає на питання «чи знайшовся хоч один».
51
- - Жодних throw-ів не передбачено в самому коді функції — будь-які помилки I/O бульбашиться з `walkDir`.
52
-
53
- ### `applies(cwd = process.cwd())` (exported)
54
-
55
- **Сигнатура**
56
-
57
- ```js
58
- export async function applies(cwd?: string): Promise<boolean>
59
- ```
60
-
61
- **Параметри**
62
-
63
- - `cwd` _(опц.)_ — корінь репозиторію. За замовчуванням — поточна робоча директорія процесу (`process.cwd()`).
64
-
65
- **Повертає**
66
-
67
- - `Promise<boolean>` — `true`, якщо правило `rego` застосовне (в репо знайдено принаймні один `.rego`); `false` — якщо правило слід пропустити.
68
-
69
- **Side effects**
8
+ # applies.mjs
70
9
 
71
- - Читає `.n-cursor.json` через `loadCursorIgnorePaths(cwd)`, щоб одержати каталоги, які слід ігнорувати.
72
- - Виконує файловий обхід через `projectHasRegoFiles` (внутрішньо — `walkDir`).
73
- - Не модифікує файлову систему, не пише в stdout/stderr.
74
-
75
- ### `check()` (exported)
76
-
77
- **Сигнатура**
78
-
79
- ```js
80
- export function check(): number
81
- ```
82
-
83
- **Параметри**
84
-
85
- - Немає.
86
-
87
- **Повертає**
88
-
89
- - `number` — exit-code, який повертає `reporter.getExitCode()` (зазвичай `0`, оскільки тут викликається лише `reporter.pass(...)`).
90
-
91
- **Side effects**
92
-
93
- - Створює локальний `check-reporter` через `createCheckReporter()`.
94
- - Друкує context-pass повідомлення: `Знайдено *.rego у дереві — перевіряємо канонічні конфіги rego.mdc`.
95
- - Фактичні порушення rego-правила цей `check()` **не повертає** — вони приходять від окремих policy-концернів, які CLI запускає декларативно через `policy/<name>/target.json`.
96
-
97
- ## Залежності
98
-
99
- Модуль явно імпортує три внутрішніх допоміжних модулі:
100
-
101
- | Імпорт | Шлях | Роль |
102
- | ----------------------- | --------------------------------------------- | ------------------------------------------------------------------------ |
103
- | `createCheckReporter` | `../../../scripts/lib/check-reporter.mjs` | Фабрика репортера для check-функцій; дає `pass()`, `getExitCode()` тощо. |
104
- | `loadCursorIgnorePaths` | `../../../scripts/lib/load-cursor-config.mjs` | Зчитує `.n-cursor.json` і повертає список ігнор-шляхів для обходу. |
105
- | `walkDir` | `../../../scripts/utils/walkDir.mjs` | Рекурсивний обхід директорії з підтримкою skip-патернів і ignorePaths. |
106
-
107
- Зовнішніх npm-залежностей у файлі немає; стандартних Node-API напряму не використовується (окрім `process.cwd()` як значення дефолту параметра).
108
-
109
- ## Потік виконання / Використання
110
-
111
- ### Контракт CLI
112
-
113
- Файл `applies.mjs` — стандартна точка входу для CLI правила. CLI (npm/n-cursor) обходить правила (`npm/rules/*/`) і для кожного шукає `js/applies.mjs`. Якщо файл є — CLI імпортує `applies` і викликає її, передаючи `cwd` репозиторію. Залежно від результату:
114
-
115
- - `applies(cwd)` повернуло `true` → CLI продовжує: запускає всі полісі-концерни правила (`policy/<name>/target.json`), а також (опціонально) викликає `check()` для друку контекстного pass-повідомлення.
116
- - `applies(cwd)` повернуло `false` → CLI **повністю пропускає** правило `rego`: жодний полісі не запускається, `check()` не викликається.
117
-
118
- ### Внутрішня послідовність викликів `applies(cwd)`
119
-
120
- 1. **Отримати ignorePaths** — викликати `loadCursorIgnorePaths(cwd)`. Результат — масив шляхів каталогів з `.n-cursor.json:ignore`, які слід виключити з обходу.
121
- 2. **Перевірити наявність `.rego`** — викликати `projectHasRegoFiles(cwd, ignorePaths)`:
122
- - `walkDir` обходить дерево від `cwd`, оминаючи `ignorePaths` і типові skip-каталоги (`node_modules`, `.git`, тощо — згідно семантики `walkDir`).
123
- - Кожен знайдений шлях `p` перевіряється на суфікс `.rego`; перший збіг встановлює `found = true`.
124
- 3. **Повернути результат** — `Promise<boolean>`.
125
-
126
- ### Внутрішня послідовність викликів `check()`
127
-
128
- 1. Створити репортер: `const reporter = createCheckReporter()`.
129
- 2. Зареєструвати pass-подію: `reporter.pass('Знайдено *.rego у дереві — перевіряємо канонічні конфіги rego.mdc')`.
130
- 3. Повернути exit-code: `return reporter.getExitCode()`.
131
-
132
- ### Типовий сценарій для проєкту з OPA-полісі
133
-
134
- Якщо у вашому репозиторії під CI/security лежать файли на kшталт `policies/foo.rego`, `infra/opa/*.rego` тощо:
135
-
136
- - `applies(cwd)` поверне `true`.
137
- - CLI прогонить полісі-концерни `rego`-правила: перевірить, що `package.json` містить очікувані скрипти/devDependencies, що `.vscode/extensions.json` рекомендує OPA-розширення, що `.vscode/settings.json` має канонічні налаштування — все це декларативно через `policy/<name>/target.json`.
138
- - Додатково CLI може надрукувати pass-рядок із `check()`.
139
-
140
- ### Типовий сценарій для проєкту без rego
141
-
142
- Якщо `.rego` файлів у дереві немає:
143
-
144
- - `applies(cwd)` поверне `false`.
145
- - CLI пропустить правило `rego` цілком — користувач не побачить жодних повідомлень про відсутні rego-tooling-конфіги, бо вони неактуальні.
10
+ ## Огляд
146
11
 
147
- ### Приклад прямого виклику з тестів або сервісного коду
12
+ Файл виконує перевірку наявності файлів із розширенням `.rego` у визначеній директорії. Функція видає повідомлення про старт перевірки та повертає код виходу.
148
13
 
149
- ```js
150
- import { applies, check } from './applies.mjs'
14
+ ## Поведінка
151
15
 
152
- const shouldRun = await applies('/abs/path/to/repo')
153
- if (shouldRun) {
154
- const code = check()
155
- process.exit(code)
156
- }
157
- ```
16
+ applies
17
+ Перевіряє наявність `.rego` файлів у дереві від вказаного шляху.
158
18
 
159
- ## Rebuild Test
19
+ check
20
+ Друкує повідомлення про початок перевірки та повертає код виходу.
160
21
 
161
- Маючи лише цей документ, інженер має змогу відтворити файл наступним чином:
22
+ ## Публічний API
162
23
 
163
- 1. Створити модуль `applies.mjs` у каталозі `npm/rules/rego/js/`.
164
- 2. Імпортувати три залежності з відносними шляхами `../../../scripts/lib/check-reporter.mjs`, `../../../scripts/lib/load-cursor-config.mjs`, `../../../scripts/utils/walkDir.mjs`.
165
- 3. Реалізувати **приватну** `async function projectHasRegoFiles(root, ignorePaths)`: завести локальну змінну `found = false`, викликати `await walkDir(root, callback, ignorePaths)`, де callback перевіряє `p.endsWith('.rego')` і виставляє `found = true`. Повернути `found`.
166
- 4. Експортувати **`async function applies(cwd = process.cwd())`**: одержати `ignorePaths` через `await loadCursorIgnorePaths(cwd)`, повернути результат `projectHasRegoFiles(cwd, ignorePaths)`.
167
- 5. Експортувати **`function check()`**: створити `reporter` через `createCheckReporter()`, викликати `reporter.pass('Знайдено *.rego у дереві — перевіряємо канонічні конфіги rego.mdc')`, повернути `reporter.getExitCode()`.
168
- 6. Додати JSDoc-коментарі: file-header пояснює призначення applies-гейта і чому JS, а не `target.json`; кожна з трьох функцій має JSDoc із параметрами/повертанням.
24
+ - applies Правило застосовується, якщо в репозиторії відсутні файли `.rego`.
25
+ - check Виводить короткий контекст політика пройде через CLI через `policy/<name>/target.json`.
169
26
 
170
- Очікуваний зовнішній контракт після rebuild:
27
+ ## Гарантії поведінки
171
28
 
172
- - `applies('/repo/with/rego/files')` `Promise<true>`.
173
- - `applies('/repo/without/rego/files')` `Promise<false>`.
174
- - `check()` → синхронно повертає число (exit-code від check-reporter), друкує pass-повідомлення.
29
+ - Read-only: файл не виконує операцій запису у файлову систему.
30
+ - Не звертається до мережі.