@nitra/cursor 12.6.0 → 12.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/.claude-template/settings.template.json +1 -1
  2. package/CHANGELOG.md +16 -0
  3. package/bin/docs/n-cursor.md +4 -20
  4. package/bin/n-cursor.js +7 -53
  5. package/docs/stryker.config.md +20 -28
  6. package/package.json +1 -1
  7. package/rules/abie/docs/index.md +1 -0
  8. package/rules/abie/docs/main.md +29 -0
  9. package/rules/abie/{fix.mjs → main.mjs} +5 -3
  10. package/rules/adr/docs/index.md +1 -0
  11. package/rules/adr/docs/main.md +29 -0
  12. package/rules/adr/{fix.mjs → main.mjs} +5 -3
  13. package/rules/bun/docs/index.md +1 -0
  14. package/rules/bun/docs/main.md +30 -0
  15. package/rules/bun/js/docs/layout.md +11 -36
  16. package/rules/bun/{fix.mjs → main.mjs} +5 -3
  17. package/rules/capacitor/docs/index.md +1 -0
  18. package/rules/capacitor/docs/main.md +29 -0
  19. package/rules/capacitor/{fix.mjs → main.mjs} +5 -3
  20. package/rules/changelog/docs/index.md +1 -0
  21. package/rules/changelog/docs/main.md +27 -0
  22. package/rules/changelog/main.mjs +20 -0
  23. package/rules/ci4/docs/index.md +1 -0
  24. package/rules/ci4/docs/main.md +30 -0
  25. package/rules/ci4/main.mjs +20 -0
  26. package/rules/doc-files/docs/index.md +1 -0
  27. package/rules/doc-files/docs/main.md +31 -0
  28. package/rules/doc-files/js/docgen-files-batch.mjs +47 -3
  29. package/rules/doc-files/js/docgen-scan.mjs +89 -9
  30. package/rules/doc-files/js/docs/docgen-files-batch.md +15 -15
  31. package/rules/doc-files/js/docs/docgen-scan.md +34 -34
  32. package/rules/doc-files/js/docs/index.md +1 -0
  33. package/rules/doc-files/js/docs/run-lint.md +27 -0
  34. package/rules/doc-files/{lint/lint.mjs → js/run-lint.mjs} +23 -9
  35. package/rules/doc-files/{js/lint.mjs → main.mjs} +60 -10
  36. package/rules/docker/docs/index.md +1 -0
  37. package/rules/docker/docs/main.md +28 -0
  38. package/rules/docker/js/docs/lint.md +26 -54
  39. package/rules/docker/js/lint.mjs +11 -0
  40. package/rules/docker/lib/docker-hadolint.mjs +1 -1
  41. package/rules/docker/lib/docs/docker-hadolint.md +16 -173
  42. package/rules/docker/main.mjs +20 -0
  43. package/rules/efes/docs/index.md +1 -0
  44. package/rules/efes/docs/main.md +29 -0
  45. package/rules/efes/main.mjs +20 -0
  46. package/rules/feedback/docs/index.md +1 -0
  47. package/rules/feedback/docs/main.md +30 -0
  48. package/rules/feedback/main.mjs +20 -0
  49. package/rules/ga/docs/index.md +1 -0
  50. package/rules/ga/docs/main.md +29 -0
  51. package/rules/ga/{lint/lint.mjs → main.mjs} +36 -10
  52. package/rules/graphql/docs/index.md +1 -0
  53. package/rules/graphql/docs/main.md +36 -0
  54. package/rules/graphql/main.mjs +20 -0
  55. package/rules/hasura/docs/index.md +1 -0
  56. package/rules/hasura/docs/main.md +30 -0
  57. package/rules/hasura/main.mjs +20 -0
  58. package/rules/image-avif/docs/index.md +1 -0
  59. package/rules/image-avif/docs/main.md +30 -0
  60. package/rules/image-avif/js/docs/avif_generation.md +20 -233
  61. package/rules/image-avif/main.mjs +20 -0
  62. package/rules/image-compress/docs/index.md +1 -0
  63. package/rules/image-compress/docs/main.md +29 -0
  64. package/rules/image-compress/js/docs/package_setup.md +12 -11
  65. package/rules/image-compress/{js/lint.mjs → main.mjs} +21 -5
  66. package/rules/js-bun-db/docs/index.md +1 -0
  67. package/rules/js-bun-db/docs/main.md +30 -0
  68. package/rules/js-bun-db/main.mjs +20 -0
  69. package/rules/js-bun-redis/docs/index.md +1 -0
  70. package/rules/js-bun-redis/docs/main.md +29 -0
  71. package/rules/js-bun-redis/main.mjs +20 -0
  72. package/rules/js-lint/docs/index.md +1 -0
  73. package/rules/js-lint/docs/main.md +29 -0
  74. package/rules/js-lint/js/check.mjs +268 -0
  75. package/rules/js-lint/js/docs/check.md +39 -0
  76. package/rules/js-lint/js/docs/index.md +1 -1
  77. package/rules/js-lint/js/docs/tooling.md +12 -32
  78. package/rules/js-lint/js/tooling.mjs +1 -265
  79. package/rules/js-lint/{js/lint.mjs → main.mjs} +19 -2
  80. package/rules/js-lint-ci/docs/index.md +1 -0
  81. package/rules/js-lint-ci/docs/main.md +27 -0
  82. package/rules/js-lint-ci/main.mjs +33 -0
  83. package/rules/js-mssql/docs/index.md +1 -0
  84. package/rules/js-mssql/docs/main.md +30 -0
  85. package/rules/js-mssql/main.mjs +20 -0
  86. package/rules/js-run/docs/index.md +1 -0
  87. package/rules/js-run/docs/main.md +30 -0
  88. package/rules/js-run/main.mjs +20 -0
  89. package/rules/k8s/docs/index.md +1 -0
  90. package/rules/k8s/docs/main.md +40 -0
  91. package/rules/k8s/js/docs/index.md +12 -0
  92. package/rules/k8s/{lint/lint.mjs → main.mjs} +32 -10
  93. package/rules/nginx-default-tpl/docs/index.md +1 -0
  94. package/rules/nginx-default-tpl/docs/main.md +30 -0
  95. package/rules/nginx-default-tpl/main.mjs +20 -0
  96. package/rules/npm-module/docs/index.md +1 -0
  97. package/rules/npm-module/docs/main.md +29 -0
  98. package/rules/npm-module/js/docs/rule_meta.md +17 -16
  99. package/rules/npm-module/js/rule_meta.mjs +13 -3
  100. package/rules/npm-module/main.mjs +20 -0
  101. package/rules/php/docs/index.md +1 -0
  102. package/rules/php/docs/main.md +33 -0
  103. package/rules/php/js/docs/tooling.md +10 -10
  104. package/rules/php/{lint/lint.mjs → main.mjs} +32 -6
  105. package/rules/python/docs/index.md +1 -0
  106. package/rules/python/docs/main.md +31 -0
  107. package/rules/python/js/docs/tooling.md +17 -17
  108. package/rules/python/{lint/lint.mjs → main.mjs} +29 -5
  109. package/rules/rego/docs/index.md +1 -0
  110. package/rules/rego/docs/main.md +37 -0
  111. package/rules/rego/{lint/lint.mjs → main.mjs} +27 -5
  112. package/rules/release/docs/index.md +1 -0
  113. package/rules/release/docs/main.md +29 -0
  114. package/rules/release/docs/release.md +0 -3
  115. package/rules/release/release.mdc +10 -0
  116. package/rules/rust/docs/index.md +1 -0
  117. package/rules/rust/docs/main.md +27 -0
  118. package/rules/rust/{js/lint.mjs → main.mjs} +20 -3
  119. package/rules/security/docs/index.md +1 -0
  120. package/rules/security/docs/main.md +28 -0
  121. package/rules/security/main.mjs +45 -0
  122. package/rules/style-lint/docs/index.md +1 -0
  123. package/rules/style-lint/docs/main.md +29 -0
  124. package/rules/style-lint/{js/lint.mjs → main.mjs} +19 -1
  125. package/rules/tauri/docs/index.md +1 -0
  126. package/rules/tauri/docs/main.md +29 -0
  127. package/rules/tauri/main.mjs +20 -0
  128. package/rules/test/docs/index.md +1 -0
  129. package/rules/test/docs/main.md +30 -0
  130. package/rules/test/main.mjs +20 -0
  131. package/rules/text/docs/index.md +1 -0
  132. package/rules/text/docs/main.md +29 -0
  133. package/rules/text/js/docs/cspell-fix.md +30 -0
  134. package/rules/text/js/docs/formatting.md +12 -45
  135. package/rules/text/js/docs/index.md +4 -0
  136. package/rules/text/js/docs/run-dotenv-linter.md +31 -0
  137. package/rules/text/js/docs/run-shellcheck.md +28 -0
  138. package/rules/text/js/docs/run-v8r.md +29 -0
  139. package/rules/text/{lint/lint.mjs → main.mjs} +38 -9
  140. package/rules/text/text.mdc +5 -14
  141. package/rules/tool-surface/docs/index.md +1 -0
  142. package/rules/tool-surface/docs/main.md +29 -0
  143. package/rules/tool-surface/main.mjs +20 -0
  144. package/rules/vue/docs/index.md +1 -0
  145. package/rules/vue/docs/main.md +29 -0
  146. package/rules/vue/main.mjs +20 -0
  147. package/rules/worktree/docs/index.md +1 -0
  148. package/rules/worktree/docs/main.md +28 -0
  149. package/rules/worktree/main.mjs +20 -0
  150. package/scripts/docs/index.md +1 -0
  151. package/scripts/docs/post-tool-use-check.md +29 -0
  152. package/scripts/docs/sync-claude-config.md +64 -92
  153. package/scripts/lib/adr/docs/normalize-cli.md +0 -3
  154. package/scripts/lib/adr/docs/normalize-pipeline.md +0 -3
  155. package/scripts/lib/docs/gha-workflow.md +25 -317
  156. package/scripts/lib/docs/index.md +1 -0
  157. package/scripts/lib/docs/list-project-rules-mdc.md +5 -4
  158. package/scripts/lib/docs/list-rule-ids.md +15 -148
  159. package/scripts/lib/docs/read-n-cursor-config-lite.md +12 -16
  160. package/scripts/lib/docs/run-lint-step.md +13 -13
  161. package/scripts/lib/docs/run-lint.md +30 -0
  162. package/scripts/lib/docs/run-rule-cli.md +14 -10
  163. package/scripts/lib/docs/run-standard-lint.md +27 -10
  164. package/scripts/lib/docs/run-standard-rule.md +12 -11
  165. package/scripts/lib/docs/timing-summary.md +11 -12
  166. package/scripts/lib/docs/worktree-notice.md +0 -3
  167. package/scripts/lib/fix/docs/index.md +1 -0
  168. package/scripts/lib/fix/docs/orchestrator.md +23 -18
  169. package/scripts/lib/fix/docs/run-conformance-check.md +32 -0
  170. package/scripts/lib/fix/docs/t0.md +10 -9
  171. package/scripts/lib/fix/orchestrator.mjs +5 -5
  172. package/scripts/lib/fix/{run-fix-check.mjs → run-conformance-check.mjs} +13 -13
  173. package/scripts/lib/fix/t0.mjs +3 -3
  174. package/scripts/lib/gha-workflow.mjs +1 -1
  175. package/scripts/lib/list-project-rules-mdc.mjs +1 -1
  176. package/scripts/lib/list-rule-ids.mjs +12 -3
  177. package/scripts/lib/read-n-cursor-config-lite.mjs +2 -2
  178. package/scripts/lib/run-lint-step.mjs +1 -1
  179. package/{rules/lint/js/orchestrate.mjs → scripts/lib/run-lint.mjs} +42 -20
  180. package/scripts/lib/run-rule-cli.mjs +4 -4
  181. package/scripts/lib/run-standard-lint.mjs +19 -6
  182. package/scripts/lib/run-standard-rule.mjs +4 -4
  183. package/scripts/lib/timing-summary.mjs +1 -1
  184. package/scripts/{post-tool-use-fix.mjs → post-tool-use-check.mjs} +9 -9
  185. package/scripts/sync-claude-config.mjs +2 -2
  186. package/rules/changelog/fix.mjs +0 -18
  187. package/rules/ci4/fix.mjs +0 -18
  188. package/rules/doc-files/fix.mjs +0 -19
  189. package/rules/doc-files/js/docs/lint.md +0 -34
  190. package/rules/doc-files/lint/docs/index.md +0 -11
  191. package/rules/doc-files/lint/docs/lint.md +0 -35
  192. package/rules/docker/fix.mjs +0 -18
  193. package/rules/docker/lint/docs/index.md +0 -11
  194. package/rules/docker/lint/docs/lint.md +0 -200
  195. package/rules/docker/lint/lint.mjs +0 -95
  196. package/rules/efes/fix.mjs +0 -18
  197. package/rules/feedback/fix.mjs +0 -18
  198. package/rules/ga/fix.mjs +0 -18
  199. package/rules/ga/js/docs/lint.md +0 -20
  200. package/rules/ga/js/lint.mjs +0 -12
  201. package/rules/ga/lint/docs/index.md +0 -11
  202. package/rules/ga/lint/docs/lint.md +0 -31
  203. package/rules/graphql/fix.mjs +0 -18
  204. package/rules/hasura/fix.mjs +0 -18
  205. package/rules/image-avif/fix.mjs +0 -18
  206. package/rules/image-compress/fix.mjs +0 -18
  207. package/rules/image-compress/js/docs/lint.md +0 -24
  208. package/rules/js-bun-db/fix.mjs +0 -18
  209. package/rules/js-bun-redis/fix.mjs +0 -18
  210. package/rules/js-lint/fix.mjs +0 -18
  211. package/rules/js-lint/js/docs/lint.md +0 -32
  212. package/rules/js-lint-ci/fix.mjs +0 -18
  213. package/rules/js-lint-ci/js/docs/lint.md +0 -22
  214. package/rules/js-lint-ci/js/lint.mjs +0 -15
  215. package/rules/js-mssql/fix.mjs +0 -18
  216. package/rules/js-run/fix.mjs +0 -18
  217. package/rules/k8s/fix.mjs +0 -18
  218. package/rules/k8s/js/lint.mjs +0 -14
  219. package/rules/k8s/lint/docs/index.md +0 -11
  220. package/rules/k8s/lint/docs/lint.md +0 -413
  221. package/rules/lint/docs/fix.md +0 -25
  222. package/rules/lint/docs/index.md +0 -11
  223. package/rules/lint/fix.mjs +0 -18
  224. package/rules/lint/js/docs/index.md +0 -11
  225. package/rules/lint/js/docs/orchestrate.md +0 -31
  226. package/rules/lint/meta.json +0 -1
  227. package/rules/nginx-default-tpl/fix.mjs +0 -18
  228. package/rules/npm-module/fix.mjs +0 -18
  229. package/rules/php/fix.mjs +0 -18
  230. package/rules/php/js/docs/lint.md +0 -20
  231. package/rules/php/js/lint.mjs +0 -15
  232. package/rules/php/lint/docs/index.md +0 -11
  233. package/rules/php/lint/docs/lint.md +0 -219
  234. package/rules/python/fix.mjs +0 -18
  235. package/rules/python/js/docs/lint.md +0 -21
  236. package/rules/python/js/lint.mjs +0 -14
  237. package/rules/python/lint/docs/index.md +0 -11
  238. package/rules/python/lint/docs/lint.md +0 -29
  239. package/rules/rego/fix.mjs +0 -18
  240. package/rules/rego/js/docs/lint.md +0 -21
  241. package/rules/rego/js/lint.mjs +0 -12
  242. package/rules/rego/lint/docs/index.md +0 -11
  243. package/rules/rego/lint/docs/lint.md +0 -208
  244. package/rules/rust/fix.mjs +0 -18
  245. package/rules/rust/js/docs/lint.md +0 -21
  246. package/rules/security/fix.mjs +0 -18
  247. package/rules/security/js/docs/lint.md +0 -175
  248. package/rules/security/js/lint.mjs +0 -26
  249. package/rules/style-lint/fix.mjs +0 -18
  250. package/rules/style-lint/js/docs/lint.md +0 -31
  251. package/rules/tauri/fix.mjs +0 -18
  252. package/rules/test/fix.mjs +0 -18
  253. package/rules/text/fix.mjs +0 -18
  254. package/rules/text/js/docs/lint.md +0 -23
  255. package/rules/text/js/lint.mjs +0 -15
  256. package/rules/text/lint/docs/cspell-fix.md +0 -32
  257. package/rules/text/lint/docs/index.md +0 -15
  258. package/rules/text/lint/docs/lint.md +0 -36
  259. package/rules/text/lint/docs/run-dotenv-linter.md +0 -161
  260. package/rules/text/lint/docs/run-shellcheck.md +0 -216
  261. package/rules/text/lint/docs/run-v8r.md +0 -201
  262. package/rules/tool-surface/fix.mjs +0 -18
  263. package/rules/vue/fix.mjs +0 -18
  264. package/rules/worktree/fix.mjs +0 -18
  265. /package/rules/release/{fix.mjs → main.mjs} +0 -0
  266. /package/rules/text/{lint → js}/cspell-fix.mjs +0 -0
  267. /package/rules/text/{lint → js}/run-dotenv-linter.mjs +0 -0
  268. /package/rules/text/{lint → js}/run-shellcheck.mjs +0 -0
  269. /package/rules/text/{lint → js}/run-v8r.mjs +0 -0
