@nitra/cursor 12.6.1 → 12.8.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 (372) hide show
  1. package/.claude-template/settings.template.json +1 -1
  2. package/.pi-template/extensions/n-cursor-adr/docs/index.md +2 -2
  3. package/CHANGELOG.md +25 -5
  4. package/bin/docs/n-cursor.md +4 -20
  5. package/bin/n-cursor.js +8 -54
  6. package/docs/index.md +3 -3
  7. package/docs/stryker.config.md +20 -28
  8. package/lib/docs/index.md +5 -5
  9. package/lib/docs/llm.md +4 -4
  10. package/package.json +2 -2
  11. package/rules/abie/docs/fix.md +8 -8
  12. package/rules/abie/docs/index.md +4 -3
  13. package/rules/abie/docs/main.md +29 -0
  14. package/rules/abie/js/docs/index.md +6 -6
  15. package/rules/abie/lib/docs/index.md +9 -9
  16. package/rules/abie/{fix.mjs → main.mjs} +5 -3
  17. package/rules/adr/docs/index.md +1 -0
  18. package/rules/adr/docs/main.md +29 -0
  19. package/rules/adr/{fix.mjs → main.mjs} +5 -3
  20. package/rules/bun/docs/fix.md +5 -5
  21. package/rules/bun/docs/index.md +4 -3
  22. package/rules/bun/docs/main.md +30 -0
  23. package/rules/bun/js/docs/index.md +2 -2
  24. package/rules/bun/js/docs/layout.md +11 -36
  25. package/rules/bun/{fix.mjs → main.mjs} +5 -3
  26. package/rules/capacitor/docs/fix.md +10 -10
  27. package/rules/capacitor/docs/index.md +4 -3
  28. package/rules/capacitor/docs/main.md +29 -0
  29. package/rules/capacitor/js/docs/index.md +2 -2
  30. package/rules/capacitor/{fix.mjs → main.mjs} +5 -3
  31. package/rules/changelog/docs/fix.md +11 -11
  32. package/rules/changelog/docs/index.md +4 -3
  33. package/rules/changelog/docs/main.md +27 -0
  34. package/rules/changelog/js/docs/consistency.md +12 -12
  35. package/rules/changelog/js/docs/index.md +2 -2
  36. package/rules/changelog/lib/docs/index.md +2 -2
  37. package/rules/changelog/main.mjs +20 -0
  38. package/rules/ci4/docs/fix.md +4 -4
  39. package/rules/ci4/docs/index.md +4 -3
  40. package/rules/ci4/docs/main.md +30 -0
  41. package/rules/ci4/js/docs/index.md +2 -2
  42. package/rules/ci4/main.mjs +20 -0
  43. package/rules/doc-files/docs/index.md +4 -3
  44. package/rules/doc-files/docs/main.md +31 -0
  45. package/rules/doc-files/js/docgen-crc.mjs +2 -8
  46. package/rules/doc-files/js/docgen-extract.mjs +5 -3
  47. package/rules/doc-files/js/docgen-files-batch.mjs +63 -4
  48. package/rules/doc-files/js/docgen-gen.mjs +11 -3
  49. package/rules/doc-files/js/docgen-judge-measure.mjs +67 -18
  50. package/rules/doc-files/js/docgen-judge.mjs +8 -1
  51. package/rules/doc-files/js/docgen-scan.mjs +99 -11
  52. package/rules/doc-files/js/docs/docgen-crc.md +25 -14
  53. package/rules/doc-files/js/docs/docgen-extract.md +15 -13
  54. package/rules/doc-files/js/docs/docgen-files-batch.md +15 -15
  55. package/rules/doc-files/js/docs/docgen-gen.md +15 -26
  56. package/rules/doc-files/js/docs/docgen-judge-measure.md +14 -12
  57. package/rules/doc-files/js/docs/docgen-scan.md +34 -34
  58. package/rules/doc-files/js/docs/index.md +16 -15
  59. package/rules/doc-files/js/docs/run-lint.md +27 -0
  60. package/rules/doc-files/{lint/lint.mjs → js/run-lint.mjs} +23 -9
  61. package/rules/doc-files/{js/lint.mjs → main.mjs} +60 -10
  62. package/rules/docker/docs/fix.md +6 -6
  63. package/rules/docker/docs/index.md +4 -3
  64. package/rules/docker/docs/main.md +28 -0
  65. package/rules/docker/js/docs/index.md +2 -2
  66. package/rules/docker/js/docs/lint.md +26 -54
  67. package/rules/docker/js/lint.mjs +11 -0
  68. package/rules/docker/lib/docker-hadolint.mjs +1 -1
  69. package/rules/docker/lib/docs/docker-hadolint.md +16 -173
  70. package/rules/docker/lib/docs/index.md +5 -5
  71. package/rules/docker/main.mjs +20 -0
  72. package/rules/efes/docs/fix.md +8 -8
  73. package/rules/efes/docs/index.md +4 -3
  74. package/rules/efes/docs/main.md +29 -0
  75. package/rules/efes/main.mjs +20 -0
  76. package/rules/feedback/docs/fix.md +5 -5
  77. package/rules/feedback/docs/index.md +4 -3
  78. package/rules/feedback/docs/main.md +30 -0
  79. package/rules/feedback/main.mjs +20 -0
  80. package/rules/ga/docs/fix.md +5 -5
  81. package/rules/ga/docs/index.md +4 -3
  82. package/rules/ga/docs/main.md +29 -0
  83. package/rules/ga/js/docs/index.md +3 -3
  84. package/rules/ga/{lint/lint.mjs → main.mjs} +36 -10
  85. package/rules/graphql/docs/fix.md +8 -8
  86. package/rules/graphql/docs/index.md +4 -3
  87. package/rules/graphql/docs/main.md +36 -0
  88. package/rules/graphql/js/docs/index.md +2 -2
  89. package/rules/graphql/lib/docs/index.md +2 -2
  90. package/rules/graphql/main.mjs +20 -0
  91. package/rules/hasura/docs/fix.md +11 -11
  92. package/rules/hasura/docs/index.md +4 -3
  93. package/rules/hasura/docs/main.md +30 -0
  94. package/rules/hasura/js/docs/index.md +2 -2
  95. package/rules/hasura/main.mjs +20 -0
  96. package/rules/image-avif/docs/fix.md +3 -3
  97. package/rules/image-avif/docs/index.md +4 -3
  98. package/rules/image-avif/docs/main.md +30 -0
  99. package/rules/image-avif/js/docs/avif_generation.md +20 -233
  100. package/rules/image-avif/js/docs/index.md +2 -2
  101. package/rules/image-avif/main.mjs +20 -0
  102. package/rules/image-compress/docs/fix.md +2 -2
  103. package/rules/image-compress/docs/index.md +4 -3
  104. package/rules/image-compress/docs/main.md +29 -0
  105. package/rules/image-compress/js/docs/index.md +3 -3
  106. package/rules/image-compress/js/docs/package_setup.md +12 -11
  107. package/rules/image-compress/{js/lint.mjs → main.mjs} +21 -5
  108. package/rules/js-bun-db/docs/fix.md +5 -5
  109. package/rules/js-bun-db/docs/index.md +4 -3
  110. package/rules/js-bun-db/docs/main.md +30 -0
  111. package/rules/js-bun-db/js/docs/index.md +2 -2
  112. package/rules/js-bun-db/lib/docs/index.md +2 -2
  113. package/rules/js-bun-db/main.mjs +20 -0
  114. package/rules/js-bun-redis/docs/fix.md +6 -6
  115. package/rules/js-bun-redis/docs/index.md +4 -3
  116. package/rules/js-bun-redis/docs/main.md +29 -0
  117. package/rules/js-bun-redis/js/docs/index.md +2 -2
  118. package/rules/js-bun-redis/lib/docs/index.md +2 -2
  119. package/rules/js-bun-redis/main.mjs +20 -0
  120. package/rules/js-lint/docs/fix.md +9 -9
  121. package/rules/js-lint/docs/index.md +4 -3
  122. package/rules/js-lint/docs/main.md +29 -0
  123. package/rules/js-lint/js/check.mjs +268 -0
  124. package/rules/js-lint/js/docs/check.md +39 -0
  125. package/rules/js-lint/js/docs/index.md +4 -4
  126. package/rules/js-lint/js/docs/tooling.md +12 -32
  127. package/rules/js-lint/js/tooling.mjs +1 -265
  128. package/rules/js-lint/{js/lint.mjs → main.mjs} +19 -2
  129. package/rules/js-lint-ci/docs/fix.md +3 -3
  130. package/rules/js-lint-ci/docs/index.md +4 -3
  131. package/rules/js-lint-ci/docs/main.md +27 -0
  132. package/rules/js-lint-ci/js/docs/index.md +2 -2
  133. package/rules/js-lint-ci/main.mjs +33 -0
  134. package/rules/js-mssql/docs/fix.md +5 -5
  135. package/rules/js-mssql/docs/index.md +4 -3
  136. package/rules/js-mssql/docs/main.md +30 -0
  137. package/rules/js-mssql/js/docs/index.md +2 -2
  138. package/rules/js-mssql/lib/docs/index.md +2 -2
  139. package/rules/js-mssql/main.mjs +20 -0
  140. package/rules/js-run/docs/fix.md +8 -8
  141. package/rules/js-run/docs/index.md +4 -3
  142. package/rules/js-run/docs/main.md +30 -0
  143. package/rules/js-run/js/docs/index.md +2 -2
  144. package/rules/js-run/lib/docs/index.md +7 -7
  145. package/rules/js-run/main.mjs +20 -0
  146. package/rules/k8s/docs/fix.md +4 -4
  147. package/rules/k8s/docs/index.md +4 -3
  148. package/rules/k8s/docs/main.md +40 -0
  149. package/rules/k8s/js/docs/index.md +12 -0
  150. package/rules/k8s/{lint/lint.mjs → main.mjs} +32 -10
  151. package/rules/nginx-default-tpl/docs/fix.md +7 -7
  152. package/rules/nginx-default-tpl/docs/index.md +4 -3
  153. package/rules/nginx-default-tpl/docs/main.md +30 -0
  154. package/rules/nginx-default-tpl/js/docs/index.md +2 -2
  155. package/rules/nginx-default-tpl/js/docs/template.md +2 -2
  156. package/rules/nginx-default-tpl/main.mjs +20 -0
  157. package/rules/npm-module/docs/fix.md +8 -8
  158. package/rules/npm-module/docs/index.md +4 -3
  159. package/rules/npm-module/docs/main.md +29 -0
  160. package/rules/npm-module/js/docs/index.md +5 -5
  161. package/rules/npm-module/js/docs/rule_meta.md +17 -16
  162. package/rules/npm-module/js/header_doc_pointer.mjs +1 -3
  163. package/rules/npm-module/js/rule_meta.mjs +13 -3
  164. package/rules/npm-module/main.mjs +20 -0
  165. package/rules/php/docs/fix.md +6 -6
  166. package/rules/php/docs/index.md +4 -3
  167. package/rules/php/docs/main.md +33 -0
  168. package/rules/php/js/docs/index.md +3 -3
  169. package/rules/php/js/docs/tooling.md +10 -10
  170. package/rules/php/{lint/lint.mjs → main.mjs} +32 -6
  171. package/rules/python/docs/fix.md +11 -11
  172. package/rules/python/docs/index.md +4 -3
  173. package/rules/python/docs/main.md +31 -0
  174. package/rules/python/js/docs/index.md +3 -3
  175. package/rules/python/js/docs/tooling.md +17 -17
  176. package/rules/python/{lint/lint.mjs → main.mjs} +31 -6
  177. package/rules/rego/docs/fix.md +5 -5
  178. package/rules/rego/docs/index.md +4 -3
  179. package/rules/rego/docs/main.md +37 -0
  180. package/rules/rego/js/docs/index.md +3 -3
  181. package/rules/rego/{lint/lint.mjs → main.mjs} +27 -5
  182. package/rules/release/docs/index.md +5 -4
  183. package/rules/release/docs/main.md +29 -0
  184. package/rules/release/docs/release.md +0 -3
  185. package/rules/release/lib/docs/index.md +4 -4
  186. package/rules/release/release.mdc +10 -0
  187. package/rules/rust/docs/fix.md +4 -4
  188. package/rules/rust/docs/index.md +4 -3
  189. package/rules/rust/docs/main.md +27 -0
  190. package/rules/rust/js/docs/index.md +3 -3
  191. package/rules/rust/lib/docs/index.md +2 -2
  192. package/rules/rust/{js/lint.mjs → main.mjs} +27 -4
  193. package/rules/security/docs/fix.md +6 -6
  194. package/rules/security/docs/index.md +4 -3
  195. package/rules/security/docs/main.md +28 -0
  196. package/rules/security/js/docs/index.md +4 -4
  197. package/rules/security/main.mjs +45 -0
  198. package/rules/style-lint/docs/fix.md +3 -3
  199. package/rules/style-lint/docs/index.md +4 -3
  200. package/rules/style-lint/docs/main.md +29 -0
  201. package/rules/style-lint/js/docs/index.md +3 -3
  202. package/rules/style-lint/{js/lint.mjs → main.mjs} +19 -1
  203. package/rules/tauri/docs/fix.md +11 -11
  204. package/rules/tauri/docs/index.md +4 -3
  205. package/rules/tauri/docs/main.md +29 -0
  206. package/rules/tauri/js/docs/index.md +3 -3
  207. package/rules/tauri/main.mjs +20 -0
  208. package/rules/test/docs/fix.md +5 -5
  209. package/rules/test/docs/index.md +4 -3
  210. package/rules/test/docs/main.md +30 -0
  211. package/rules/test/js/data/stryker_config/docs/index.md +4 -4
  212. package/rules/test/js/data/vitest_config/docs/index.md +2 -2
  213. package/rules/test/js/docs/index.md +7 -7
  214. package/rules/test/main.mjs +20 -0
  215. package/rules/text/docs/fix.md +11 -11
  216. package/rules/text/docs/index.md +4 -3
  217. package/rules/text/docs/main.md +29 -0
  218. package/rules/text/{lint → js}/cspell-fix.mjs +7 -2
  219. package/rules/text/js/docs/cspell-fix.md +30 -0
  220. package/rules/text/js/docs/formatting.md +12 -45
  221. package/rules/text/js/docs/index.md +8 -4
  222. package/rules/text/js/docs/run-dotenv-linter.md +31 -0
  223. package/rules/text/js/docs/run-shellcheck.md +28 -0
  224. package/rules/text/js/docs/run-v8r.md +29 -0
  225. package/rules/text/{lint/lint.mjs → main.mjs} +41 -10
  226. package/rules/tool-surface/docs/index.md +4 -3
  227. package/rules/tool-surface/docs/main.md +29 -0
  228. package/rules/tool-surface/main.mjs +20 -0
  229. package/rules/tool-surface/meta.json +6 -1
  230. package/rules/vue/docs/fix.md +6 -6
  231. package/rules/vue/docs/index.md +4 -3
  232. package/rules/vue/docs/main.md +29 -0
  233. package/rules/vue/js/docs/index.md +2 -2
  234. package/rules/vue/lib/docs/index.md +2 -2
  235. package/rules/vue/main.mjs +20 -0
  236. package/rules/worktree/docs/fix.md +11 -11
  237. package/rules/worktree/docs/index.md +4 -3
  238. package/rules/worktree/docs/main.md +28 -0
  239. package/rules/worktree/main.mjs +20 -0
  240. package/scripts/coverage-classify/docs/index.md +6 -6
  241. package/scripts/dispatcher/docs/index.md +2 -2
  242. package/scripts/docs/index.md +16 -15
  243. package/scripts/docs/post-tool-use-check.md +29 -0
  244. package/scripts/docs/sync-claude-config.md +64 -92
  245. package/scripts/lib/adr/docs/normalize-cli.md +0 -3
  246. package/scripts/lib/adr/docs/normalize-pipeline.md +0 -3
  247. package/scripts/lib/docs/gha-workflow.md +25 -317
  248. package/scripts/lib/docs/index.md +36 -35
  249. package/scripts/lib/docs/list-project-rules-mdc.md +5 -4
  250. package/scripts/lib/docs/list-rule-ids.md +15 -148
  251. package/scripts/lib/docs/read-n-cursor-config-lite.md +12 -16
  252. package/scripts/lib/docs/run-lint-step.md +13 -13
  253. package/scripts/lib/docs/run-lint.md +30 -0
  254. package/scripts/lib/docs/run-rule-cli.md +14 -10
  255. package/scripts/lib/docs/run-standard-lint.md +29 -10
  256. package/scripts/lib/docs/run-standard-rule.md +12 -11
  257. package/scripts/lib/docs/timing-summary.md +11 -12
  258. package/scripts/lib/docs/worktree-notice.md +0 -3
  259. package/scripts/lib/fix/analyze-escalation.mjs +4 -1
  260. package/scripts/lib/fix/docs/index.md +11 -10
  261. package/scripts/lib/fix/docs/orchestrator.md +23 -18
  262. package/scripts/lib/fix/docs/run-conformance-check.md +33 -0
  263. package/scripts/lib/fix/docs/run-fix-check.md +3 -3
  264. package/scripts/lib/fix/docs/t0.md +10 -9
  265. package/scripts/lib/fix/orchestrator.mjs +31 -8
  266. package/scripts/lib/fix/{run-fix-check.mjs → run-conformance-check.mjs} +13 -13
  267. package/scripts/lib/fix/t0.mjs +6 -3
  268. package/scripts/lib/list-project-rules-mdc.mjs +1 -1
  269. package/scripts/lib/list-rule-ids.mjs +12 -3
  270. package/scripts/lib/read-n-cursor-config-lite.mjs +2 -2
  271. package/{rules/lint/js/orchestrate.mjs → scripts/lib/run-lint.mjs} +42 -22
  272. package/scripts/lib/run-rule-cli.mjs +4 -4
  273. package/scripts/lib/run-standard-lint.mjs +19 -6
  274. package/scripts/lib/run-standard-rule.mjs +4 -4
  275. package/scripts/lib/timing-summary.mjs +1 -1
  276. package/scripts/{post-tool-use-fix.mjs → post-tool-use-check.mjs} +9 -9
  277. package/scripts/sync-claude-config.mjs +2 -2
  278. package/scripts/utils/docs/index.md +14 -14
  279. package/skills/doc-aggregate/js/docs/index.md +3 -3
  280. package/skills/doc-files/.changes/260612-0002.md +1 -0
  281. package/skills/doc-files/.changes/260612-0006.md +1 -0
  282. package/skills/doc-files/.changes/260612-0008.md +1 -0
  283. package/skills/doc-files/.changes/260612-0012.md +1 -0
  284. package/skills/doc-files/.changes/260612-0031.md +1 -0
  285. package/skills/doc-files/.changes/260612-0036.md +1 -0
  286. package/skills/doc-files/.changes/260612-0114.md +1 -0
  287. package/skills/start-check/js/docs/index.md +2 -2
  288. package/skills/taze/js/docs/index.md +2 -2
  289. package/types/bin/n-cursor.d.ts +1 -1
  290. package/rules/changelog/fix.mjs +0 -18
  291. package/rules/ci4/fix.mjs +0 -18
  292. package/rules/doc-files/fix.mjs +0 -19
  293. package/rules/doc-files/js/docs/lint.md +0 -34
  294. package/rules/doc-files/lint/docs/index.md +0 -11
  295. package/rules/doc-files/lint/docs/lint.md +0 -35
  296. package/rules/docker/fix.mjs +0 -18
  297. package/rules/docker/lint/docs/index.md +0 -11
  298. package/rules/docker/lint/docs/lint.md +0 -200
  299. package/rules/docker/lint/lint.mjs +0 -95
  300. package/rules/efes/fix.mjs +0 -18
  301. package/rules/feedback/fix.mjs +0 -18
  302. package/rules/ga/fix.mjs +0 -18
  303. package/rules/ga/js/docs/lint.md +0 -20
  304. package/rules/ga/js/lint.mjs +0 -12
  305. package/rules/ga/lint/docs/index.md +0 -11
  306. package/rules/ga/lint/docs/lint.md +0 -31
  307. package/rules/graphql/fix.mjs +0 -18
  308. package/rules/hasura/fix.mjs +0 -18
  309. package/rules/image-avif/fix.mjs +0 -18
  310. package/rules/image-compress/fix.mjs +0 -18
  311. package/rules/image-compress/js/docs/lint.md +0 -24
  312. package/rules/js-bun-db/fix.mjs +0 -18
  313. package/rules/js-bun-redis/fix.mjs +0 -18
  314. package/rules/js-lint/fix.mjs +0 -18
  315. package/rules/js-lint/js/docs/lint.md +0 -32
  316. package/rules/js-lint-ci/fix.mjs +0 -18
  317. package/rules/js-lint-ci/js/docs/lint.md +0 -22
  318. package/rules/js-lint-ci/js/lint.mjs +0 -15
  319. package/rules/js-mssql/fix.mjs +0 -18
  320. package/rules/js-run/fix.mjs +0 -18
  321. package/rules/k8s/fix.mjs +0 -18
  322. package/rules/k8s/js/lint.mjs +0 -14
  323. package/rules/k8s/lint/docs/index.md +0 -11
  324. package/rules/k8s/lint/docs/lint.md +0 -413
  325. package/rules/lint/docs/fix.md +0 -25
  326. package/rules/lint/docs/index.md +0 -11
  327. package/rules/lint/fix.mjs +0 -18
  328. package/rules/lint/js/docs/index.md +0 -11
  329. package/rules/lint/js/docs/orchestrate.md +0 -31
  330. package/rules/lint/meta.json +0 -1
  331. package/rules/nginx-default-tpl/fix.mjs +0 -18
  332. package/rules/npm-module/fix.mjs +0 -18
  333. package/rules/php/fix.mjs +0 -18
  334. package/rules/php/js/docs/lint.md +0 -20
  335. package/rules/php/js/lint.mjs +0 -15
  336. package/rules/php/lint/docs/index.md +0 -11
  337. package/rules/php/lint/docs/lint.md +0 -219
  338. package/rules/python/fix.mjs +0 -18
  339. package/rules/python/js/docs/lint.md +0 -21
  340. package/rules/python/js/lint.mjs +0 -14
  341. package/rules/python/lint/docs/index.md +0 -11
  342. package/rules/python/lint/docs/lint.md +0 -29
  343. package/rules/rego/fix.mjs +0 -18
  344. package/rules/rego/js/docs/lint.md +0 -21
  345. package/rules/rego/js/lint.mjs +0 -12
  346. package/rules/rego/lint/docs/index.md +0 -11
  347. package/rules/rego/lint/docs/lint.md +0 -208
  348. package/rules/rust/fix.mjs +0 -18
  349. package/rules/rust/js/docs/lint.md +0 -21
  350. package/rules/security/fix.mjs +0 -18
  351. package/rules/security/js/docs/lint.md +0 -175
  352. package/rules/security/js/lint.mjs +0 -26
  353. package/rules/style-lint/fix.mjs +0 -18
  354. package/rules/style-lint/js/docs/lint.md +0 -31
  355. package/rules/tauri/fix.mjs +0 -18
  356. package/rules/test/fix.mjs +0 -18
  357. package/rules/text/fix.mjs +0 -18
  358. package/rules/text/js/docs/lint.md +0 -23
  359. package/rules/text/js/lint.mjs +0 -15
  360. package/rules/text/lint/docs/cspell-fix.md +0 -32
  361. package/rules/text/lint/docs/index.md +0 -15
  362. package/rules/text/lint/docs/lint.md +0 -36
  363. package/rules/text/lint/docs/run-dotenv-linter.md +0 -161
  364. package/rules/text/lint/docs/run-shellcheck.md +0 -216
  365. package/rules/text/lint/docs/run-v8r.md +0 -201
  366. package/rules/tool-surface/fix.mjs +0 -18
  367. package/rules/vue/fix.mjs +0 -18
  368. package/rules/worktree/fix.mjs +0 -18
  369. /package/rules/release/{fix.mjs → main.mjs} +0 -0
  370. /package/rules/text/{lint → js}/run-dotenv-linter.mjs +0 -0
  371. /package/rules/text/{lint → js}/run-shellcheck.mjs +0 -0
  372. /package/rules/text/{lint → js}/run-v8r.mjs +0 -0
