@nitra/cursor 12.6.1 → 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 (266) hide show
  1. package/.claude-template/settings.template.json +1 -1
  2. package/CHANGELOG.md +10 -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/tool-surface/docs/index.md +1 -0
  141. package/rules/tool-surface/docs/main.md +29 -0
  142. package/rules/tool-surface/main.mjs +20 -0
  143. package/rules/vue/docs/index.md +1 -0
  144. package/rules/vue/docs/main.md +29 -0
  145. package/rules/vue/main.mjs +20 -0
  146. package/rules/worktree/docs/index.md +1 -0
  147. package/rules/worktree/docs/main.md +28 -0
  148. package/rules/worktree/main.mjs +20 -0
  149. package/scripts/docs/index.md +1 -0
  150. package/scripts/docs/post-tool-use-check.md +29 -0
  151. package/scripts/docs/sync-claude-config.md +64 -92
  152. package/scripts/lib/adr/docs/normalize-cli.md +0 -3
  153. package/scripts/lib/adr/docs/normalize-pipeline.md +0 -3
  154. package/scripts/lib/docs/gha-workflow.md +25 -317
  155. package/scripts/lib/docs/index.md +1 -0
  156. package/scripts/lib/docs/list-project-rules-mdc.md +5 -4
  157. package/scripts/lib/docs/list-rule-ids.md +15 -148
  158. package/scripts/lib/docs/read-n-cursor-config-lite.md +12 -16
  159. package/scripts/lib/docs/run-lint-step.md +13 -13
  160. package/scripts/lib/docs/run-lint.md +30 -0
  161. package/scripts/lib/docs/run-rule-cli.md +14 -10
  162. package/scripts/lib/docs/run-standard-lint.md +27 -10
  163. package/scripts/lib/docs/run-standard-rule.md +12 -11
  164. package/scripts/lib/docs/timing-summary.md +11 -12
  165. package/scripts/lib/docs/worktree-notice.md +0 -3
  166. package/scripts/lib/fix/docs/index.md +1 -0
  167. package/scripts/lib/fix/docs/orchestrator.md +23 -18
  168. package/scripts/lib/fix/docs/run-conformance-check.md +32 -0
  169. package/scripts/lib/fix/docs/t0.md +10 -9
  170. package/scripts/lib/fix/orchestrator.mjs +5 -5
  171. package/scripts/lib/fix/{run-fix-check.mjs → run-conformance-check.mjs} +13 -13
  172. package/scripts/lib/fix/t0.mjs +3 -3
  173. package/scripts/lib/list-project-rules-mdc.mjs +1 -1
  174. package/scripts/lib/list-rule-ids.mjs +12 -3
  175. package/scripts/lib/read-n-cursor-config-lite.mjs +2 -2
  176. package/{rules/lint/js/orchestrate.mjs → scripts/lib/run-lint.mjs} +42 -20
  177. package/scripts/lib/run-rule-cli.mjs +4 -4
  178. package/scripts/lib/run-standard-lint.mjs +19 -6
  179. package/scripts/lib/run-standard-rule.mjs +4 -4
  180. package/scripts/lib/timing-summary.mjs +1 -1
  181. package/scripts/{post-tool-use-fix.mjs → post-tool-use-check.mjs} +9 -9
  182. package/scripts/sync-claude-config.mjs +2 -2
  183. package/rules/changelog/fix.mjs +0 -18
  184. package/rules/ci4/fix.mjs +0 -18
  185. package/rules/doc-files/fix.mjs +0 -19
  186. package/rules/doc-files/js/docs/lint.md +0 -34
  187. package/rules/doc-files/lint/docs/index.md +0 -11
  188. package/rules/doc-files/lint/docs/lint.md +0 -35
  189. package/rules/docker/fix.mjs +0 -18
  190. package/rules/docker/lint/docs/index.md +0 -11
  191. package/rules/docker/lint/docs/lint.md +0 -200
  192. package/rules/docker/lint/lint.mjs +0 -95
  193. package/rules/efes/fix.mjs +0 -18
  194. package/rules/feedback/fix.mjs +0 -18
  195. package/rules/ga/fix.mjs +0 -18
  196. package/rules/ga/js/docs/lint.md +0 -20
  197. package/rules/ga/js/lint.mjs +0 -12
  198. package/rules/ga/lint/docs/index.md +0 -11
  199. package/rules/ga/lint/docs/lint.md +0 -31
  200. package/rules/graphql/fix.mjs +0 -18
  201. package/rules/hasura/fix.mjs +0 -18
  202. package/rules/image-avif/fix.mjs +0 -18
  203. package/rules/image-compress/fix.mjs +0 -18
  204. package/rules/image-compress/js/docs/lint.md +0 -24
  205. package/rules/js-bun-db/fix.mjs +0 -18
  206. package/rules/js-bun-redis/fix.mjs +0 -18
  207. package/rules/js-lint/fix.mjs +0 -18
  208. package/rules/js-lint/js/docs/lint.md +0 -32
  209. package/rules/js-lint-ci/fix.mjs +0 -18
  210. package/rules/js-lint-ci/js/docs/lint.md +0 -22
  211. package/rules/js-lint-ci/js/lint.mjs +0 -15
  212. package/rules/js-mssql/fix.mjs +0 -18
  213. package/rules/js-run/fix.mjs +0 -18
  214. package/rules/k8s/fix.mjs +0 -18
  215. package/rules/k8s/js/lint.mjs +0 -14
  216. package/rules/k8s/lint/docs/index.md +0 -11
  217. package/rules/k8s/lint/docs/lint.md +0 -413
  218. package/rules/lint/docs/fix.md +0 -25
  219. package/rules/lint/docs/index.md +0 -11
  220. package/rules/lint/fix.mjs +0 -18
  221. package/rules/lint/js/docs/index.md +0 -11
  222. package/rules/lint/js/docs/orchestrate.md +0 -31
  223. package/rules/lint/meta.json +0 -1
  224. package/rules/nginx-default-tpl/fix.mjs +0 -18
  225. package/rules/npm-module/fix.mjs +0 -18
  226. package/rules/php/fix.mjs +0 -18
  227. package/rules/php/js/docs/lint.md +0 -20
  228. package/rules/php/js/lint.mjs +0 -15
  229. package/rules/php/lint/docs/index.md +0 -11
  230. package/rules/php/lint/docs/lint.md +0 -219
  231. package/rules/python/fix.mjs +0 -18
  232. package/rules/python/js/docs/lint.md +0 -21
  233. package/rules/python/js/lint.mjs +0 -14
  234. package/rules/python/lint/docs/index.md +0 -11
  235. package/rules/python/lint/docs/lint.md +0 -29
  236. package/rules/rego/fix.mjs +0 -18
  237. package/rules/rego/js/docs/lint.md +0 -21
  238. package/rules/rego/js/lint.mjs +0 -12
  239. package/rules/rego/lint/docs/index.md +0 -11
  240. package/rules/rego/lint/docs/lint.md +0 -208
  241. package/rules/rust/fix.mjs +0 -18
  242. package/rules/rust/js/docs/lint.md +0 -21
  243. package/rules/security/fix.mjs +0 -18
  244. package/rules/security/js/docs/lint.md +0 -175
  245. package/rules/security/js/lint.mjs +0 -26
  246. package/rules/style-lint/fix.mjs +0 -18
  247. package/rules/style-lint/js/docs/lint.md +0 -31
  248. package/rules/tauri/fix.mjs +0 -18
  249. package/rules/test/fix.mjs +0 -18
  250. package/rules/text/fix.mjs +0 -18
  251. package/rules/text/js/docs/lint.md +0 -23
  252. package/rules/text/js/lint.mjs +0 -15
  253. package/rules/text/lint/docs/cspell-fix.md +0 -32
  254. package/rules/text/lint/docs/index.md +0 -15
  255. package/rules/text/lint/docs/lint.md +0 -36
  256. package/rules/text/lint/docs/run-dotenv-linter.md +0 -161
  257. package/rules/text/lint/docs/run-shellcheck.md +0 -216
  258. package/rules/text/lint/docs/run-v8r.md +0 -201
  259. package/rules/tool-surface/fix.mjs +0 -18
  260. package/rules/vue/fix.mjs +0 -18
  261. package/rules/worktree/fix.mjs +0 -18
  262. /package/rules/release/{fix.mjs → main.mjs} +0 -0
  263. /package/rules/text/{lint → js}/cspell-fix.mjs +0 -0
  264. /package/rules/text/{lint → js}/run-dotenv-linter.mjs +0 -0
  265. /package/rules/text/{lint → js}/run-shellcheck.mjs +0 -0
  266. /package/rules/text/{lint → js}/run-v8r.mjs +0 -0