@@ -3,27 +3,27 @@ type: JS Module
3
3
  title: run-lint-step.mjs
4
4
  resource: npm/scripts/lib/run-lint-step.mjs
5
5
  docgen:
6
- crc: 5932fa98
6
+ crc: f37a61b9
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
7
9
  ---
8
10
 
9
- Цей файл забезпечує спільний хелпер для запуску окремих кроків у ланцюжку linting, що використовується CLI-обгортками. Він імітує прямий виклик команд у shell, логуючи команди та перенаправляючи stdout/stderr на користувацькі stream-и. Це дозволяє уникнути дублювання обгорток у різних `rules/<id>/js/lint.mjs` файлах.
11
+ Спільний хелпер для CLI-обгорток `lint-<rule>`. Він запускає один крок ланцюжка з логуванням команди та прокидає stdout/stderr на користувацькі stream (`stdio: 'inherit'`). Це дозволяє rule-адаптерам `n-cursor lint <rule>` уникнути дублювання логіки обгортки у файлах `rules/<id>/js/lint.mjs`. Функція не виконує операцій з файловою системою чи базою даних.
10
12
 
11
13
  ## Поведінка
12
14
 
13
- 1. Записує в лог повідомлення про початок виконання кроку ланцюжка з описом команди та її аргументів.
14
- 2. Визначає шлях до виконуваного файлу команди на основі її імені.
15
- 3. Якщо шлях не знайдено в системному PATH, записує повідомлення про помилку та повертає код 127.
16
- 4. Запускає визначену команду з заданими аргументами, передаючи стандартний потік введення/виведення (stdio) потокам користувача.
17
- 5. Якщо команда завершилася з помилкою, записує повідомлення про помилку та повертає код 1.
18
- 6. Якщо команда завершилася успішно, повертає код виходу дочірнього процесу, який дорівнює 0, якщо все добре, або 1, якщо виникла помилка.
15
+ 1. Викликається `runLintStep` для запуску одного кроку ланцюжка лінтування.
16
+ 2. Виводиться у консоль повідомлення про запуск команди з вказаним заголовком.
17
+ 3. Визначається повний шлях до команди.
18
+ 4. Якщо повний шлях до команди не знайдено в PATH, виводиться повідомлення про помилку, і функція повертає код 127.
19
+ 5. Запускається дочірній процес з успадкованими потоками виводу та помилки.
20
+ 6. Якщо виникає помилка при запуску процесу, виводиться повідомлення про помилку, і функція повертає код 1.
21
+ 7. Якщо процес успішно запущено, функція повертає код виходу дочірнього процесу.
19
22
 