@@ -4,7 +4,7 @@
4
4
  * Відносні шляхи з прямими слешами; hadolint резолвиться через `ensureTool`
5
5
  * (PATH → кеш → авто-install brew/scoop/GitHub Release per-platform). Docker-fallback
6
6
  * прибрано — hadolint ставиться як **нативний бінарник**, без `docker run`.
7
- * Використовується `./check.mjs` (check-docker) та `../../lint/lint.mjs` (run-docker).
7
+ * Використовується `../js/lint.mjs` (правило `n-cursor lint docker` / check-docker).
8
8
  */
9
9
  import { spawnSync } from 'node:child_process'
10
10
  import { relative, sep } from 'node:path'
@@ -3,186 +3,29 @@ type: JS Module
3
3
  title: docker-hadolint.mjs
4
4
  resource: npm/rules/docker/lib/docker-hadolint.mjs
5
5
  docgen:
6
- crc: b97701f3
6
+ crc: ebab2135
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 90
7
9
  ---
8
10
 
9
- Модуль `docker-hadolint.mjs` інкапсулює спільну логіку запуску статичного аналізатора `hadolint` для перевірки `Dockerfile`-ів у межах правила `docker` (див. `.cursor/rules/docker.mdc` / `n-docker`). Він є тонким адаптером поверх системного бінарника `hadolint` та надає двом викликачам — `check.mjs` (skill `check-docker`) і `../../lint/lint.mjs` (skill `run-docker`) — єдину функцію перевірки одного `Dockerfile` плюс утиліту нормалізації шляхів.
11
+ ## Огляд
10
12
 