@@ -1,32 +0,0 @@
1
- ---
2
- type: JS Module
3
- title: cspell-fix.mjs
4
- resource: npm/rules/text/lint/cspell-fix.mjs
5
- docgen:
6
- crc: 7b40e8f9
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
- score: 95
9
- issues: anchor-miss:meta.json,judge:inaccurate:0.98
10
- judgeModel: openai-codex/gpt-5.4-mini
11
- ---
12
-
13
- ## Огляд
14
-
15
- Цей модуль інтегрує cspell у ланцюжок lint-text для класифікації невідомих слів згідно зі схемою omlx. Він витягує невідомі слова, класифікує їх за допомогою LLM (detect $\rightarrow$ omlx-класифікація) та автоматично дописує валідні терміни до словника `.cspell.json`. Нерозкласифіковані та ймовірні одруки залишаються для ручного рев'ю. Процес є read-only, оскільки він лише класифікує знахідки, а не переписує файли.
16
-
17
- ## Поведінка
18
-
19
- unknownWords витягує унікальні невідомі слова з виводу cspell.
20
- appendWordsToDict дописує класифіковані валідні слова до файлу .cspell.json, оновлюючи словник.
21
- runCspellText запускає cspell, класифікує знахідки за допомогою LLM (якщо увімкнено) та повторно перевіряє код, повертаючи 0 при чистоті або 1 при знахідках.
22
-
23
- ## Публічний API
24
-
25
- unknownWords — Збирає унікальні слова, які не були знайдені у словнику cspell.
26
- appendWordsToDict — Додає зібрані слова до файлу `.cspell.json#words` у відсортованому та унікальному вигляді для перегляду у Git.
27
- runCspellText — Виконує перевірку тексту за допомогою cspell, класифікуючи слова та оновлюючи словник за новою схемою.
28
-
29
- ## Гарантії поведінки
30
-
31
- - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
32
- - За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
@@ -1,15 +0,0 @@
1
- ---
2
- type: Directory Index
3
- title: npm/rules/text/lint
4
- resource: npm/rules/text/lint/
5
- ---
6
-
7
- # npm/rules/text/lint
8
-
9
- | Файл | Тип |
10
- |---|---|
11
- | [cspell-fix.mjs](cspell-fix.md) | JS Module |
12
- | [lint.mjs](lint.md) | JS Module |
13
- | [run-dotenv-linter.mjs](run-dotenv-linter.md) | JS Module |
14
- | [run-shellcheck.mjs](run-shellcheck.md) | JS Module |
15
- | [run-v8r.mjs](run-v8r.md) | JS Module |
@@ -1,36 +0,0 @@
1
- ---
2
- type: JS Module
3
- title: lint.mjs
4
- resource: npm/rules/text/lint/lint.mjs
5
- docgen:
6
- crc: 02550273
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
- score: 90
9
- ---
10
-
11
- runLintTextCli надає внутрішню обгортку для послідовного лінтингу текстових файлів (text.mdc). Обгортка автоматично встановлює необхідні інструменти (`shellcheck`, `dotenv-linter`) через `ensureTool` перед виконанням ланцюжка перевірок. Ланцюжок включає: перевірку правопису (`cspell`), аналіз скриптів (`shellcheck`), перевірку конфігураційних файлів (`dotenv-linter`), форматування Markdown (`markdownlint-cli2`) та валідацію схем (`v8r`). При виявленні першого ненульового коду в ланцюжку, цей код повертається як код виходу, і подальші кроки не виконуються. Зовнішня точка входу правила — `n-cursor lint text`.
12
-
13
- ## Поведінка
14
-
15
- 1. Викликається `runLintTextCli` для запуску процесу лінтингу.
16
- 2. Якщо передано опцію для режиму лише перевірки, всі кроки виконуються без автоматичного виправлення.
17
- 3. Перед виконанням лінтингу автоматично встановлюються необхідні інструменти (`shellcheck`, `dotenv-linter`).
18
- 4. Перевіряється наявність інструменту `patch` для можливого автоматичного виправлення помилок `shellcheck`.
19
- 5. Виконується перевірка правопису за допомогою `cspell`.
20
- 6. Виконується автоматичне виправлення та фінальна перевірка скриптів `.sh` за допомогою `shellcheck`.
21
- 7. Виконується автоматичне виправлення та фінальна перевірка файлів `.env*` за допомогою `dotenv-linter`.
22
- 8. Виконується автоматичне виправлення файлів Markdown (`.md`, `.mdc`) за допомогою `markdownlint-cli2`.
23
- 9. Виконується валідація схем для файлів JSON, JSON5, YAML, YML, TOML за допомогою `v8r`.
24
- 10. Якщо будь-який крок повертає ненульовий код, виконання зупиняється, і повертається код цього першого невдалого кроку.
25
- 11. У разі успішного виконання всіх кроків повертається код 0.
26
- 12. У разі відсутності необхідних бінарників, `runLintTextCli` виводить повідомлення про помилку з інструкціями щодо встановлення (text.mdc).
27
-
28
- ## Публічний API
29
-
30
- runLintTextCli — Виконує лінтинг тексту через командний інтерфейс, синхронізуючи доступ за допомогою блокування та усуваючи дублікати на основі стану Git-дерева. (text.mdc)
31
-
32
- ## Гарантії поведінки
33
-
34
- - Read-only: файл не виконує операцій запису у файлову систему.
35
- - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
36
- - Не звертається до мережі.
@@ -1,161 +0,0 @@
1
- ---
2
- type: JS Module
3
- title: run-dotenv-linter.mjs
4
- resource: npm/rules/text/lint/run-dotenv-linter.mjs
5
- docgen:
6
- crc: 4719ac66
7
- ---
8
-
9
- Модуль `run-dotenv-linter.mjs` інкапсулює інтеграцію зовнішнього інструмента **dotenv-linter** у ланцюжок `lint-text` правила `text` (тека `npm/rules/text/lint/`). Він виконує дві послідовні фази:
10
-
11
- 1. **Авто-фікс** — `dotenv-linter fix -r --no-backup --quiet . --exclude …`. dotenv-linter сам застосовує всі підтримувані виправлення на місці (на відміну від shellcheck, який лише пропонує diff).
12
- 2. **Фінальна перевірка** — `dotenv-linter check -r --quiet . --exclude …`. Якщо лишаються порушення, їх вивід ретранслюється у `stdout`/`stderr`, а функція повертає код `1`.
13
-
14
- `dotenv-linter` — швидкий лінтер для `.env`-файлів, що ловить правила на кшталт `LowercaseKey`, `DuplicatedKey`, `IncorrectDelimiter`, `UnorderedKey` тощо. Він **очікується у `PATH`** і **не** додається в `dependencies` / `devDependencies` проєкту (та сама модель, що й `shellcheck`). Якщо бінарника немає, користувач отримує підказки встановлення (`brew`, `curl`, `cargo`), а функція повертає `1`.
15
-
16
- Файли модуль не перераховує самостійно — це робить сам `dotenv-linter` у режимі `-r` (рекурсивний обхід дерева проєкту). З обходу виключаються `node_modules` (стороння кодова база) та `.envrc` (синтаксис direnv shell, не `key=value`). Резервні `.bak`-файли інструмент ігнорує самостійно. За відсутності `.env*`-файлів `dotenv-linter` повертає `0` ("Nothing to check").
17
-
18
- Файл одночасно є **бібліотечним модулем** (експортує функцію `runDotenvLinter`) та **CLI-точкою входу**: за прямого запуску (`node run-dotenv-linter.mjs`) він викликає функцію та виставляє `process.exitCode` у її результат.
19
-
20
- ## Експорти / API
21
-
22
- | Експорт | Тип | Призначення |
23
- | ----------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------- |
24
- | `runDotenvLinter(cwd?)` | named function | Запуск двофазного циклу `fix` + `check` для `.env`-файлів у дереві `cwd`. Повертає числовий exit-code (`0` або `1`). |
25
-
26
- Інші ідентифікатори модуля (`EXCLUDED_PATHS`, `printDotenvLinterInstallHints`, `buildExcludeArgs`) — внутрішні, **не** експортуються.
27
-
28
- ## Функції
29
-
30
- ### `runDotenvLinter(cwd?)`
31
-
32
- Публічний експорт; основна логіка модуля.
33
-
34
- - **Сигнатура:** `export function runDotenvLinter(cwd = process.cwd()): number`
35
- - **Параметри:**
36
- - `cwd` _(string, optional)_ — кореневий каталог для рекурсивного сканування. За замовчуванням — `process.cwd()`. Перед використанням нормалізується через `node:path#resolve` в абсолютний шлях.
37
- - **Повертає:** `number`
38
- - `0` — `dotenv-linter check` завершився без порушень (включно з ситуацією "Nothing to check").
39
- - `1` — будь-яка з наступних умов:
40
- - бінарник `dotenv-linter` не знайдено у `PATH` (`resolveCmd` повернув falsy);
41
- - `spawnSync` для фази `fix` повернув `error` (наприклад, помилка спавну процесу);
42
- - `spawnSync` для фази `check` повернув `error`;
43
- - `check`-прогон завершився з ненульовим `status` (виявлені залишкові порушення).
44
- - **Побічні ефекти:**
45
- - Викликає `spawnSync` із зовнішнім бінарником `dotenv-linter` — два окремих процеси (`fix`, потім `check`).
46
- - Може модифікувати файли `.env*` у дереві `cwd` (фаза `fix`). Прапорець `--no-backup` гарантує, що `.bak`-файли не створюються.
47
- - Записує підказки встановлення у `process.stderr`, якщо бінарника немає.
48
- - Записує повідомлення про помилку `spawnSync` у `process.stderr` (поле `.error.message`), якщо процес не вдалося запустити.
49
- - На фазі `check`: при ненульовому `status` ретранслює зібрані `stdout`/`stderr` дочірнього процесу в `process.stdout` / `process.stderr` (захищено `?.length`).
50
- - Не змінює глобального стану модуля; чистий exit-code-based контракт.
51
- - **Контракт виклику дочірніх процесів:**
52
- - Аргументи fix: `['fix', '-r', '--no-backup', '--quiet', ...exclude, '.']`.
53
- - Аргументи check: `['check', '-r', '--quiet', ...exclude, '.']`.
54
- - `cwd` — нормалізований `root`.
55
- - `encoding: 'utf8'`, `env: process.env`, `stdio: ['ignore', 'pipe', 'pipe']` (stdin закритий, stdout/stderr захоплюються в буфер).
56
-
57
- ### `printDotenvLinterInstallHints()` _(internal)_
58
-
59
- - **Сигнатура:** `function printDotenvLinterInstallHints(): void`
60
- - **Параметри:** немає.
61
- - **Повертає:** `void`.
62
- - **Побічні ефекти:** Пише у `process.stderr` багаторядкове повідомлення з трьома варіантами встановлення (`brew`, `curl … sh`, `cargo install`) та заголовком `❌ dotenv-linter не знайдено в PATH.`. Завершується порожнім рядком (зручне відокремлення в логах).
63
-
64
- ### `buildExcludeArgs()` _(internal)_
65
-
66
- - **Сигнатура:** `function buildExcludeArgs(): string[]`
67
- - **Параметри:** немає.
68
- - **Повертає:** плоский масив аргументів CLI у форматі, який очікує `dotenv-linter`: `['--exclude', 'node_modules', '--exclude', '.envrc']`. Формується через `EXCLUDED_PATHS.flatMap(p => ['--exclude', p])`, тож додавання нового елемента в `EXCLUDED_PATHS` автоматично продовжує перелік прапорців.
69
- - **Побічні ефекти:** немає (чиста функція).
70
-
71
- ## Константи
72
-
73
- ### `EXCLUDED_PATHS`
74
-
75
- - **Тип:** `string[]`
76
- - **Значення:** `['node_modules', '.envrc']`
77
- - **Призначення:** Перелік каталогів/файлів, які виключаються з рекурсивного сканування `dotenv-linter -r`. Семантика:
78
- - `node_modules` — стороння кодова база, її `.env*` не наша зона відповідальності.
79
- - `.envrc` — файл direnv із shell-синтаксисом (`export FOO=bar`, `source_up` тощо), формально не key=value `.env`, лінтер на ньому давав би false positives.
80
-
81
- ## Залежності
82
-
83
- ### Стандартна бібліотека Node.js
84
-
85
- - `node:child_process` — функція `spawnSync` для синхронного запуску дочірніх процесів `dotenv-linter`.
86
- - `node:path` — функція `resolve` для нормалізації `cwd` в абсолютний шлях.
87
-
88
- ### Внутрішні модулі проєкту
89
-
90
- - `../../../scripts/cli-entry.mjs` — функція `isRunAsCli(import.meta.url)`. Детектує, чи модуль запущений як CLI (а не імпортований). При `true` виставляється `process.exitCode`.
91
- - `../../../scripts/utils/resolve-cmd.mjs` — функція `resolveCmd(name)`. Шукає виконуваний файл у `PATH`; повертає абсолютний шлях або falsy-значення, якщо бінарника немає.
92
-
93
- ### Зовнішній інструмент
94
-
95
- - **`dotenv-linter`** — нативний бінарник, очікується у `PATH`. **Не** є npm-залежністю проєкту. Встановлюється окремо командами:
96
- - macOS: `brew install dotenv-linter`
97
- - Linux: `curl -sSfL https://git.io/JLbXn | sh -s -- -b /usr/local/bin`
98
- - cargo: `cargo install dotenv-linter`
99
-
100
- ## Потік виконання / Використання
101
-
102
- ### Як CLI
103
-
104
- Файл містить хвостовий блок:
105
-
106
- ```js
107
- if (isRunAsCli(import.meta.url)) {
108
- process.exitCode = runDotenvLinter()
109
- }
110
- ```
111
-
112
- Тобто прямий запуск виставить exit-code процесу у `0` (успіх) або `1` (помилка/порушення). Виклик:
113
-
114
- ```sh
115
- node npm/rules/text/lint/run-dotenv-linter.mjs
116
- ```
117
-
118
- `cwd` при цьому — поточний робочий каталог процесу (`process.cwd()`).
119
-
120
- ### Як бібліотечний модуль
121
-
122
- Імпортується з оркестратора `lint-text`:
123
-
124
- ```js
125
- import { runDotenvLinter } from './run-dotenv-linter.mjs'
126
-
127
- const code = runDotenvLinter('/abs/path/to/project')
128
- if (code !== 0) process.exit(code)
129
- ```
130
-
131
- ### Покроковий потік
132
-
133
- 1. **Нормалізація `cwd`.** `resolve(cwd)` → абсолютний `root`.
134
- 2. **Резолв бінарника.** `resolveCmd('dotenv-linter')` шукає виконуваний файл у `PATH`.
135
- - Якщо `null`/`undefined`/порожній рядок → виклик `printDotenvLinterInstallHints()` → повернення `1`. Подальші кроки не виконуються.
136
- 3. **Підготовка списку виключень.** `buildExcludeArgs()` → `['--exclude', 'node_modules', '--exclude', '.envrc']`.
137
- 4. **Фаза fix.** `spawnSync(bin, ['fix', '-r', '--no-backup', '--quiet', '--exclude', 'node_modules', '--exclude', '.envrc', '.'], { cwd: root, encoding: 'utf8', env: process.env, stdio: ['ignore', 'pipe', 'pipe'] })`.
138
- - Якщо `fixRun.error` (наприклад, EACCES/ENOENT при спавні) → запис `fixRun.error.message` у `stderr` → повернення `1`.
139
- - `status` фази `fix` **не** перевіряється — інструмент може повертати ненульовий код, якщо лишилися ще не виправлені порушення; це штатно, бо далі йде фінальний `check`.
140
- 5. **Фаза check.** `spawnSync(bin, ['check', '-r', '--quiet', '--exclude', 'node_modules', '--exclude', '.envrc', '.'], …)` з тими самими опціями оточення.
141
- - Якщо `checkRun.error` → запис `checkRun.error.message` у `stderr` → повернення `1`.
142
- - Якщо `checkRun.status === 0` → повернення `0` (успіх).
143
- - Інакше: за наявності `checkRun.stdout` пишемо його у `process.stdout`, за наявності `checkRun.stderr` — у `process.stderr`, повертаємо `1`.
144
-
145
- ### Контракт побічних ефектів
146
-
147
- | Подія | Куди пишеться | Коли |
148
- | ------------------------------ | ---------------- | ---------------------------------------- |
149
- | Підказки встановлення | `process.stderr` | бінарника немає у `PATH` |
150
- | `error.message` зі `spawnSync` | `process.stderr` | помилка спавну `fix` або `check` |
151
- | `stdout` дочірнього `check` | `process.stdout` | `check.status !== 0` та буфер непорожній |
152
- | `stderr` дочірнього `check` | `process.stderr` | `check.status !== 0` та буфер непорожній |
153
- | Модифікація `.env*`-файлів | дерево `cwd` | фаза `fix` (без `.bak`) |
154
-
155
- ### Інтеграція в `lint-text`
156
-
157
- Модуль викликається сусіднім оркестратором `lint.mjs` тієї ж теки разом із `run-shellcheck.mjs` і `run-v8r.mjs`. Кожен раннер повертає `0` / `1`, оркестратор агрегує коди для фінального exit-status команди `lint-text`. Кожна перевірка ізольована — падіння одного раннера не блокує запуск інших, якщо це визначено архітектурою оркестратора.
158
-
159
- ### Тестування
160
-
161
- Поруч у теці є `tests/`, що містить юніт-тести для раннерів `lint-`. Модуль навмисно структуровано так, щоб тестам було легко мокати `spawnSync` і `resolveCmd`: усі гілки повернення (`bin not found`, `fix error`, `check error`, `check non-zero`, `check ok`) відокремлені й деталі поведінки видимі через `process.stdout`/`process.stderr`.
@@ -1,216 +0,0 @@
1
- ---
2
- type: JS Module
3
- title: run-shellcheck.mjs
4
- resource: npm/rules/text/lint/run-shellcheck.mjs
5
- docgen:
6
- crc: 6b2daaa8
7
- ---
8
-
9
- Модуль `run-shellcheck.mjs` — частина ланцюжка `lint-text` для перевірки якості shell-скриптів (`*.sh`) у проєкті за допомогою зовнішнього інструменту **ShellCheck**. Скрипт виконує два етапи:
10
-
11
- 1. **Авто-виправлення**: оскільки ShellCheck не має прапорця `--fix`, для кожного знайденого `*.sh` файла модуль запускає `shellcheck -f diff` і застосовує отриманий unified-diff через системну утиліту `patch -p1` у корені проєкту. Цикл повторюється до `MAX_FIX_ROUNDS_PER_FILE` (32) разів, поки залишаються авто-виправні зауваження.
12
- 2. **Фінальний прогон**: звичайний `shellcheck` по всіх зібраних файлах. Будь-яке попередження чи помилка дають ненульовий код виходу.
13
-
14
- Модуль уміє працювати як **CLI** (через `isRunAsCli`) і як **бібліотека** (експортує функції). Шляхи скриптів збираються з `git ls-files` у git-репозиторії або через `globSync` (з виключенням `node_modules`) поза git-деревом.
15
-
16
- Якщо у системі немає `shellcheck` чи `patch`, у stderr друкуються підказки встановлення для macOS (Homebrew), Debian/Ubuntu (apt) та Arch (pacman), а скрипт завершується з кодом 1.
17
-
18
- ## Експорти / API
19
-
20
- | Експорт | Тип | Призначення |
21
- | --------------------------- | -------------- | ---------------------------------------------------------------------------------- |
22
- | `listShellScriptPaths(cwd)` | named function | Зібрати відсортований унікальний список відносних шляхів до `*.sh` файлів у `cwd`. |
23
- | `runShellcheckText(cwd?)` | named function | Запустити повний цикл: авто-фікси + фінальна перевірка. Повертає код виходу (0/1). |
24
-
25
- Модуль також виконується як CLI: якщо `import.meta.url` відповідає поточному запуску — викликається `runShellcheckText()` і її результат присвоюється `process.exitCode`.
26
-
27
- ## Функції
28
-
29
- ### `printShellcheckInstallHints()`
30
-
31
- - **Сигнатура**: `function printShellcheckInstallHints(): void`
32
- - **Параметри**: немає.
33
- - **Повертає**: `void`.
34
- - **Side effects**: пише у `process.stderr` повідомлення з інструкціями встановлення `shellcheck` для macOS, Debian/Ubuntu та Arch.
35
-
36
- ### `printPatchInstallHints()`
37
-
38
- - **Сигнатура**: `function printPatchInstallHints(): void`
39
- - **Параметри**: немає.
40
- - **Повертає**: `void`.
41
- - **Side effects**: пише у `process.stderr` підказку про встановлення `patch` (на macOS зазвичай є; на Debian/Ubuntu — `sudo apt-get install -y patch`).
42
-
43
- ### `listShellScriptPaths(cwd)` (export)
44
-
45
- - **Сигнатура**: `function listShellScriptPaths(cwd: string): string[]`
46
- - **Параметри**:
47
- - `cwd` — абсолютний шлях до кореня проєкту (вже має бути нормалізований через `resolve`, якщо потрібно).
48
- - **Повертає**: відсортований масив унікальних відносних шляхів до `*.sh` файлів від `cwd`. Слеші уніфікуються в forward-slash (`'/'`).
49
- - **Side effects**: виконує `git rev-parse --is-inside-work-tree` і `git ls-files -z -- ':(glob)**/*.sh'` через `spawnSync`; у безгітовому контексті — викликає `globSync('**/*.sh')` з виключенням `node_modules`.
50
- - **Логіка**:
51
- - Якщо `git` доступний і `cwd` — частина git-робочого дерева, читаються лише tracked файли (`ls-files` з NUL-розділенням, дублікати усуваються через `Set`).
52
- - Якщо `git` доступний, але `ls-files` повертає ненульовий статус — повертається порожній масив.
53
- - Інакше — `globSync` з `exclude`, який відкидає шляхи, що містять `node_modules` (на будь-якому рівні), і нормалізує бекслеші (`\\` → `/`).
54
-
55
- ### `runShellcheckText(cwd = process.cwd())` (export)
56
-
57
- - **Сигнатура**: `function runShellcheckText(cwd?: string): number`
58
- - **Параметри**:
59
- - `cwd` — необов'язковий робочий каталог. За замовчуванням — `process.cwd()`.
60
- - **Повертає**: `0` — все OK; `1` — помилка середовища (немає `shellcheck`/`patch`), помилка spawn, або залишкові зауваження ShellCheck після авто-фіксів.
61
- - **Side effects**:
62
- - Можливий вивід підказок у `stderr` (якщо немає `shellcheck`/`patch`).
63
- - Запис патчів у файли через `patch -p1` (модифікує source-файли).
64
- - Друк звичайного звіту ShellCheck у `stdout`/`stderr` на фінальному кроці.
65
- - **Алгоритм**:
66
- 1. `root = resolve(cwd)`.
67
- 2. `shellcheck = resolveCmd('shellcheck')` → якщо немає, друк підказки та `return 1`.
68
- 3. `patchBin = resolveCmd('patch')` → якщо немає, друк підказки та `return 1`.
69
- 4. `files = listShellScriptPaths(root)` → якщо порожньо, `return 0`.
70
- 5. Для кожного `rel` із `files`: `autofixOneFile(...)`. Якщо ненульовий код — негайний `return`.
71
- 6. `return runFinalShellcheck(shellcheck, files, root)`.
72
-
73
- ### `autofixOneFile(shellcheck, patchBin, root, rel)`
74
-
75
- - **Сигнатура**: `function autofixOneFile(shellcheck: string, patchBin: string, root: string, rel: string): number`
76
- - **Параметри**:
77
- - `shellcheck` — абсолютний шлях до бінарника ShellCheck.
78
- - `patchBin` — абсолютний шлях до бінарника `patch`.
79
- - `root` — абсолютний `cwd` для spawn.
80
- - `rel` — відносний шлях файла від `root`.
81
- - **Повертає**: `0` — більше нема чого фіксити (нормальне завершення циклу); `1` — помилка spawn чи помилка `patch`.
82
- - **Side effects**: до 32 викликів `spawnSync(shellcheck, ['-f', 'diff', rel])` і `applyShellcheckDiff(...)` на файл; модифікує сам файл через `patch`.
83
- - **Логіка**:
84
- - У циклі `0..MAX_FIX_ROUNDS_PER_FILE-1`:
85
- - Запускає `shellcheck -f diff <rel>` з `maxBuffer: 10MiB`.
86
- - Якщо `diffResult.error` — друкує повідомлення і повертає 1.
87
- - Якщо `shouldStopAutofixLoop(diffResult)` — повертає 0.
88
- - Інакше — `applyShellcheckDiff(...)`. На помилку — повертає 1.
89
- - Якщо досягнуто `MAX_FIX_ROUNDS_PER_FILE` — повертає 0 (захист від зациклення).
90
-
91
- ### `shouldStopAutofixLoop(diffResult)`
92
-
93
- - **Сигнатура**: `function shouldStopAutofixLoop(diffResult: { status: number | null, stdout?: string | null, stderr?: string | null }): boolean`
94
- - **Параметри**:
95
- - `diffResult` — об'єкт результату `spawnSync` (потрібні `status`, `stdout`, `stderr`).
96
- - **Повертає**: `true`, якщо подальші ітерації авто-фіксів не мають сенсу.
97
- - **Side effects**: немає (чиста перевірка).
98
- - **Логіка**: повертає `true`, якщо
99
- - `status === 0` (ShellCheck не знайшов зауважень), **або**
100
- - `stderr` містить підрядок `'none were auto-fixable'` (`NON_AUTOFIXABLE_HINT`), **або**
101
- - `stdout` після `trim()` порожній (нема дифу для застосування).
102
-
103
- ### `applyShellcheckDiff(patchBin, root, rel, diffStdout)`
104
-
105
- - **Сигнатура**: `function applyShellcheckDiff(patchBin: string, root: string, rel: string, diffStdout: string): number`
106
- - **Параметри**:
107
- - `patchBin` — абсолютний шлях до `patch`.
108
- - `root` — `cwd` для spawn (корінь проєкту).
109
- - `rel` — відносний шлях файла, для якого формується diff (використовується тільки у повідомленні про помилку).
110
- - `diffStdout` — вміст unified-diff, отриманий від `shellcheck -f diff`.
111
- - **Повертає**: `0` — патч застосовано; `1` — `patch` повернув ненульовий код.
112
- - **Side effects**:
113
- - Запускає `patch -p1` із `diffStdout` через stdin.
114
- - На помилку виливає `stderr` і `stdout` процесу `patch` у `process.stderr`, а також додає рядок `run-shellcheck-text: patch не застосував diff для ${rel}`.
115
-
116
- ### `runFinalShellcheck(shellcheck, files, root)`
117
-
118
- - **Сигнатура**: `function runFinalShellcheck(shellcheck: string, files: string[], root: string): number`
119
- - **Параметри**:
120
- - `shellcheck` — абсолютний шлях до ShellCheck.
121
- - `files` — відносні шляхи усіх файлів для перевірки.
122
- - `root` — `cwd` для spawn.
123
- - **Повертає**: `0` — звіт чистий; `1` — `spawnSync` віддав `error` або `status !== 0`.
124
- - **Side effects**:
125
- - Виконує `shellcheck <files...>` без прапорця `-f diff`, з `maxBuffer: 10MiB` і `stdio: ['ignore', 'pipe', 'pipe']`.
126
- - Якщо є помилка — друкує `error.message` у `stderr`.
127
- - Якщо `status !== 0` — друкує `stdout` у `process.stdout` і `stderr` у `process.stderr`.
128
-
129
- ## Константи
130
-
131
- | Ім'я | Значення | Призначення |
132
- | ------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------ |
133
- | `NON_AUTOFIXABLE_HINT` | `'none were auto-fixable'` | Маркер у stderr ShellCheck про відсутність авто-виправлень — критерій виходу з циклу `autofixOneFile`. |
134
- | `MAX_FIX_ROUNDS_PER_FILE` | `32` | Жорсткий ліміт ітерацій `diff`+`patch` на один файл для уникнення зациклення. |
135
-
136
- ## Залежності
137
-
138
- ### Node.js (built-in)
139
-
140
- - `node:child_process` → `spawnSync` — синхронний запуск `git`, `shellcheck`, `patch`.
141
- - `node:fs` → `globSync` — пошук `*.sh` поза git-деревом.
142
- - `node:path` → `resolve` — нормалізація `cwd` у абсолютний шлях.
143
-
144
- ### Внутрішні модулі
145
-
146
- - `../../../scripts/cli-entry.mjs` → `isRunAsCli(import.meta.url)` — перевіряє, чи модуль запущено напряму як CLI (а не імпортовано).
147
- - `../../../scripts/utils/resolve-cmd.mjs` → `resolveCmd(name)` — повертає абсолютний шлях до бінарника з PATH або `null`.
148
-
149
- ### Зовнішні бінарники (runtime)
150
-
151
- - **shellcheck** — обов'язковий; без нього `runShellcheckText` повертає 1.
152
- - **patch** — обов'язковий для авто-фіксів; без нього `runShellcheckText` повертає 1.
153
- - **git** — необов'язковий: якщо доступний і ми у робочому дереві — використовується `git ls-files`; інакше — `globSync`.
154
-
155
- ## Потік виконання / Використання
156
-
157
- ### CLI
158
-
159
- Скрипт можна запустити напряму:
160
-
161
- ```bash
162
- node npm/rules/text/lint/run-shellcheck.mjs
163
- ```
164
-
165
- Логіка CLI-входу:
166
-
167
- ```js
168
- if (isRunAsCli(import.meta.url)) {
169
- process.exitCode = runShellcheckText()
170
- }
171
- ```
172
-
173
- `process.exitCode` встановлюється у значення, повернуте `runShellcheckText()` (0 або 1).
174
-
175
- ### Програмний виклик
176
-
177
- ```js
178
- import { runShellcheckText, listShellScriptPaths } from './run-shellcheck.mjs'
179
-
180
- // Повний прогон у поточному каталозі:
181
- const code = runShellcheckText()
182
-
183
- // Тільки список *.sh файлів:
184
- const files = listShellScriptPaths(process.cwd())
185
- ```
186
-
187
- ### Високорівнева послідовність кроків `runShellcheckText`
188
-
189
- 1. `resolve(cwd)` → абсолютний `root`.
190
- 2. `resolveCmd('shellcheck')` → перевірка наявності бінарника. **Fail-fast**: підказка + `return 1`.
191
- 3. `resolveCmd('patch')` → перевірка наявності бінарника. **Fail-fast**: підказка + `return 1`.
192
- 4. `listShellScriptPaths(root)`:
193
- - `git` доступний і ми в робочому дереві → `git ls-files -z -- ':(glob)**/*.sh'` (NUL-роздільник, унікальні, відсортовані).
194
- - Інакше → `globSync('**/*.sh', { exclude: ... })` з виключенням `node_modules` (forward-slashes).
195
- 5. Якщо файлів немає → `return 0` (no-op).
196
- 6. Для кожного файла → `autofixOneFile(...)`:
197
- - Цикл до 32 разів: `shellcheck -f diff <rel>` → `patch -p1` (через stdin).
198
- - Виходить раніше, якщо `status === 0`, `none were auto-fixable`, або порожній diff.
199
- 7. `runFinalShellcheck(shellcheck, files, root)`:
200
- - `shellcheck <files...>` без формату diff.
201
- - Будь-який ненульовий статус → друк stdout/stderr у консоль і `return 1`.
202
-
203
- ### Коди виходу
204
-
205
- | Код | Причина |
206
- | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
207
- | `0` | Немає `*.sh` файлів, або всі пройшли фінальний `shellcheck` чисто (можливо, після авто-фіксів). |
208
- | `1` | Немає `shellcheck`/`patch` у PATH; помилка `spawnSync` (наприклад, `ENOENT`); `patch` не застосував diff; фінальний `shellcheck` повернув ненульовий статус. |
209
-
210
- ### Ефекти на файлову систему
211
-
212
- Авто-фікси **модифікують сам source `.sh`-файл** через `patch -p1`. Запуск передбачає, що користувач готовий побачити змінений вміст (наприклад, виконує перевірку перед коммітом у CI або локально).
213
-
214
- ### Контекст застосування
215
-
216
- Модуль використовується у складі `lint-text` ланцюжка (правила `npm/rules/text/lint/`) для перевірки текстової частини проєкту, де shell-скрипти підлягають аналізу ShellCheck. Це частина набору `rules/text/lint/*`, описаного у `n-text.mdc` і `n-js-lint.mdc`.