20
23
  ## Публічний API
21
24
 
22
- runLintStep — запускає процес linting та перевіряє його успішність.
25
+ runLintStep — запускає один етап перевірки коду, знаходячи відповідну команду в системному шляху та виконуючи її з передаченим вхідно-вихідним потоком.
23
26
 
24
27
  ## Гарантії поведінки
25
28
 
26
- - Запускає один крок ланцюжка linting.
27
- - Перенаправляє stdout та stderr на користувацькі stream-и (stdio: 'inherit').
28
- - Не використовує кешування.
29
- - Не має внутрішніх приватних імен.
29
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,30 @@
1
+ ---
2
+ type: JS Module
3
+ title: run-lint.mjs
4
+ resource: npm/scripts/lib/run-lint.mjs
5
+ docgen:
6
+ crc: dd80d058
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Модуль керує вибором та виконанням правил лінтування. Він визначає набір правил для лінтування, спираючись на конфігурації `meta.json` та `.n-cursor.json`. Публічна функція `selectLintRules` вибирає та сортує ці правила на основі їхньої лінт-поверхні. Публічна функція `runLint` ініціює виконання визначеного набору правил, перевіряючи змінені файли або весь репозиторій.
14
+
15
+ ## Поведінка
16
+
17
+ selectLintRules вибирає і алфавітно сортує ідентифікатори правил для лінтування на основі їхньої лінт-поверхні та наявності в активних конфігураціях.
18
+ runLint запускає лінт-оркестрацію, виконуючи перевірку змінених файлів або повний прогін репозиторію, залежно від наданих опцій.
19
+
20
+ ## Публічний API
21
+
22
+ selectLintRules — обирає ідентифікатори правил для контексту, розташовуючи їх в алфавітному порядку.
23
+ runLint — ініціює процес лінтування.
24
+ full — сканує весь репозиторій, порівнюючи його з початковим станом.
25
+ readOnly — лише виявляє проблеми без внесення змін.
26
+ rules — виконує повне сканування репозиторію, застосовуючи лише вказаний набір правил.
27
+
28
+ ## Гарантії поведінки
29
+
30
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -3,22 +3,26 @@ type: JS Module
3
3
  title: run-rule-cli.mjs