11
- Ключові архітектурні рішення:
13
+ Спільна логіка виклику hadolint для шляхів до Dockerfile. Модуль створює стандартизовані відносні шляхи з прямими слешами. Він ініціює перевірку Dockerfile, використовуючи hadolint як нативний бінарник, який резолвиться через `ensureTool` (PATH → кеш → авто-install brew/scoop/GitHub Release per-platform). Для отримання інформації про встановлення можна звертатися до https://github.com/hadolint/hadolint/releases. Публічна функція `lintDockerfileWithHadolint` виконує перевірку за правилом `n-cursor lint docker` / check-docker.
12
14
 
13
- - `hadolint` запускається **виключно як нативний бінарник**. Будь-який Docker-fallback (наприклад, `docker run hadolint/hadolint`) свідомо прибраний, тож модуль не залежить від запущеного Docker Engine.
14
- - Розв’язання шляху до бінарника делеговано в `ensureTool('hadolint')`, який реалізує ланцюжок `PATH → локальний кеш інструментів → авто-install` через `brew` / `scoop` / GitHub Release, відповідно до платформи.
15
- - Якщо `ensureTool` падає (інструмент відсутній і авто-install вимкнено через `N_CURSOR_NO_AUTO_INSTALL` або фізично не вдався), модуль **не кидає виняток назовні**, а повертає структурований результат `{ ok: false, stderr: <інструкція з установки> }`. Це дозволяє викликачам однаково обробляти і реальні порушення hadolint, і відсутність інструмента.
16
- - Шляхи у виводі нормалізуються через `posixRel` (відносно `root`, з прямими слешами `/`), щоб лог і повідомлення про помилки були стабільними між macOS / Linux / Windows.
15
+ ## Поведінка
17
16
 