4
4
  resource: npm/scripts/lib/run-rule-cli.mjs
5
5
  docgen:
6
- crc: 264e7ab0
7
- score: 100
6
+ crc: 1251c4d0
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 95
8
9
  ---
9
10
 
10
- Файл є автономним CLI-запускачем для одного правила. Він друкує звіт про перевірку та повертає агрегований код виходу. Whitelist-гейту тут немає: гейтинг активних правил живе виключно у `resolveCheckRuleIds` (селекція за `.n-cursor.json`), а прямий запуск файлу правила — свідома debug/override-дія, тож виконується беззастережно.
11
+ ## Огляд
12
+
13
+ Standalone CLI runner для одного правила. Викликається з `rules/<id>/check.mjs` у блоці `if (import.meta.main)`, що робить його повним еквівалентом `bun rules/<id>/check.mjs` або `npx @nitra/cursor fix <id>`. Цей запуск є свідомим (debug / override) і виконується без whitelist-гейту. Ініціалізує кеш для проходження файлової системи та виконує стандартну перевірку, друкуючи summary результату та повертаючи aggregated exit-code.
11
14
 
12
15
  ## Поведінка
13
16
 
14
- 1. Викликається для запуску правила.
15
- 2. Друкує повідомлення про перевірку правила.
16
- 3. Використовує кеш для перевірки.
17
- 4. Викликає функцію для виконання стандартного правила з кешем.
18
- 5. Повертає агрегований код виходу.
17
+ 1. Викликається для виконання одного правила у режимі командного рядка.
18
+ 2. Визначається ідентифікатор правила на основі шляху до директорії правила.
19
+ 3. Виводиться повідомлення про початок перевірки для цього правила.
20
+ 4. Ініціалізується кеш для проходження файлової системи.
21
+ 5. Виконується стандартна перевірка для правила, використовуючи ініціалізований кеш.
22
+ 6. Виводиться підсумок результату перевірки.
23
+ 7. Повертається код виходу, що відображає успішність або наявність порушень.
19
24
 
20
25
  ## Гарантії поведінки
21
26
 
22
- - Read-only: файл не виконує операцій запису у файлову систему.
27
+ - Read-only: не виконує операцій запису (ФС/БД).
23
28
  - Кешує результати в межах одного прогону.
24
- - Не звертається до мережі.
@@ -3,24 +3,41 @@ type: JS Module
3
3
  title: run-standard-lint.mjs
4
4
  resource: npm/scripts/lib/run-standard-lint.mjs
5
5
  docgen:
6
- crc: e7e3f0ae
6
+ crc: 2b275963
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 90
7
9
  ---
8
10
 
9
- Файл забезпечує централізовану точку запуску для підкоманд `lint-<rule>` у `@nitra/cursor`. Він серіалізує та дедублює запуски, використовуючи `withLock`, щоб гарантувати узгодженість та ефективність. Це дозволяє легко інтегрувати нові правила та обробляти крос-cutting концерни, не вносячи змін у окремі файли правил.
11
+ ## Огляд
12
+
13
+ Спільна точка входу для канонічних `lint-<rule>` підкоманд `@nitra/cursor`. Файл серіалізує та дедуплікує запуски лінту через `withLock`. `ruleId` визначається зі шляху незалежно від глибини виклику (наприклад, `rules/<id>`). Це дозволяє уніфікувати крос-cutting концерни. Інтеграція з боку правила виглядає так:
14
+ * import { runStandardLint } from '../../scripts/lib/run-standard-lint.mjs'
15
+ *
16
+ * async function runLintFooSteps { ... }
17
+ *
18
+ * export function lint { return runStandardLint }
10
19
 
11
20
  ## Поведінка
12
21
 
13
- runLintFooCli: Запускає лінт для правила, використовуючи `runStandardLint`.
14
- runStandardLint: Серіалізує та дедуплікує запуск лінту, використовуючи блокування. Визначає ідентифікатор правила з шляху.
22
+ lint: Викликає стандартизований лінт, використовуючи шлях каталогу правила для визначення його ідентифікатора.
23
+ runStandardLint: Серіалізує та дедуплікує запуск лінту для заданого правила, використовуючи ідентифікатор, виведений зі шляху каталогу правила.
15
24
 
16
25
  ## Публічний API
17
26
 
18
- - runLintFooCli Перевіряє код на відповідність стандартам Foo CLI.
19
- - runStandardLint — Перевіряє код на відповідність загальним стандартам кодування.
27
+ lintє спільною точкою входу для канонічних `lint-<rule>` підкоманд `@nitra/cursor`. Він ініціює серіалізацію та дедуплікацію запусків лінтингу для вказаних файлів, забезпечуючи централізоване управління крос-cutting концернами.
28
+
29
+ runStandardLint — виконує стандартний лінтинг у директорії, приймаючи контекст директорії та функцію, що описує кроки лінтингу.
30
+
31
+ Приклад інтеграції:
32
+ ```js
33
+ import { runStandardLint } from '../../scripts/lib/run-standard-lint.mjs'
34
+
35
+ async function runLintFooSteps { ... }
36
+
37
+ export function lint { return runStandardLint }
38
+ ```
20
39
 
21
40
  ## Гарантії поведінки
22
41
 
23
- - Приймає `ruleId` з шляху файлу.
24
- - Створює блокування з іменем `lint-<ruleId>`.
25
- - Використовує попередньо збережені результати для уникнення повторного виконання.
26
- - Повертає результат виконання.
42
+ - Read-only: не виконує операцій запису (ФС/БД).
43
+ - Кешує результати в межах одного прогону.
@@ -3,23 +3,24 @@ type: JS Module
3
3
  title: run-standard-rule.mjs
4
4
  resource: npm/scripts/lib/run-standard-rule.mjs
5
5
  docgen:
6
- crc: c1ae8f0e
7
- score: 90
6
+ crc: 0c3b2e60
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 70
8
9
  ---
9
10
 
10
- Файл інкапсулює оркестрацію виконання правил. Він забезпечує запуск правила через визначений шлях, ізолюючи його виконання у блоці `withLock` для уникнення паралельних запусків.
11
+ ## Огляд
12
+
13
+ Файл надає публічний API для оркестрації правил, який викликається з `rules/<id>/check.mjs`. Він інкапсулює логіку пошуку єдиного правила (`discoverOneRule`) та його виконання (`runRule`). Виконання обертається у `withLock` для дедуплікації паралельних запусків того самого правила на основі стану git-дерева. Локальна логіка в правилах заборонена; розширення поведінки відбувається через `ctx`-опції. Це централізована точка для запуску стандартних правил з кешуванням у межах одного прогону.
11
14
 
12
15
  ## Поведінка
13
16
 
14
- 1. Отримання шляху до правила
15
- 2. Визначення ідентифікатора правила
16
- 3. Охоплення виконання у блоці блокування
17
- 4. Пошук правила
18
- 5. Отримання кешу проходу
19
- 6. Запуск виконання правила
17
+ 1. Викликати `runStandardRule` для певного правила.
18
+ 2. Забезпечити унікальну блокування для виконання цього правила, використовуючи його ID.
19
+ 3. Виявити єдине правило, пов'язане з наданим шляхом.
20
+ 4. Отримати або створити кеш для прогону.
21
+ 5. Виконати правило, використовуючи виявлене правило, шлях до пакету та кеш прогону.
20
22
 
21
23
  ## Гарантії поведінки
22
24
 
23
- - Read-only: файл не виконує операцій запису у файлову систему.
25
+ - Read-only: не виконує операцій запису (ФС/БД).
24
26
  - Кешує результати в межах одного прогону.
25
- - Не звертається до мережі.
@@ -3,26 +3,25 @@ type: JS Module
3
3
  title: timing-summary.mjs
4
4
  resource: npm/scripts/lib/timing-summary.mjs
5
5
  docgen:
6
- crc: f21a9b91
6
+ crc: ee74c1cd
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
7
9
  ---
8
10
 
9
- Цей файл генерує табличне резюме часу виконання для команд `fix` та `lint`, які використовуються в orchestrator. Він підсумовує час виконання окремих правил та скриптів linting, надаючи інформацію для аналізу продуктивності. Результат представлений у вигляді рядка, який можна вивести для відображення користувачеві.
11
+ ## Огляд
12
+
13
+ Формує таблицю-резюме часу виконання для оркестратора `fix` або `lint`. Таблиця використовується після прогону всіх правил перевірки (`runFixCommand` у `bin/n-cursor.js`) або після прогону скриптів лінтингу (`runLintCli` у `scripts/lib/run-lint-cli.mjs`), які визначаються у `package.json`. Звіт містить деталі часу виконання для кожного елемента у форматі `<ціла>.<десята>s`, а маркер `❌` на рядку вказує на невдачу (`ok === false`).
10
14
 
11
15
  ## Поведінка
12
16
 
13
- formatDurationMs: Перетворює мілісекунди на рядок у форматі `<ціла>.<десята>s`.
14
- formatTimingSummary: Формує таблицю-резюме часу виконання з масиву записів, виводячи їх у текстовому форматі.
17
+ formatDurationMs перетворює тривалість у мілісекундах у рядок формату `<ціла>.<десята>s`.
18
+ formatTimingSummary генерує багаторядковий текст таблиці-резюме часу виконання на основі наданого заголовка та списку записів про час.
15
19
 
16
20
  ## Публічний API
17
21
 
18
- - formatDurationMs Форматує значення тривалості в форматі `<сек>.<десята>с`. Округлення виконується вниз (floor), щоб забезпечити консистентність результатів незалежно від платформи.
19
- - formatTimingSummary Створює багаторядковий текст у форматі таблиці-резюме для виведення в консоль (stdout).
22
+ formatDurationMs: Перетворює мілісекунди на формат `<sec>.<десята>s`, використовуючи округлення вниз.
23
+ formatTimingSummary: Генерує багаторядковий вивід у форматі таблиці-резюме для стандартного виводу.
20
24
 
21
25
  ## Гарантії поведінки
22
26
 
23
- Якщо `ok` дорівнює `false`, повертає `null`.
24
- ❌ Якщо час виконання перевищує 5 секунд, повертає `null`.
25
- Повертає рядок, що містить таблицю з часом виконання.
26
- Час виконання виражається у форматі `<ціла>.<десята>s`.
27
- Повертає рядок з символом `\n` в кінці.
28
- Не використовує кешування.
27
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -6,11 +6,8 @@ docgen:
6
6
  crc: 1f7d5e0d
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
- judgeModel: openai-codex/gpt-5.4-mini
10
9
  ---
11
10
 
12
- ## Огляд
13
-
14
11
  Цей файл вшиває worktree-інструкцію у синкнутий `SKILL.md` (рішення D2 зі spec). Коли `meta.json.worktree === true`, скіл вставляє/замінює ідемпотентний ре-синкнутий блок, що містить маркери WORKTREE_START та WORKTREE_END, забезпечуючи виконання скілу в окремому git-worktree та запобігаючи паралелізації. Функція `injectWorktreeNotice` керує наявністю або відсутністю цього блоку в `SKILL.md` на основі конфігурації.
15
12
 
16
13
  ## Поведінка
@@ -14,5 +14,6 @@ resource: npm/scripts/lib/fix/
14
14
  | [llm-lint-fix.mjs](llm-lint-fix.md) | JS Module |
15
15
  | [llm-worker.mjs](llm-worker.md) | JS Module |
16
16
  | [orchestrator.mjs](orchestrator.md) | JS Module |
17
+ | [run-conformance-check.mjs](run-conformance-check.md) | JS Module |
17
18
  | [run-fix-check.mjs](run-fix-check.md) | JS Module |
18
19
  | [t0.mjs](t0.md) | JS Module |
@@ -3,34 +3,39 @@ type: JS Module
3
3
  title: orchestrator.mjs
4
4
  resource: npm/scripts/lib/fix/orchestrator.mjs
5
5
  docgen:
6
- crc: d327ab6d
6
+ crc: fbc91330
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
- Модуль керує процесом валідації та виправлення конформності правил. Він перевіряє правила, застосовує детермінований механізм (T0), а нерозв'язані порушення проводить по **драбині ескалації моделей**: локальна min-модель → той самий локальний тир із feedback → хмарна min → хмарна avg. Кожен крок драбини логується для подальшого аналізу. Функція `runOrchestratorCli` запускає процес.
11
+ ## Огляд
12
+
13
+ Модуль керує процесом вирішення порушень за допомогою багаторівневої системи ескалації. Він збирає послідовність рівнів моделей, починаючи з локальних і закінчуючи хмарними. Модуль парсить параметри запуску за допомогою `parseOrchestratorArgs` та виконує повний цикл фіксації, застосовуючи детермінований фікс. Для невирішених проблем застосовується ескалація правил через `escalateRule`, а фінальний запуск оркестратора здійснюється через `runOrchestratorCli`, який використовує структуру, побудовану за допомогою `buildLadder`.
12
14
 
13
15
  ## Поведінка
14
16
 