18
- ## Експорти / API
17
+ posixRel
18
+ Створює відносний шлях від кореня з використанням прямих слешів.
19
19
 
20
- Модуль є ESM (`.mjs`) і має два іменовані експорти:
20
+ lintDockerfileWithHadolint
21
+ Запускає hadolint як нативний бінарник для перевірки Dockerfile. Якщо не вдається знайти hadolint, повертає помилку з інструкцією для встановлення (наприклад, https://github.com/hadolint/hadolint/releases).
21
22
 
22
- | Експорт | Тип | Призначення |
23
- | ------------------------------------------- | -------- | ---------------------------------------------------------------------------------- |
24
- | `posixRel(root, absPath)` | function | Перетворити абсолютний шлях на відносний від `root` з прямими слешами. |
25
- | `lintDockerfileWithHadolint(root, absPath)` | function | Запустити `hadolint` для одного `Dockerfile` і повернути структурований результат. |
23
+ ## Публічний API
26
24
 
27
- Default-експорту немає. Глобальних побічних ефектів на рівні модуля немає імпорт лише підтягує `ensureTool`, не виконуючи його.
25
+ - posixRel Генерує абсолютний шлях від кореня з використанням лише слешів, забезпечуючи стабільність незалежно від операційної системи.
26
+ - lintDockerfileWithHadolint — Запускає інструмент hadolint для аналізу Dockerfile. Якщо інструмент не знайдено у системних шляхах, він намагається встановити його. У разі невдачі встановлення або відключення автоматичного встановлення, повертає помилку, надаючи користувачеві підказку для ручного запуску (детальніше про інструмент можна знайти на https://github.com/hadolint/hadolint/releases).
28
27
 
29
- ## Функції
28
+ ## Гарантії поведінки
30
29
 
31
- ### `posixRel(root, absPath)`
32
-
33
- Утиліта нормалізації шляхів для стабільного логування й передачі в `hadolint`.
34
-
35
- **Сигнатура:**
36
-
37
- ```js
38
- export function posixRel(root: string, absPath: string): string
39
- ```
40
-
41
- **Параметри:**
42
-
43
- - `root` — абсолютний шлях до кореня репозиторію (або будь-якого опорного каталогу), відносно якого треба отримати шлях.
44
- - `absPath` — абсолютний шлях до файлу, який треба представити відносно `root`.
45
-
46
- **Повертає:**
47
-
48
- - Рядок із відносним шляхом, де всі системні розділювачі (`path.sep`) замінено на прямий слеш `/`. На POSIX-системах результат фактично збігається з `path.relative`, на Windows — конвертує `\` на `/`.
49
-
50
- **Алгоритм:**
51
-
52
- 1. Викликає `relative(root, absPath)` з `node:path` для обчислення відносного шляху.
53
- 2. Розбиває результат за поточним `sep` (`path.sep`) і склеює знову через `'/'`.
54
-
55
- **Side effects:** немає; функція чиста й детермінована.
56
-
57
- **Примітка:** функція не валідовує, чи `absPath` справді абсолютний і чи він знаходиться під `root` — у такому випадку `relative` поверне відносний шлях із `..`, що теж буде нормалізовано до прямих слешів.
58
-
59
- ---
60
-
61
- ### `lintDockerfileWithHadolint(root, absPath)`
62
-
63
- Основна точка входу модуля: виконує `hadolint` для одного `Dockerfile` і повертає уніфікований результат.
64
-
65
- **Сигнатура:**
66
-
67
- ```js
68
- export function lintDockerfileWithHadolint(
69
- root: string,
70
- absPath: string
71
- ): {
72
- ok: boolean,
73
- stdout: string,
74
- stderr: string,
75
- via: string
76
- }
77
- ```
78
-
79
- **Параметри:**
80
-
81
- - `root` — абсолютний шлях до кореня репозиторію. Використовується одночасно як `cwd` для дочірнього процесу і як база для `posixRel`.
82
- - `absPath` — абсолютний шлях до конкретного `Dockerfile` (або файлу, який треба перевірити hadolint’ом).
83
-
84
- **Повертає об’єкт із полями:**
85
-
86
- - `ok` — `true`, якщо `hadolint` завершився з кодом виходу `0` (порушень немає). `false` — у будь-якому іншому випадку: інструмент знайшов проблеми, не запустився, або не зміг бути встановленим/знайденим.
87
- - `stdout` — stdout процесу hadolint як рядок (UTF-8). При помилці отримання інструмента — порожній рядок.
88
- - `stderr` — stderr процесу hadolint як рядок. Якщо інструмент не вдалося отримати, тут міститься українська інструкція з установки (`brew install hadolint` / `scoop install hadolint` / посилання на GitHub Releases) разом із повідомленням оригінальної помилки.
89
- - `via` — завжди константа `'hadolint'`. Поле залишене для зворотної сумісності з API, де раніше міг бути ще варіант на кшталт `'docker'`; зараз інших значень не повертається.
90
-
91
- **Алгоритм:**
92
-
93
- 1. Обчислює відносний шлях `rel = posixRel(root, absPath)`.
94
- 2. Намагається отримати шлях до бінарника через `hadolintPath = ensureTool('hadolint')`.
95
- - Якщо `ensureTool` кидає виняток, функція **перехоплює** його і повертає об’єкт з `ok: false`, порожнім `stdout`, інструктивним `stderr` (текст помилки + поради з установки) і `via: 'hadolint'`. На цьому виконання завершується.
96
- 3. Викликає `spawnSync(hadolintPath, [rel], { cwd: root, encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 })`:
97
- - `cwd: root` — щоб hadolint бачив правильну робочу директорію і `rel` коректно резолвився.
98
- - `encoding: 'utf8'` — `stdout`/`stderr` одразу приходять як рядки, а не `Buffer`.
99
- - `maxBuffer: 10 МіБ` — захист від великих обсягів виводу при множинних попередженнях.
100
- 4. Формує результат: `ok = local.status === 0`, `stdout`/`stderr` приходять з процесу (з фолбеком на порожній рядок через `??`), `via: 'hadolint'`.
101
-
102
- **Side effects:**
103
-
104
- - Може ініціювати **авто-install** `hadolint` через `ensureTool` (мережа, brew/scoop/завантаження GitHub Release, запис у локальний кеш інструментів), якщо інструмент відсутній і авто-install не вимкнено `N_CURSOR_NO_AUTO_INSTALL`.
105
- - Синхронно запускає дочірній процес `hadolint`, що блокує цикл подій Node.js до завершення (через `spawnSync`).
106
- - Не пише в stdout/stderr поточного процесу самостійно — увесь вивід hadolint повертає викликачу.
107
- - Не змінює `process.cwd()` поточного процесу (тільки `cwd` дочірнього).
108
-
109
- **Обробка помилок:**
110
-
111
- - Виняток від `ensureTool` ловиться і конвертується у м’який `ok: false` з підказкою.
112
- - Помилки запуску `spawnSync` (наприклад, права доступу) **не обгортаються окремо**: у такому разі `spawnSync` повертає об’єкт з `status: null` і `error`-полем, відповідно `ok` буде `false`, а `stdout`/`stderr` — порожніми (через `??`). Поле `error` об’єкта `spawnSync` у результат не транслюється.
113
- - Ненульовий `status` від самого `hadolint` (тобто знайдені порушення) трактується як `ok: false`, але `stderr`/`stdout` несуть звіт hadolint для подальшого парсингу/виводу користувачу.
114
-
115
- ## Залежності
116
-
117
- ### Node.js (стандартні)
118
-
119
- - `node:child_process` — імпортується `spawnSync` для синхронного запуску `hadolint`.
120
- - `node:path` — імпортуються `relative` і `sep` для побудови відносного шляху з нормалізацією роздільників.
121
-
122
- ### Внутрішні (моноpепо)
123
-
124
- - `../../../scripts/lib/ensure-tool.mjs` — функція `ensureTool(name)`, яка:
125
- - повертає абсолютний шлях до бінарника;
126
- - намагається знайти його у `PATH`, у локальному кеші інструментів;
127
- - за потреби виконує авто-install через `brew` (macOS), `scoop` (Windows) чи GitHub Release (Linux);
128
- - кидає виняток, якщо інструмент недоступний і авто-install неможливий / вимкнено `N_CURSOR_NO_AUTO_INSTALL`.
129
-
130
- ### Зовнішні (runtime)
131
-
132
- - Бінарник `hadolint` (нативний; брати з `brew`, `scoop`, GitHub Release). **Не** використовується `docker run hadolint/hadolint` — Docker-fallback явно прибраний.
133
-
134
- ### Імпорт-споживачі (всередині правила `docker`)
135
-
136
- - `./check.mjs` — скіл `check-docker`: разова перевірка обраних `Dockerfile`-ів.
137
- - `../../lint/lint.mjs` — скіл `run-docker`: інтеграція в загальний `lint`-конвеєр.
138
-
139
- ## Потік виконання / Використання
140
-
141
- Типовий сценарій використання модуля викликачем:
142
-
143
- 1. Викликач (наприклад, `check-docker` або `run-docker`) визначає `root` репозиторію і список абсолютних шляхів до `Dockerfile`-ів.
144
- 2. Для кожного шляху викликається `lintDockerfileWithHadolint(root, absPath)`.
145
- 3. Модуль:
146
- - нормалізує шлях у POSIX-форму (`posixRel`);
147
- - резолвить `hadolint` через `ensureTool` (можливо з авто-install);
148
- - синхронно запускає `hadolint <rel>` у `cwd = root`;
149
- - повертає `{ ok, stdout, stderr, via }`.
150
- 4. Викликач інтерпретує результат:
151
- - `ok === true` → файл чистий, нічого не виводити (або вивести позитивний статус);
152
- - `ok === false` → показати `stdout`/`stderr` користувачу, зарахувати як порушення; якщо `stderr` містить інструкцію з установки — повідомити користувача, як отримати інструмент.
153
-
154
- ### Приклад використання
155
-
156
- ```js
157
- import { lintDockerfileWithHadolint, posixRel } from './docker-hadolint.mjs'
158
-
159
- const root = process.cwd()
160
- const absPath = '/abs/path/to/repo/services/api/Dockerfile'
161
-
162
- const result = lintDockerfileWithHadolint(root, absPath)
163
-
164
- if (!result.ok) {
165
- console.error(`hadolint failed for ${posixRel(root, absPath)} (via=${result.via})`)
166
- if (result.stdout) console.error(result.stdout)
167
- if (result.stderr) console.error(result.stderr)
168
- process.exitCode = 1
169
- }
170
- ```
171
-
172
- ### Поведінка за відсутності `hadolint`
173
-
174
- - Якщо `hadolint` відсутній і `N_CURSOR_NO_AUTO_INSTALL` **не** виставлена, `ensureTool` спробує встановити бінарник автоматично (за платформою).
175
- - Якщо `N_CURSOR_NO_AUTO_INSTALL` виставлена або авто-install не вдався, `lintDockerfileWithHadolint` повертає:
176
- - `ok: false`,
177
- - `stdout: ''`,
178
- - `stderr: 'Не вдалося отримати hadolint (<повідомлення>). Встанови: brew install hadolint (macOS) / scoop install hadolint (Windows) / https://github.com/hadolint/hadolint/releases (Linux).'`,
179
- - `via: 'hadolint'`.
180
- - Завдяки м’якій обробці викликач може коректно показати інструкцію користувачу замість аварійного завершення.
181
-
182
- ### Особливості та обмеження
183
-
184
- - **Синхронність**: усі виклики блокуючі (`spawnSync`). Для пакетної перевірки сотень файлів варіант — викликати модуль із зовнішнього оркестратора, який сам керує паралелізмом (з урахуванням обмежень середовища).
185
- - **Один файл за виклик**: функція передає у `hadolint` рівно один аргумент `rel`. Для масової перевірки слід викликати функцію в циклі — це свідомий вибір, щоб уніфікувати результат і прив’язку до конкретного файлу.
186
- - **Розмір буфера**: `maxBuffer = 10 МіБ` достатньо для звичайних `Dockerfile`-звітів; для аномально великих виводів значення доведеться змінювати на рівні форку модуля.
187
- - **`via` константно `'hadolint'`**: поле залишене для майбутньої сумісності, але наразі ніколи не приймає інших значень.
188
- - **Стабільність шляхів**: завдяки `posixRel` повідомлення про порушення містять однакові шляхи з прямими слешами на всіх ОС — це важливо для дифу логів у CI.
30
+ - Read-only: не виконує операцій запису (ФС/БД).
31
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
@@ -6,9 +6,9 @@ resource: npm/rules/docker/lib/
6
6
 
7
7
  # npm/rules/docker/lib
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [docker-hadolint.mjs](docker-hadolint.md) | JS Module |
12
- | [docker-mirror.mjs](docker-mirror.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ------------------------------------------------- | --------- |
11
+ | [docker-hadolint.mjs](docker-hadolint.md) | JS Module |
12
+ | [docker-mirror.mjs](docker-mirror.md) | JS Module |
13
13
  | [docker-native-addon.mjs](docker-native-addon.md) | JS Module |
14
- | [docker-nginx-user.mjs](docker-nginx-user.md) | JS Module |
14
+ | [docker-nginx-user.mjs](docker-nginx-user.md) | JS Module |
@@ -0,0 +1,20 @@
1
+ import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
2
+ import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
3
+
4
+ /**
5
+ * Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня: applies →
6
+ * JS-concerns → policy → mdc-refs. `lint()` — lint-поверхня; важка реалізація лишається
7
+ * у js/-хелпері `js/lint.mjs` (main.mjs тонкий — лише re-export).
8
+ * @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону
9
+ * @returns {Promise<number>} 0 — OK, 1 — порушення
10
+ */
11
+ export function run(ctx) {
12
+ return runStandardRule(import.meta.dirname, ctx)
13
+ }
14
+
15
+ export { lint } from './js/lint.mjs'
16
+
17
+ if (isRunAsCli(import.meta.url)) {
18
+ // Standalone: bun rules/<id>/main.mjs — повний еквівалент `npx @nitra/cursor check <id>`.
19
+ process.exitCode = await runRuleCli(import.meta.dirname)
20
+ }
@@ -14,16 +14,16 @@ docgen:
14
14
  ## Поведінка
15
15
 
16
16
  1. Запуск правила.
17
- * Приймає контекст прогону.
18
- * Виконує застосування JS-занепокоєних.
19
- * Застосовує політику.
20
- * Генерує посилання MDC.
21
- * Повертає результат прогону.
17
+ - Приймає контекст прогону.
18
+ - Виконує застосування JS-занепокоєних.
19
+ - Застосовує політику.
20
+ - Генерує посилання MDC.
21
+ - Повертає результат прогону.
22
22
 
23
23
  2. Запуск у режимі CLI.
24
- * Виконується при запуску через CLI.
25
- * Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
26
- * Повертає код виходу.
24
+ - Виконується при запуску через CLI.
25
+ - Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
26
+ - Повертає код виходу.
27
27
 
28
28
  ## Публічний API
29
29
 
@@ -6,6 +6,7 @@ resource: npm/rules/efes/
6
6
 
7
7
  # npm/rules/efes
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [fix.mjs](fix.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ------------------- | --------- |
11
+ | [fix.mjs](fix.md) | JS Module |
12
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,29 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/efes/main.mjs
5
+ docgen:
6
+ crc: 762b6875
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Модуль перевіряє відповідність коду визначеним правилам, використовуючи конфігурацію з meta.json. Він виконує аналіз, який може бути ініційований через публічну функцію run. Модуль є read-only, тобто не здійснює записів у файлову систему чи бази даних. Кешування даних відбувається у межах одного прогону. При завершенні роботи як окремий інструмент, він надає підсумковий звіт.
14
+
15
+ ## Поведінка
16
+
17
+ 1. Виконує перевірку правила, застосовуючи логіку, визначену в конфігах, зокрема `meta.json`.
18
+ 2. Виконує перевірку, що включає аналіз JS-залежностей та політик.
19
+ 3. Виконує перевірку, що включає посилання на MDC.
20
+ 4. Якщо код запускається як окремий інструмент (standalone), виконується повний цикл роботи з конфігурацією, білистами дозволених елементів та підсумковим звітом, завершуючи роботу з відповідним кодом виходу.
21
+
22
+ ## Публічний API
23
+
24
+ run — єдиний вхідний пункт правила; виконує послідовність перевірок: застосовує JS-занепокоєння, застосовує політику, перевіряє посилання MDC.
25
+
26
+ ## Гарантії поведінки
27
+
28
+ - Read-only: не виконує операцій запису (ФС/БД).
29
+ - Кешує результати в межах одного прогону.
@@ -0,0 +1,20 @@
1
+ import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
2
+ import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
3
+
4
+ /**
5
+ * Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня: applies →
6
+ * JS-concerns → policy → mdc-refs (через runStandardRule). Lint-поверхні правило не має
7
+ * (`meta.json` без `lint`), тож експорту `lint` тут немає.
8
+ * Library mode: викликається CLI orchestration через `import + run(ctx)`.
9
+ * @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
10
+ * @returns {Promise<number>} 0 — OK, 1 — порушення
11
+ */
12
+ export function run(ctx) {
13
+ return runStandardRule(import.meta.dirname, ctx)
14
+ }
15
+
16
+ if (isRunAsCli(import.meta.url)) {
17
+ // Standalone: bun rules/<id>/main.mjs — повний еквівалент `npx @nitra/cursor check <id>`
18
+ // (config-loading + whitelist + summary): library-роль (run) + standalone-роль (CLI-блок).
19
+ process.exitCode = await runRuleCli(import.meta.dirname)
20
+ }
@@ -12,11 +12,11 @@ docgen:
12
12
  ## Поведінка
13
13
 
14
14
  1. Запуск правила.
15
- * Приймає контекст прогону.
16
- * Виконує застосування JS-занепокоєних.
17
- * Застосовує політику.
18
- * Генерує посилання MDC.
19
- * Повертає результат прогону.
15
+ - Приймає контекст прогону.
16
+ - Виконує застосування JS-занепокоєних.
17
+ - Застосовує політику.
18
+ - Генерує посилання MDC.
19
+ - Повертає результат прогону.
20
20
 
21
21
  ## Публічний API
22
22
 
@@ -6,6 +6,7 @@ resource: npm/rules/feedback/
6
6
 
7
7
  # npm/rules/feedback
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [fix.mjs](fix.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ------------------- | --------- |
11
+ | [fix.mjs](fix.md) | JS Module |
12
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,30 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/feedback/main.mjs
5
+ docgen:
6
+ crc: 762b6875
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Модуль перевіряє відповідність даних заданим правилам, використовуючи конфігурації, політики та посилання на MDC, які визначаються у meta.json. Він застосовує білий список для формування підсумку. Публічний інтерфейс run завершує роботу, інформуючи про успішне виконання або виявлені порушення. Модуль є Read-only і не виконує записів у файлову систему чи бази даних.
14
+
15
+ ## Поведінка
16
+
17
+ 1. Викликається функція `run` для виконання перевірки.
18
+ 2. Виконання `run` застосовує логіку правила, включаючи перевірку конфігурацій, політик та посилання на MDC.
19
+ 3. Якщо скрипт виконується як окрема програма (CLI), виконується логіка оркестрації правила.
20
+ 4. Оркестрація правила зчитує конфігурації, застосовує білий список та генерує підсумок.
21
+ 5. Вихідний код завершує роботу з кодом, що вказує на успіх або наявність порушень.
22
+
23
+ ## Публічний API
24
+
25
+ run — виконує основну логіку правила: застосовує перевірки JS-зацікавленостей, політики та посилання на MDC.
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
30
+ - Кешує результати в межах одного прогону.
@@ -0,0 +1,20 @@
1
+ import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
2
+ import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
3
+
4
+ /**
5
+ * Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня: applies →
6
+ * JS-concerns → policy → mdc-refs (через runStandardRule). Lint-поверхні правило не має
7
+ * (`meta.json` без `lint`), тож експорту `lint` тут немає.
8
+ * Library mode: викликається CLI orchestration через `import + run(ctx)`.
9
+ * @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
10
+ * @returns {Promise<number>} 0 — OK, 1 — порушення
11
+ */
12
+ export function run(ctx) {
13
+ return runStandardRule(import.meta.dirname, ctx)
14
+ }
15
+
16
+ if (isRunAsCli(import.meta.url)) {
17
+ // Standalone: bun rules/<id>/main.mjs — повний еквівалент `npx @nitra/cursor check <id>`
18
+ // (config-loading + whitelist + summary): library-роль (run) + standalone-роль (CLI-блок).
19
+ process.exitCode = await runRuleCli(import.meta.dirname)
20
+ }
@@ -12,11 +12,11 @@ docgen:
12
12
  ## Поведінка
13
13
 
14
14
  1. Запуск правила.
15
- * Приймає контекст прогону.
16
- * Виконує застосування JS-занепокоєних.
17
- * Застосовує політику.
18
- * Генерує посилання MDC.
19
- * Повертає результат прогону.
15
+ - Приймає контекст прогону.
16
+ - Виконує застосування JS-занепокоєних.
17
+ - Застосовує політику.
18
+ - Генерує посилання MDC.
19
+ - Повертає результат прогону.
20
20
 
21
21
  ## Публічний API
22
22
 
@@ -6,6 +6,7 @@ resource: npm/rules/ga/
6
6
 
7
7
  # npm/rules/ga
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [fix.mjs](fix.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ------------------- | --------- |
11
+ | [fix.mjs](fix.md) | JS Module |
12
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,29 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/ga/main.mjs
5
+ docgen:
6
+ crc: f6b5f0b3
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 90
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Цей модуль є CLI-обгорткою над канонічним `lint-ga` (ga.mdc). Він автоматично встановлює `shellcheck` та `conftest` через `ensureTool` (використовуючи brew/scoop/GitHub Release залежно від платформи), перевіряє наявність `uv` (для `uvx zizmor`), а потім послідовно виконує `bunx github-actionlint`, `uvx zizmor --offline --collect=workflows .` та делегує до `rules/ga/check.mjs::check`. Функція `lint` викликає `runLintGaCli`, який є частиною оркестраторного адаптера `n-cursor lint ga`. При відсутності `uv`, користувачеві надається підказка з командою встановлення, наприклад, https://astral.sh/uv/install.sh, оскільки `uv` не в реєстрі `ensureTool`.
14
+
15
+ ## Поведінка
16
+
17
+ run виконує стандартну перевірку правила, застосовуючи логіку, описану в `mdc-refs`.
18
+ runLintGaCli виконує повний канонічний процес `lint-ga`: автоматично встановлює `shellcheck` та `conftest`, перевіряє наявність `uv`, а потім послідовно запускає `github-actionlint`, `zizmor` та перевірку Rego-полісі через `rules/ga/check.mjs`.
19
+ lint делегує виконання повного канонічного процесу `lint-ga` через `runLintGaCli`.
20
+
21
+ ## Публічний API
22
+
23
+ run — виконує основну перевірку, яка охоплює логіку застосування до JS-задач, політики та посилання на mdc-референси.
24
+ runLintGaCli — виконує лінтинг з використанням інструментів actionlint/zizmor та перевірку ga.
25
+ lint — керує процесом лінтингу, делегуючи виконання `runLintGaCli`.
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -6,7 +6,7 @@ resource: npm/rules/ga/js/
6
6
 
7
7
  # npm/rules/ga/js
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [lint.mjs](lint.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ----------------------------- | --------- |
11
+ | [lint.mjs](lint.md) | JS Module |
12
12
  | [workflows.mjs](workflows.md) | JS Module |
@@ -2,13 +2,13 @@
2
2
  * CLI-обгортка над канонічним `lint-ga` (ga.mdc): авто-встановлює `shellcheck` і `conftest`
3
3
  * через `ensureTool` (brew/scoop/GitHub Release per-platform), перевіряє наявність `uv` (для `uvx`),
4
4
  * тоді послідовно виконує `bunx github-actionlint`, `uvx zizmor --offline --collect=workflows .` і
5
- * делегує до `rules/ga/fix.mjs::check()` — там і Rego-частина (через `runConftestBatch`),
5
+ * делегує до `rules/ga/check.mjs::check()` — там і Rego-частина (через `runConftestBatch`),
6
6
  * і JS cross-file перевірки правил `ga.mdc`.
7
7
  *
8
8
  * Plan B-патерн (rego-authoritative): Rego-полісі (`npm/policy/ga/`) запускає вже сам
9
- * `rules/ga/fix.mjs::check()` як перший крок — `lint-ga.mjs` про це не знає. Раніше `lint-ga.mjs` сам
9
+ * `rules/ga/check.mjs::check()` як перший крок — `lint-ga.mjs` про це не знає. Раніше `lint-ga.mjs` сам
10
10
  * спавнив conftest для `ga.<name>` per-workflow і `ga.workflow_common` (PoC); тепер ця логіка
11
- * централізована у `rules/ga/fix.mjs`, тож одне джерело істини, без дублювання між
11
+ * централізована у `rules/ga/check.mjs`, тож одне джерело істини, без дублювання між
12
12
  * `lint-ga` і `npx \@nitra/cursor check ga`.
13
13
  *
14
14
  * Без preflight `actionlint` (через `bunx github-actionlint`) мовчки пропускає shell-перевірки в
@@ -18,18 +18,30 @@
18
18
  * `uv` потрібен для `uvx zizmor`. Якщо його нема — `uvx zizmor` падає неінформативно; підказка
19
19
  * з командою встановлення коротша й корисніша. `uv` не в реєстрі ensureTool → hint-only.
20
20
  *
21
- * Експортовано окремо `runLintGaCli` — використовується з `bin/n-cursor.js` як підкоманда `lint-ga`.
21
+ * Експортовано окремо `runLintGaCli` — викликається через `n-cursor lint ga` (оркестраторний адаптер `lint()` делегує сюди); окремої bin-підкоманди `lint-ga` немає.
22
22
  *
23
23
  * Канон патерну `lint-*` (серіалізація через `runStandardLint`, без прямого `withLock`) —
24
24
  * `.cursor/rules/scripts.mdc`, секція «Серіалізація важких CLI-команд».
25
25
  */
26
26
  import { platform } from 'node:process'
27
27
 
28
- import { check as checkGa } from '../js/workflows.mjs'
29
- import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
30
- import { runLintStep } from '../../../scripts/lib/run-lint-step.mjs'
31
- import { runStandardLint } from '../../../scripts/lib/run-standard-lint.mjs'
32
- import { ensureTool } from '../../../scripts/lib/ensure-tool.mjs'
28
+ import { check as checkGa } from './js/workflows.mjs'
29
+ import { resolveCmd } from '../../scripts/utils/resolve-cmd.mjs'
30
+ import { runLintStep } from '../../scripts/lib/run-lint-step.mjs'
31
+ import { runStandardLint } from '../../scripts/lib/run-standard-lint.mjs'
32
+ import { ensureTool } from '../../scripts/lib/ensure-tool.mjs'
33
+ import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
34
+ import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
35
+
36
+ /**
37
+ * Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня (applies → JS-concerns
38
+ * → policy → mdc-refs); `lint()` нижче — lint-поверхня (actionlint/zizmor + check-ga), імпл інлайн тут.
39
+ * @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону
40
+ * @returns {Promise<number>} 0 — OK, 1 — порушення
41
+ */
42
+ export function run(ctx) {
43
+ return runStandardRule(import.meta.dirname, ctx)
44
+ }
33
45
 
34
46
  /**
35
47
  * Опис залежності preflight-ом: бінарник, для чого потрібен, і команди встановлення.
@@ -109,7 +121,7 @@ function preflight(dep) {
109
121
  * 2) preflight: `uv` (для `uvx zizmor`) — hint-only, без авто-install;
110
122
  * 3) `bunx github-actionlint`;
111
123
  * 4) `uvx zizmor --offline --collect=workflows .`;
112
- * 5) `rules/ga/fix.mjs::check()` — Rego-полісі (батч conftest з `npm/policy/ga/`) + JS cross-file
124
+ * 5) `rules/ga/check.mjs::check()` — Rego-полісі (батч conftest з `npm/policy/ga/`) + JS cross-file
113
125
  * перевірки правил `ga.mdc`. Це **те саме**, що робить `npx \@nitra/cursor check ga`, тож
114
126
  * `lint-ga` тепер є суперсетом перевірки правила: external-tools + check.
115
127
  * @returns {Promise<number>} 0 — все OK, інакше — код першого кроку, що впав
@@ -133,3 +145,17 @@ async function runLintGaSteps() {
133
145
  }
134
146
 
135
147
  export const runLintGaCli = () => runStandardLint(import.meta.dirname, runLintGaSteps)
148
+
149
+ /**
150
+ * Оркестраторний адаптер `n-cursor lint ga`: делегує у `runLintGaCli`.
151
+ * @param {string[] | undefined} _files ігнорується (whole-repo аналіз)
152
+ * @returns {Promise<number>} exit code
153
+ */
154
+ export function lint(_files) {
155
+ return runLintGaCli()
156
+ }
157
+
158
+ if (isRunAsCli(import.meta.url)) {
159
+ // Standalone: bun rules/ga/main.mjs — повний еквівалент `npx @nitra/cursor check ga`.
160
+ process.exitCode = await runRuleCli(import.meta.dirname)
161
+ }
@@ -14,16 +14,16 @@ docgen:
14
14
  ## Поведінка
15
15
 
16
16
  1. Запуск правила.
17
- * Приймає контекст прогону.
18
- * Виконує застосування JS-занепокоєних.
19
- * Застосовує політику.
20
- * Генерує посилання MDC.
21
- * Повертає результат прогону.
17
+ - Приймає контекст прогону.
18
+ - Виконує застосування JS-занепокоєних.
19
+ - Застосовує політику.
20
+ - Генерує посилання MDC.
21
+ - Повертає результат прогону.
22
22
 
23
23
  2. Запуск у режимі CLI.
24
- * Виконується як автономний скрипт.
25
- * Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
26
- * Перевіряє результат прогону для встановлення коду виходу.
24
+ - Виконується як автономний скрипт.
25
+ - Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
26
+ - Перевіряє результат прогону для встановлення коду виходу.
27
27
 
28
28
  ## Публічний API
29
29
 
@@ -6,6 +6,7 @@ resource: npm/rules/graphql/
6
6
 
7
7
  # npm/rules/graphql
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [fix.mjs](fix.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ------------------- | --------- |
11
+ | [fix.mjs](fix.md) | JS Module |
12
+ | [main.mjs](main.md) | JS Module |