15
- 1. `runOrchestratorCli` виконує початкову перевірку правил. Якщо порушень немає успіх.
16
- 2. Один прохід детермінованого фіксу (T0) зменшує набір порушень без LLM.
17
- 3. `buildLadder` будує драбину з доступних тирів (`N_LOCAL_MIN_MODEL`, `N_CLOUD_MIN_MODEL`, `N_CLOUD_AVG_MODEL`); незадані тири відсіюються. Якщо драбина порожня — процес завершується з ознакою нерозв'язаних порушень.
18
- 4. `escalateRule` проводить кожне правило по драбині до першого зеленого re-check:
19
- - рунг `local-min` — перший прохід без feedback;
20
- - рунг `local-min-retry` — той самий локальний тир, але з feedback попереднього рунга (попередні зміни + залишковий violation);
21
- - рунги `cloud-min` / `cloud-avg` — хмарні моделі (через pi), теж із feedback.
22
- Кожен рунг має per-tier `timeoutMs`: локальні **fail-fast** (`N_LOCAL_FIX_TIMEOUT_MS`, дефолт 45s — не палити стіну 120s на повільному локальному inference), хмарні — повний (`N_CLOUD_FIX_TIMEOUT_MS`, дефолт 120s).
23
- 5. Достроковий вихід драбини: systemic-помилка локального тиру пропускає рунги тієї ж моделі; відсутній API-ключ на хмарному обриває драбину; хмарний транспортний збій (pi таймаут/spawn) обриває драбину, щоб не палити avg-бюджет на ту саму стіну; вичерпаний avg-кеп пропускає avg-рунг (із записом у лог).
24
- 6. Після обробки всіх правил — фінальна перевірка. Усі чисті → успіх; інакше — ознака нерозв'язаних.
17
+ buildLadder будує послідовність тирів ескалації для вирішення порушень, від локальних мінімальних моделей до хмарних середніх моделей.
18
+ escalateRule проводить один прохід по послідовності тирів, намагаючись вирішити порушення, і повертає статус вирішення та використаний бюджет хмарних викликів.
19
+ parseOrchestratorArgs парсить аргументи командного рядка для визначення максимального бюджету хмарних викликів та фільтра правил.
20
+ runOrchestratorCli виконує повний цикл фіксації: перевіряє правила, застосовує детермінований фікс (T0-auto), а потім використовує LLM-драбину ескалації для невирішених порушень.
25
21
 
26
22
  ## Публічний API
27
23
 
28
- - `buildLadder({ localMin, cloudMin, cloudAvg })` будує драбину рунгів із наявних тирів.
29
- - `escalateRule(rule, cwd, deps)` — проводить одне правило по драбині; повертає `{ resolved, avgUsed }`. Залежності (`worker`, `check`, `clock`) інжектовні для тестів.
30
- - `parseOrchestratorArgs(args)` парсить `--max-avg N` (кеп на хмарні avg-виклики) і фільтр правил.
31
- - `runOrchestratorCli(args, cwd)` точка входу; повертає `0` (усе чисто) або `1` (нерозв'язані).
24
+ buildLadder Створює послідовність моделей для ескалації, виходячи з доступних рівнів.
25
+
26
+ local-minЗапускає первинний прохід з найменшою локальною моделлю.
27
+ local-min-retryПовторює локальний прохід, використовуючи відгук від попереднього кроку.
28
+ cloud-min — Запускає прохід з найменшою хмарною моделлю, використовуючи відгук.
29
+ cloud-avg — Запускає прохід з середньою хмарною моделлю, використовуючи відгук та обмеження середнього.
30
+
31
+ escalateRule — Виконує одне правило по драбині ескалації до першого успішного перевірки.
32
+ Кожен рунг — Запускає роботу моделі з урахуванням попереднього відгуку, перевіряє правило, фіксує результат у лозі.
33
+ Достроковий вихід — Зупиняє процес при певних умовах (відсутність ключа, пропуск моделі на системному рівні) або при досягненні ліміту середнього.
34
+
35
+ parseOrchestratorArgs — Витягує максимальне значення середнього та збирає список правил для фільтрації з командного рядка.
36
+
37
+ runOrchestratorCli — Запускає основний процес оркестрації, обробляючи аргументи та виконуючи ескалацію правил.
32
38
 
33
39
  ## Гарантії поведінки
34
40
 
35
- - Кожен рунг драбини дописується в escalation-лог (`escalation-log.mjs`): модель, чи виклик удався, чи правило стало зеленим, залишковий violation і само-аналіз моделі.
36
- - Звертається до мережі лише на хмарних рунгах драбини (через pi).
41
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,32 @@
1
+ ---
2
+ type: JS Module
3
+ title: run-conformance-check.mjs
4
+ resource: npm/scripts/lib/fix/run-conformance-check.mjs
5
+ docgen:
6
+ crc: 7a026c26
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 90
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Модуль реалізує прямий механізм виконання конформності, викликаючи конформність-фазу `lint`, движок (`orchestrator.mjs`, `t0.mjs`) та PostToolUse-хук. Селекція активних правил здійснюється на основі конфігурації `.n-cursor.json`. Для забезпечення ізоляції, кожен обраний `entrypoint rules/<id>/main.mjs` запускається окремим процесом `bun`.
14
+
15
+ ## Поведінка
16
+
17
+ resolveCheckRuleIds визначає набір ID правил для прогону, використовуючи `.n-cursor.json` як єдине джерело правди для селекції. Якщо запитані правила надані, вони фільтруються за активністю; інакше, він вибирає активні правила з конфігурації, або, за відсутності конфігурації, використовує зматеріалізовані файли `.cursor/rules/*.mdc` для режиму відладки.
18
+
19
+ runConformanceCheck виконує перевірку конформності для кожного правила, яке було визначено як активне. Він запускає кожен `check.mjs` окремим процесом `bun` для ізоляції та повертає загальну кількість виконаних, успішних та невдалих перевірок.
20
+
21
+ ## Публічний API
22
+
23
+ resolveCheckRuleIds — Визначає, які правила будуть застосовані для перевірки, використовуючи `.n-cursor.json` як основне джерело:
24
+ * Якщо вказані правила, вони фільтруються до активних у конфігурації.
25
+ * Якщо правила не вказані, беруться всі активні правила з конфігу.
26
+ * Якщо правила не вказані і конфіг відсутній, використовується список правил, що були збережені локально.
27
+
28
+ runConformanceCheck — Виконує перевірку відповідності для кожного окремого правила без внесення змін.
29
+
30
+ ## Гарантії поведінки
31
+
32
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -3,26 +3,27 @@ type: JS Module
3
3
  title: t0.mjs
4
4
  resource: npm/scripts/lib/fix/t0.mjs
5
5
  docgen:
6
- crc: 524d91e2
6
+ crc: 49c0669b
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
- Модуль керує детермінованим (без LLM) застосуванням паттернів до виводів порушень конформності. Паттерни: `vscode-ext-add` (дописати розширення), `rm-forbidden-file` (видалити заборонений файл), `changelog-create-change-file` (створити change-файл через канонічну `writeChange` для воркспейсів із «немає change-файлу» — прибирає ескалацію в LLM на цьому кейсі). `filterT0AutoRules` визначає, які правила мають придатний паттерн; `applyT0Auto`/`runT0AutoCli` застосовують. Паттерн може бути sync або async (await нормалізує). Fail-safe: помилки перехоплюються.
11
+ ## Огляд
12
+
13
+ Модуль керує автоматичним застосуванням T0-auto паттернів до виводів порушень. Він визначає, які правила можуть бути оброблені автоматично, використовуючи конфігурації з `extensions.json` та `package-lock.json`. Функціонал реалізовано через публічні функції: `filterT0AutoRules` для визначення правил, `applyT0Auto` для автоматичного застосування паттернів до виводів, та `runT0AutoCli` для запуску процесу. Модуль працює у режимі fail-safe, перехоплюючи помилки та не кидаючи винятків назовні, надаючи звіт про застосовані автоматичні виправлення.
12
14
 
13
15
  ## Поведінка
14
16
 
15
- applyT0Auto застосовує придатні паттерни до одного виводу порушення (await на apply — паттерн може бути async, як `changelog-create-change-file`).
16
- filterT0AutoRules повертає id правил, для яких існує придатний паттерн.
17
- runT0AutoCli запускає T0-auto для всіх провальних правил, повторно перевіряє check-gate і виводить підсумок.
17
+ applyT0Auto застосовує всі визначені T0-auto паттерни до одного виводу порушення, повертаючи результат застосування.
18
+ filterT0AutoRules повертає список ID правил, для яких існує хоча б один T0-auto паттерн, виходячи з виводів порушень.
19
+ runT0AutoCli запускає T0-auto для кожного провального правила, повторно перевіряє конформність та виводить підсумок.
18
20
 
19
21
  ## Публічний API
20
22
 
21
- applyT0Auto — Впроваджує всі шаблони T0-auto до одного результату виявлених проблем.
22
- filterT0AutoRules — Визначає, які правила мають хоча б один шаблон T0-auto, виходячи з результату `fix --json`.
23
- runT0AutoCli — Запускає команду `n-cursor fix-t0 [rule...]`, виконує `fix --json`, застосовує T0-auto до кожної проблеми, повторно перевіряє check-gate та надає звіт.
23
+ applyT0Auto — вносить зміни до виводу порушень, використовуючи всі визначені T0-auto шаблони.
24
+ filterT0AutoRules — визначає, які правила мають принаймні один T0-auto шаблон, ґрунтуючись на виводі порушень у форматі JSON.
25
+ runT0AutoCli — виконує команду `n-cursor fix-t0 [rule...]`, яка застосовує T0-auto до кожного порушення, повторно перевіряє check-gate та надає звіт.
24
26
 
25
27
  ## Гарантії поведінки
26
28
 
27
29
  - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
28
- - Не звертається до мережі.
@@ -1,7 +1,7 @@
1
1
  /** @see ./docs/orchestrator.md */
2
2
 
3
3
  import { env } from 'node:process'
4
- import { runFixCheck } from './run-fix-check.mjs'
4
+ import { runConformanceCheck } from './run-conformance-check.mjs'
5
5
  import { runT0AutoCli } from './t0.mjs'
6
6
  import { logEscalation } from './escalation-log.mjs'
7
7
  import { runLlmWorker } from './llm-worker.mjs'
@@ -165,7 +165,7 @@ export function parseOrchestratorArgs(args) {
165
165
  async function runT0Step(cwd, ruleFilter, failed) {
166
166
  await runT0AutoCli([...ruleFilter], cwd)
167
167
 
168
- const afterT0 = await runFixCheck(ruleFilter, cwd)
168
+ const afterT0 = await runConformanceCheck(ruleFilter, cwd)
169
169
  const failedAfterT0 = afterT0.rules.filter(r => !r.ok)
170
170
  const t0Fixed = failed.filter(r => !failedAfterT0.some(f => f.ruleId === r.ruleId))
171
171
 
@@ -186,7 +186,7 @@ export async function runOrchestratorCli(args, cwd) {
186
186
  const ladder = buildLadder({ localMin: LOCAL_MIN, cloudMin: CLOUD_MIN, cloudAvg: CLOUD_AVG })
187
187
 
188
188
  // ── Перша перевірка (тихо) ──
189
- const initial = await runFixCheck(ruleFilter, cwd)
189
+ const initial = await runConformanceCheck(ruleFilter, cwd)
190
190
  let failed = initial.rules.filter(r => !r.ok)
191
191
  const total = initial.total
192
192
 
@@ -220,14 +220,14 @@ export async function runOrchestratorCli(args, cwd) {
220
220
  const { avgUsed } = await escalateRule(rule, cwd, {
221
221
  ladder,
222
222
  worker,
223
- check: runFixCheck,
223
+ check: runConformanceCheck,
224
224
  avgBudget
225
225
  })
226
226
  avgBudget -= avgUsed
227
227
  }
228
228
 
229
229
  // ── Фінальна перевірка ──
230
- const finalCheck = await runFixCheck(ruleFilter, cwd)
230
+ const finalCheck = await runConformanceCheck(ruleFilter, cwd)
231
231
  const stillFailed = finalCheck.rules.filter(r => !r.ok)
232
232
  if (stillFailed.length === 0) {
233
233
  console.log(`✅ fix: ${total} правил — все чисто`)
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Конформність-детект (колишній subcommand `_fix-check`) як ПРЯМА функція — без subprocess-обгортки
3
- * `bun n-cursor.js _fix-check`. Викликають конформність-фаза `lint` (read-only), движок
4
- * (`orchestrator.mjs`, `t0.mjs`) і PostToolUse-хук.
2
+ * Конформність-детект як ПРЯМА функція — без subprocess-обгортки.
3
+ * Викликають конформність-фаза `lint` (read-only), движок (`orchestrator.mjs`, `t0.mjs`)
4
+ * і PostToolUse-хук.
5
5
  *
6
- * Per-rule ізоляція зберігається: кожне `rules/<id>/fix.mjs` усе ще запускається окремим
7
- * процесом `bun` (crash-isolation). Прибрано лише зовнішній wrapper-subprocess, що його
8
- * раніше шелили оркестратор/хук.
6
+ * Per-rule ізоляція зберігається: entrypoint `rules/<id>/main.mjs` кожного правила
7
+ * запускається окремим процесом `bun` (crash-isolation). Канон єдиний `main.mjs`
8
+ * (ADR 2026-06-21); його CLI-блок кличе `runRuleCli(import.meta.dirname)`.
9
9
  *
10
10
  * Селекція активних правил — виключно тут (`resolveCheckRuleIds` за `.n-cursor.json`);
11
11
  * per-rule whitelist у спавнених процесах прибрано як дубль (див. `runRuleCli`).
@@ -21,7 +21,7 @@ import { discoverCheckRulesFromCursorRules } from '../discover-check-rules-from-
21
21
  import { listProjectRulesMdcFiles } from '../list-project-rules-mdc.mjs'
22
22
  import { isRuleEnabled, readNCursorConfigLite } from '../read-n-cursor-config-lite.mjs'
23
23
 
24
- // Цей файл: npm/scripts/lib/fix/run-fix-check.mjs → npm/rules (чотири dirname угору + rules).
24
+ // Цей файл: npm/scripts/lib/fix/run-conformance-check.mjs → npm/rules (чотири dirname угору + rules).
25
25
  const BUNDLED_RULES_DIR = join(dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url))))), 'rules')
26
26
 
27
27
  /**
@@ -61,16 +61,16 @@ export async function resolveCheckRuleIds(requestedRules, available, cwd) {
61
61
  }
62
62
 
63
63
  /**
64
- * Прогоняє `fix.mjs` кожного правила окремим процесом, захоплюючи output.
64
+ * Прогоняє check-entrypoint кожного правила окремим процесом, захоплюючи output.
65
65
  * @param {string[]} idsToRun правила
66
66
  * @param {string} cwd корінь
67
67
  * @returns {{ totalFailed:number, rules:Array<{ruleId:string, ok:boolean, output:string}> }} результат
68
68
  */
69
- function runRuleFixProcesses(idsToRun, cwd) {
69
+ function runRuleCheckProcesses(idsToRun, cwd) {
70
70
  let totalFailed = 0
71
71
  const rules = []
72
72
  for (const id of idsToRun) {
73
- const r = spawnSync('bun', [join(BUNDLED_RULES_DIR, id, 'fix.mjs')], { cwd, encoding: 'utf8' })
73
+ const r = spawnSync('bun', [join(BUNDLED_RULES_DIR, id, 'main.mjs')], { cwd, encoding: 'utf8' })
74
74
  const ok = r.status === 0
75
75
  rules.push({ ruleId: id, ok, output: `${r.stdout ?? ''}${r.stderr ?? ''}`.trim() })
76
76
  if (!ok) totalFailed++
@@ -79,12 +79,12 @@ function runRuleFixProcesses(idsToRun, cwd) {
79
79
  }
80
80
 
81
81
  /**
82
- * Конформність-детект: per-rule `fix.mjs run()` (= перевірка, без мутацій).
82
+ * Конформність-детект: per-rule `check.mjs run()` (= перевірка, без мутацій).
83
83
  * @param {string[]} [requestedRules] фільтр (порожній → discovery з `.cursor/rules/`)
84
84
  * @param {string} [cwd] корінь
85
85
  * @returns {Promise<{ total:number, failed:number, rules:Array<{ruleId:string, ok:boolean, output:string}> }>} результат
86
86
  */
87
- export async function runFixCheck(requestedRules = [], cwd = processCwd()) {
87
+ export async function runConformanceCheck(requestedRules = [], cwd = processCwd()) {
88
88
  ensureTool('conftest')
89
89
  const available = await listRuleIds(BUNDLED_RULES_DIR)
90
90
  if (available.length === 0) return { total: 0, failed: 0, rules: [] }
@@ -92,6 +92,6 @@ export async function runFixCheck(requestedRules = [], cwd = processCwd()) {
92
92
  const idsToRun = await resolveCheckRuleIds(requestedRules, available, cwd)
93
93
  if (idsToRun.length === 0) return { total: 0, failed: 0, rules: [] }
94
94
 
95
- const { totalFailed, rules } = runRuleFixProcesses(idsToRun, cwd)
95
+ const { totalFailed, rules } = runRuleCheckProcesses(idsToRun, cwd)
96
96
  return { total: idsToRun.length, failed: totalFailed, rules }
97
97
  }
@@ -3,7 +3,7 @@ import { spawnSync } from 'node:child_process'
3
3
  import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
4
4
  import { join } from 'node:path'
5
5
 
6
- import { runFixCheck } from './run-fix-check.mjs'
6
+ import { runConformanceCheck } from './run-conformance-check.mjs'
7
7
  import { writeChange } from '../../../rules/release/change.mjs'
8
8
 
9
9
  const REC_REQUIRE_RE = /recommendations має містити "[^"]+"/
@@ -188,7 +188,7 @@ export async function runT0AutoCli(args, cwd) {
188
188
  const verbose = args.includes('--verbose') || args.includes('-v')
189
189
 
190
190
  // 1. Конформність-детект (пряма функція, без subprocess)
191
- const fixJson = await runFixCheck(ruleFilter, cwd)
191
+ const fixJson = await runConformanceCheck(ruleFilter, cwd)
192
192
  const failed = fixJson.rules.filter(r => !r.ok)
193
193
  if (failed.length === 0) {
194
194
  console.log(`✅ fix-t0: всі правила чисті — T0 не потрібен`)
@@ -210,7 +210,7 @@ export async function runT0AutoCli(args, cwd) {
210
210
  }
211
211
 
212
212
  // 4. Check-gate: перевірити лише ті правила, що ми чіпали
213
- const recheckJson = await runFixCheck(applied.map(a => a.ruleId), cwd)
213
+ const recheckJson = await runConformanceCheck(applied.map(a => a.ruleId), cwd)
214
214
  const stillFailed = recheckJson.rules.filter(r => !r.ok)
215
215
 
216
216
  if (verbose) {
@@ -135,7 +135,7 @@ export function verifyLintJsWorkflowStructure(root) {
135
135
  }
136
136
 
137
137
  /**
138
- * Чи є в будь-якому `run` кроку підрядок (наприклад `bun run lint-text`).
138
+ * Чи є в будь-якому `run` кроку підрядок (наприклад `n-cursor lint text --read-only`).
139
139
  * @param {Record<string, unknown>} root корінь workflow
140
140
  * @param {string} needle підрядок для пошуку
141
141
  * @returns {boolean} `true`, якщо хоча б один `run` містить `needle`
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Список `.mdc`-файлів правил у `.cursor/rules/` проєкту-споживача (відсортований).
3
- * Винесено зі `bin/n-cursor.js`, щоб ділити між CLI-dispatch і `run-fix-check` (конформність-детект).
3
+ * Винесено зі `bin/n-cursor.js`, щоб ділити між CLI-dispatch і `run-conformance-check` (конформність-детект).
4
4
  */
5
5
  import { existsSync } from 'node:fs'
6
6
  import { readdir } from 'node:fs/promises'
@@ -1,12 +1,21 @@
1
1
  /**
2
- * Перебір `rules/<id>/` директорій з фільтром на наявність `fix.mjs`.
3
- * Після атомарної міграції `fix.mjs` обов'язковий у кожному правилі каталог без нього
2
+ * Перебір `rules/<id>/` директорій з фільтром на наявність entrypoint-а.
3
+ * Канон (ADR 2026-06-21): єдиний entrypoint `rules/<id>/main.mjs`. Каталог без нього
4
4
  * пропускається (це not-a-rule або заглушка).
5
5
  */
6
6
  import { existsSync } from 'node:fs'
7
7
  import { readdir } from 'node:fs/promises'
8
8
  import { join } from 'node:path'
9
9
 
10
+ /**
11
+ * Чи має каталог правила entrypoint `main.mjs`.
12
+ * @param {string} ruleDir абсолютний шлях `rules/<id>/`
13
+ * @returns {boolean} true, якщо `main.mjs` існує
14
+ */
15
+ function hasEntrypoint(ruleDir) {
16
+ return existsSync(join(ruleDir, 'main.mjs'))
17
+ }
18
+
10
19
  /**
11
20
  * @param {string} bundledRulesDir абсолютний шлях до `npm/rules/`
12
21
  * @param {string} [filter] id одного правила (через `--rule abie`)
@@ -17,7 +26,7 @@ export async function listRuleIds(bundledRulesDir, filter) {
17
26
  const ids = entries
18
27
  .filter(e => e.isDirectory() && !e.name.startsWith('.'))
19
28
  .map(e => e.name)
20
- .filter(id => existsSync(join(bundledRulesDir, id, 'fix.mjs')))
29
+ .filter(id => hasEntrypoint(join(bundledRulesDir, id)))
21
30
  .filter(id => filter === undefined || id === filter)
22
31
  return ids.toSorted((a, b) => a.localeCompare(b))
23
32
  }