@nitra/cursor 5.3.4 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/.claude-template/settings.template.json +2 -2
  2. package/.pi-template/extensions/n-cursor-adr/docs/index.md +13 -24
  3. package/CHANGELOG.md +11 -0
  4. package/bin/n-cursor.js +43 -22
  5. package/lib/docs/models.md +29 -18
  6. package/lib/docs/omlx-trace.md +51 -0
  7. package/lib/docs/omlx.md +31 -15
  8. package/lib/omlx.mjs +2 -5
  9. package/package.json +1 -1
  10. package/rules/abie/docs/fix.md +17 -11
  11. package/rules/adr/docs/fix.md +25 -140
  12. package/rules/bun/docs/fix.md +18 -151
  13. package/rules/capacitor/docs/fix.md +16 -13
  14. package/rules/capacitor/js/docs/platforms.md +31 -43
  15. package/rules/changelog/docs/fix.md +25 -169
  16. package/rules/ci4/docs/fix.md +11 -14
  17. package/rules/doc-files/doc-files.mdc +60 -0
  18. package/rules/doc-files/docs/fix.md +31 -0
  19. package/rules/doc-files/fix.mjs +19 -0
  20. package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
  21. package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
  22. package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
  23. package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
  24. package/{skills → rules}/doc-files/js/docs/docgen-extract-anchors.md +1 -1
  25. package/{skills → rules}/doc-files/js/docs/docgen-extract.md +2 -2
  26. package/{skills → rules}/doc-files/js/docs/docgen-files-batch.md +1 -1
  27. package/{skills → rules}/doc-files/js/docs/docgen-gen.md +1 -1
  28. package/{skills → rules}/doc-files/js/docs/docgen-ignore.md +4 -4
  29. package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
  30. package/rules/doc-files/js/docs/docgen-scan.md +54 -0
  31. package/rules/doc-files/js/docs/lint.md +36 -0
  32. package/rules/doc-files/js/docs/units-js.md +31 -0
  33. package/rules/doc-files/js/docs/units-rs.md +35 -0
  34. package/rules/doc-files/js/docs/units.md +30 -0
  35. package/rules/doc-files/js/lint.mjs +96 -0
  36. package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
  37. package/rules/doc-files/lint/docs/lint.md +37 -0
  38. package/rules/doc-files/lint/lint.mjs +105 -0
  39. package/rules/doc-files/meta.json +1 -0
  40. package/rules/docker/docs/fix.md +21 -161
  41. package/rules/efes/docs/fix.md +23 -194
  42. package/rules/feedback/docs/fix.md +10 -8
  43. package/rules/ga/docs/fix.md +10 -5
  44. package/rules/graphql/docs/fix.md +23 -119
  45. package/rules/hasura/docs/fix.md +19 -5
  46. package/rules/hasura/js/docs/internal_urls.md +34 -307
  47. package/rules/image-avif/docs/fix.md +16 -127
  48. package/rules/image-compress/docs/fix.md +20 -141
  49. package/rules/image-compress/js/docs/package_setup.md +22 -182
  50. package/rules/js-bun-db/docs/fix.md +23 -139
  51. package/rules/js-bun-db/js/docs/safety.md +33 -221
  52. package/rules/js-bun-redis/docs/fix.md +25 -114
  53. package/rules/js-bun-redis/js/docs/imports.md +18 -166
  54. package/rules/js-lint/docs/fix.md +30 -108
  55. package/rules/js-lint/js/docs/lint-findings.md +37 -17
  56. package/rules/js-lint/js/docs/lint.md +22 -238
  57. package/rules/js-lint/js/docs/tooling.md +34 -331
  58. package/rules/js-lint-ci/docs/fix.md +16 -149
  59. package/rules/js-lint-ci/js/docs/lint.md +16 -136
  60. package/rules/js-mssql/docs/fix.md +18 -123
  61. package/rules/js-mssql/js/docs/deps.md +28 -251
  62. package/rules/js-run/docs/fix.md +23 -138
  63. package/rules/js-run/js/docs/runtime.md +24 -378
  64. package/rules/k8s/docs/fix.md +18 -123
  65. package/rules/nginx-default-tpl/docs/fix.md +22 -118
  66. package/rules/nginx-default-tpl/js/docs/template.md +38 -360
  67. package/rules/npm-module/docs/fix.md +27 -89
  68. package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
  69. package/rules/npm-module/js/docs/package_structure.md +36 -258
  70. package/rules/npm-module/js/docs/rule_meta.md +25 -127
  71. package/rules/npm-module/js/docs/skill_meta.md +18 -180
  72. package/rules/php/docs/fix.md +21 -98
  73. package/rules/php/js/docs/tooling.md +20 -143
  74. package/rules/python/docs/fix.md +25 -157
  75. package/rules/python/js/docs/applies.md +20 -98
  76. package/rules/python/js/docs/tooling.md +27 -144
  77. package/rules/rego/docs/fix.md +24 -112
  78. package/rules/rego/js/docs/applies.md +20 -164
  79. package/rules/rego/js/docs/lint.md +15 -110
  80. package/rules/release/docs/fix.md +16 -114
  81. package/rules/rust/docs/fix.md +24 -119
  82. package/rules/rust/js/docs/applies.md +20 -129
  83. package/rules/security/docs/fix.md +21 -78
  84. package/rules/security/js/docs/sample_secret.md +23 -182
  85. package/rules/security/js/docs/trufflehog.md +19 -128
  86. package/rules/style-lint/docs/fix.md +16 -150
  87. package/rules/style-lint/js/docs/lint.md +21 -172
  88. package/rules/style-lint/js/docs/tooling.md +19 -184
  89. package/rules/tauri/docs/fix.md +26 -152
  90. package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
  91. package/rules/tauri/js/docs/tooling.md +20 -217
  92. package/rules/test/docs/fix.md +19 -127
  93. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
  94. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
  95. package/rules/test/js/docs/cargo_mutants_config.md +24 -164
  96. package/rules/test/js/docs/location.md +24 -126
  97. package/rules/test/js/docs/no-process-chdir.md +20 -151
  98. package/rules/test/js/docs/no-relative-fs-path.md +24 -261
  99. package/rules/test/js/docs/stryker_config.md +48 -148
  100. package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
  101. package/rules/text/docs/fix.md +25 -113
  102. package/rules/text/js/docs/forbidden-prettier.md +21 -132
  103. package/rules/text/js/docs/formatting.md +60 -251
  104. package/rules/text/js/docs/lint.md +17 -114
  105. package/rules/vue/docs/fix.md +25 -118
  106. package/rules/vue/js/docs/packages.md +25 -323
  107. package/rules/worktree/docs/fix.md +31 -150
  108. package/scripts/coverage-classify/docs/index.md +23 -209
  109. package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
  110. package/scripts/dispatcher/docs/trace.md +35 -0
  111. package/scripts/docs/auto-rules.md +37 -361
  112. package/scripts/docs/lint-cli.md +12 -13
  113. package/scripts/docs/post-tool-use-fix.md +16 -15
  114. package/scripts/docs/skills-cli.md +26 -23
  115. package/scripts/docs/sync-claude-config.md +94 -34
  116. package/scripts/docs/worktree-cli.md +11 -34
  117. package/scripts/lib/docs/assert-project-root.md +14 -16
  118. package/scripts/lib/docs/changed-files.md +24 -139
  119. package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
  120. package/scripts/lib/docs/rule-predicates.md +20 -17
  121. package/scripts/lib/docs/run-rule-cli.md +14 -18
  122. package/scripts/lib/docs/run-rule.md +13 -20
  123. package/scripts/lib/docs/run-standard-rule.md +12 -15
  124. package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
  125. package/scripts/lib/rule-predicates.mjs +1 -1
  126. package/scripts/sync-claude-config.mjs +4 -1
  127. package/scripts/utils/docs/with-lock.md +19 -12
  128. package/scripts/utils/with-lock.mjs +4 -2
  129. package/skills/doc-aggregate/SKILL.md +2 -2
  130. package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
  131. package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
  132. package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
  133. package/skills/doc-files/.changes/260612-0031.md +5 -0
  134. package/skills/doc-files/.changes/260612-0036.md +5 -0
  135. package/skills/doc-files/.changes/260612-0114.md +5 -0
  136. package/skills/doc-files/SKILL.md +6 -6
  137. package/skills/fix/js/docs/llm-worker.md +17 -15
  138. package/skills/fix/js/docs/orchestrator.md +30 -23
  139. package/skills/fix/js/docs/t0.md +26 -16
  140. package/skills/start-check/js/docs/check.md +26 -22
  141. package/skills/taze/js/docs/diff.md +44 -20
  142. package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
  143. package/skills/doc-files/js/docs/docgen-scan.md +0 -25
  144. package/skills/doc-files/js/docs/units-rs.md +0 -35
  145. /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
  146. /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
  147. /package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +0 -0
  148. /package/{skills → rules}/doc-files/js/docgen-gen.mjs +0 -0
  149. /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
  150. /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
  151. /package/{skills → rules}/doc-files/js/units.mjs +0 -0
@@ -1,164 +1,30 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/rules/style-lint/fix.mjs
4
- crc: 12fc1644
4
+ crc: 38cf876b
5
+ score: 100
5
6
  ---
6
7
 
7
- # fix.mjs — точка входу правила `style-lint`
8
+ # fix.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Файл `npm/rules/style-lint/fix.mjs` це точка входу (entry-point) правила з ідентифікатором `style-lint` у системі `@nitra/cursor`. Він виконує дві ролі одночасно:
12
+ Файл застосовує визначене правило до вхідного контексту прогону. Застосовує правило та повертає отриманий результат.
12
13
 
13
- 1. **Library mode** — експортує функцію `run(ctx)`, яку зовнішній CLI-оркестратор (`npx @nitra/cursor fix <id>` чи внутрішній диспетчер правил) імпортує й запускає в межах загального прогону пакета правил.
14
- 2. **Standalone mode** — якщо файл запущено напряму через `bun rules/style-lint/fix.mjs`, він самостійно ініціалізує конфіг, whitelist, summary та повертає exit-code, повністю еквівалентний виклику `npx @nitra/cursor fix style-lint`.
14
+ ## Поведінка
15
15
 
16
- Сам файл навмисно тонкий: вся логіка перевірок винесена у спільні утиліти `runStandardRule` (стандартний пайплайн правила: `applies → JS-concerns → policy → mdc-refs`) і `runRuleCli` (обгортка для standalone-запуску). Це канонічна форма entry-point для будь-якого правила в монорепо `@nitra/cursor`, що дозволяє додавати нові правила, не дублюючи orchestration-код.
16
+ 1. Запуск правила.
17
+ * Приймає контекст прогону.
18
+ * Виконує правило.
19
+ * Повертає результат.
17
20
 
18
- Правило `style-lint` оперує над стилями (Style/CSS-частина) — деталі його перевірок мешкають у сусідніх теках (`js/`, `policy/`, `style-lint.mdc`), але сам цей файл їх не імпортує: пайплайн виявляє їх автоматично за конвенцією директорії `import.meta.dirname`.
21
+ ## Публічний API
19
22
 
20
- ## Експорти / API
23
+ run запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
24
+ Library mode — викликається CLI orchestration через `import + run`.
21
25
 
22
- | Експорт | Тип | Призначення |
23
- | ------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
24
- | `run` | `function (ctx?: RuleContext) => Promise<number>` | Запускає стандартний пайплайн правила `style-lint`. Повертає `0` за відсутності порушень, `1` — за наявності. |
26
+ ## Гарантії поведінки
25
27
 
26
- Експорт `run` це **публічний контракт правила**. Будь-який оркестратор, що знає лише шлях до директорії правила, може динамічно імпортувати `fix.mjs` і викликати `run(ctx)`.
27
-
28
- Жодних інших іменованих експортів, default-експорту, констант чи класів файл не надає.
29
-
30
- ## Функції
31
-
32
- ### `run(ctx)`
33
-
34
- ```js
35
- /**
36
- *
37
- */
38
- export function run(ctx) {
39
- return runStandardRule(import.meta.dirname, ctx)
40
- }
41
- ```
42
-
43
- - **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
44
- - **Параметри:**
45
- - `ctx` (необов'язковий) — об'єкт контексту прогону типу `RuleContext` (визначений у `../../scripts/lib/run-standard-rule.mjs`). Містить, зокрема, `walkCache` — кеш обходу файлової системи, який оркестратор переюзує між правилами, щоб не сканувати дерево повторно. Якщо `ctx` не передано — `runStandardRule` створить дефолтний контекст самостійно.
46
- - **Повертає:** `Promise<number>` — exit-code:
47
- - `0` — правило виконано, порушень не знайдено;
48
- - `1` — знайдено порушення (CI має зафейлити збірку).
49
- - **Side effects:**
50
- - Звертається до файлової системи через `runStandardRule` (читає файли проєкту, що підпадають під `applies`-фільтр правила).
51
- - Може писати у stdout/stderr (summary, помилки) через утиліти всередині `runStandardRule`.
52
- - Сам по собі функція **не** мутує жодного файлу — навіть для правил із суфіксом `fix.mjs` пайплайн у режимі звичайного прогону є read-only (модифікації виконуються в окремих fix-режимах, які тут не задіяні).
53
- - **Як працює:** делегує всю роботу `runStandardRule`, передаючи їй власну директорію (`import.meta.dirname` = абсолютний шлях до `npm/rules/style-lint/`). Пайплайн всередині послідовно прогонить чотири фази:
54
- 1. **applies** — визначення, які файли проєкту підпадають під дію правила;
55
- 2. **JS-concerns** — JS/MJS-перевірки (логіка з `js/`);
56
- 3. **policy** — Rego/політики (логіка з `policy/`);
57
- 4. **mdc-refs** — звірення посилань у `style-lint.mdc` (актуальність документації).
58
-
59
- ### Standalone-блок (top-level `if`)
60
-
61
- ```js
62
- if (isRunAsCli(import.meta.url)) {
63
- process.exit(await runRuleCli(import.meta.dirname))
64
- }
65
- ```
66
-
67
- - **Не функція**, а top-level guard, що виконується лише коли файл стартує безпосередньо як CLI-точка (а не імпортується іншим модулем).
68
- - **Детект:** `isRunAsCli(import.meta.url)` повертає `true`, коли `import.meta.url` відповідає аргументу запуску процесу (тобто `bun npm/rules/style-lint/fix.mjs` чи `node npm/rules/style-lint/fix.mjs`).
69
- - **Дія:** викликає `runRuleCli(import.meta.dirname)`, яка проганяє повний цикл CLI (config-loading, whitelist, summary, exit-code) і завершує процес через `process.exit` зі здобутим кодом.
70
- - **Чому `await` на верхньому рівні:** файл — ES-модуль `.mjs`, top-level `await` дозволений.
71
- - **Eslint-винятки:** `n/no-process-exit` та `unicorn/no-process-exit` навмисно відключені рядковим коментарем, бо для standalone entry-point явний `process.exit` — єдиний коректний спосіб віддати exit-code CI/IDE.
72
-
73
- ## Залежності
74
-
75
- ### Внутрішні (relative imports)
76
-
77
- | Модуль | Що з нього імпортовано | Роль |
78
- | ----------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
79
- | `../../scripts/lib/run-rule-cli.mjs` | `isRunAsCli`, `runRuleCli` | Утиліти standalone-режиму: детект CLI-запуску та повний CLI-цикл (config + whitelist + summary). |
80
- | `../../scripts/lib/run-standard-rule.mjs` | `runStandardRule` | Стандартний пайплайн правила (applies → JS-concerns → policy → mdc-refs). Також надає тип `RuleContext` (через JSDoc-typedef). |
81
-
82
- Шляхи `../../scripts/lib/...` обчислюються відносно `npm/rules/style-lint/` і вказують на `npm/scripts/lib/`.
83
-
84
- ### Зовнішні
85
-
86
- - **Жодних** npm-пакетів файл напряму не імпортує. Усі залежності — внутрішні.
87
- - **Runtime:** Node.js / Bun з підтримкою ESM, `import.meta.url`, `import.meta.dirname` та top-level `await`.
88
-
89
- ### Сусідні артефакти правила (не імпортуються тут, але задіяні через пайплайн)
90
-
91
- - `npm/rules/style-lint/meta.json` — метадані правила (id, applies-патерни тощо), читається `runStandardRule`/`runRuleCli`.
92
- - `npm/rules/style-lint/style-lint.mdc` — людиночитна специфікація правила (target для mdc-refs-фази).
93
- - `npm/rules/style-lint/js/` — JS-частина перевірок (підвантажується JS-concerns-фазою).
94
- - `npm/rules/style-lint/policy/` — Rego-політики (підвантажуються policy-фазою).
95
-
96
- ## Потік виконання / Використання
97
-
98
- ### Сценарій A — імпорт оркестратором (library mode)
99
-
100
- ```text
101
- @nitra/cursor CLI (або інший runner)
102
-
103
- │ dynamic import('npm/rules/style-lint/fix.mjs')
104
-
105
- fix.mjs → export run(ctx)
106
-
107
- │ runStandardRule(import.meta.dirname, ctx)
108
-
109
- run-standard-rule.mjs
110
-
111
- ├── applies-фаза (фільтр файлів)
112
- ├── JS-concerns-фаза (js/)
113
- ├── policy-фаза (policy/)
114
- └── mdc-refs-фаза (style-lint.mdc)
115
-
116
-
117
- return 0 | 1
118
- ```
119
-
120
- Оркестратор зазвичай передає `ctx` із попередньо побудованим `walkCache`, щоб уникнути повторного обходу файлового дерева між десятками правил.
121
-
122
- ### Сценарій B — пряма CLI-точка (standalone mode)
123
-
124
- ```text
125
- $ bun npm/rules/style-lint/fix.mjs
126
-
127
- │ Node/Bun завантажує fix.mjs як головний модуль
128
-
129
- import-блок виконано → run експортовано
130
-
131
-
132
- top-level if (isRunAsCli(import.meta.url)) // true
133
-
134
- │ await runRuleCli(import.meta.dirname)
135
-
136
- run-rule-cli.mjs
137
-
138
- ├── завантажує конфіг проєкту
139
- ├── застосовує whitelist
140
- ├── викликає внутрішньо аналог run(ctx)
141
- ├── друкує summary
142
- └── повертає number (exit-code)
143
-
144
-
145
- process.exit(<exit-code>)
146
- ```
147
-
148
- Цей режим використовується розробником локально (`bun npm/rules/style-lint/fix.mjs`) або IDE-інтеграцією, що очікує POSIX exit-code.
149
-
150
- ### Інваріанти та контракт
151
-
152
- - Файл — **stateless**: жодних модульних змінних, кешів, синглтонів. Усе передається через `ctx`.
153
- - Функція `run` **ідемпотентна** щодо файлової системи (read-only прогон).
154
- - `run` **завжди** повертає `Promise<number>` зі значенням `0` або `1` — оркестратор не повинен очікувати інших значень чи кидків.
155
- - Standalone-блок виконується **виключно** коли файл — головний модуль; при `import` із іншого коду блок мовчазно пропускається завдяки `isRunAsCli`.
156
-
157
- ### Як додати аналогічний entry-point для нового правила
158
-
159
- 1. Створити теку `npm/rules/<new-rule-id>/`.
160
- 2. Скопіювати цей `fix.mjs` без змін (шляхи відносні до `npm/rules/<id>/` ідентичні).
161
- 3. Покласти поруч `meta.json`, `<new-rule-id>.mdc`, `js/`, `policy/` за потреби.
162
- 4. Пайплайн `runStandardRule` підхопить нове правило автоматично, без правок самого `fix.mjs`.
163
-
164
- Це і є цінність «тонкого» entry-point: правила додаються декларативно, без дублювання orchestration-логіки.
28
+ - Read-only: файл не виконує операцій запису у файлову систему.
29
+ - Кешує результати в межах одного прогону.
30
+ - Не звертається до мережі.
@@ -1,184 +1,33 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/style-lint/js/lint.mjs
4
+ crc: 94e067b3
5
+ score: 100
6
+ ---
7
+
1
8
  # lint.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль `lint.mjs` — це «quick-крок» (швидкий етап) правила `style-lint`, який запускає `stylelint --fix` по стильових файлах проєкту: `*.css`, `*.scss`, `*.vue`. Модуль виконує дві окремі задачі:
6
-
7
- 1. Фільтрує довільний список шляхів, лишаючи з нього тільки файли зі стильовими розширеннями (`.css`, `.scss`, `.vue`).
8
- 2. Запускає виконуваний бінарник `stylelint` через `npx` з прапорцем `--fix` — або по точному списку файлів (режим «quick»), або по всьому glob-патерну `**/*.{css,scss,vue}` (режим «ci»).
9
-
10
- Модуль написаний як ES-модуль (`.mjs`), не має побічних ефектів на рівні імпорту (не запускає `stylelint` під час завантаження модуля) і експортує дві функції: `filterStyleFiles` та `lint`.
11
-
12
- Призначений для використання в інфраструктурі лінтінгу монорепо: викликається з оркестратора правил (наприклад, `tooling.mjs` сусіднього модуля), який передає або конкретний набір змінених файлів (швидкий цикл локального розробника), або `undefined` (повний прогін в CI).
13
-
14
- ## Експорти / API
15
-
16
- Модуль має два іменованих експорти:
17
-
18
- | Експорт | Тип | Призначення |
19
- | ------------------ | ---------- | -------------------------------------------------------------------------- |
20
- | `filterStyleFiles` | `function` | Чистий фільтр: з масиву шляхів повертає тільки `.css` / `.scss` / `.vue`. |
21
- | `lint` | `function` | Запускає `stylelint --fix` через `npx`, повертає `Promise<number>` (exit). |
22
-
23
- Дефолтного експорту немає.
24
-
25
- Окрім експортів, у модулі визначена константа модульного рівня `STYLE_EXT_RE` — приватна (не експортується) регулярка `/\.(?:css|scss|vue)$/u`, яка матчить лише суфікс імені файлу.
26
-
27
- ## Функції
28
-
29
- ### `filterStyleFiles(files)`
30
-
31
- **Сигнатура.**
32
-
33
- ```js
34
- export function filterStyleFiles(files: string[]): string[]
35
- ```
36
-
37
- **Параметри.**
38
-
39
- - `files` — масив рядків-шляхів (відносних або абсолютних — функція не розрізняє). Жодних обмежень на роздільник шляху чи на регістр розширення регулярка не накладає, окрім того що розширення має бути в нижньому регістрі (`.css`, `.scss`, `.vue`).
40
-
41
- **Повертає.**
42
-
43
- - `string[]` — новий масив, що містить лише ті елементи `files`, у яких суфікс задовольняє регулярку `STYLE_EXT_RE` (`.css` / `.scss` / `.vue` в кінці рядка). Порядок збережено.
44
-
45
- **Side effects.**
46
-
47
- - Немає. Функція чиста: не змінює вхідний масив, не звертається до файлової системи, не пише в stdout/stderr, не залежить від процесового стану. Імпорт `node:child_process` тут не задіяний.
48
-
49
- **Поведінкові деталі.**
50
-
51
- - Якщо `files` — порожній масив, повертається порожній масив.
52
- - Якщо в `files` немає жодного стильового файлу, повертається порожній масив.
53
- - Файли з розширеннями `.CSS`, `.Vue` тощо (з великими літерами) **не** будуть включені, бо регулярка не має прапора `i`.
54
- - Регулярка прив'язана до кінця рядка (`$`), тому шляхи на кшталт `foo.css.bak` не пройдуть.
55
- - Прапор `u` (Unicode) у регулярці дозволяє коректно обробляти шляхи з Unicode-символами.
56
-
57
- ### `lint(files, cwd = process.cwd())`
58
-
59
- **Сигнатура.**
60
-
61
- ```js
62
- export function lint(
63
- files: string[] | undefined,
64
- cwd?: string
65
- ): Promise<number>
66
- ```
67
-
68
- **Параметри.**
69
-
70
- - `files` — або масив шляхів (тоді функція працює в режимі «quick»: фільтрує його через `filterStyleFiles` і запускає `stylelint` тільки по відфільтрованих файлах), або `undefined` (режим «ci»: запускає `stylelint` по glob-патерну `**/*.{css,scss,vue}` від кореня `cwd`).
71
- - `cwd` — корінь, у якому запускатиметься `npx`. За замовчуванням — поточна робоча директорія процесу (`process.cwd()`).
72
-
73
- **Повертає.**
74
-
75
- - `Promise<number>` — обіцянка з exit-кодом:
76
- - `0` — якщо `files` — масив, але після фільтрації не лишилось жодного стильового файлу (швидкий вихід без запуску `stylelint`).
77
- - Числовий exit-код процесу `npx stylelint ...`, отриманий з поля `r.status` синхронного результату `spawnSync`.
78
- - `1` — якщо `r.status` не є числом (наприклад, процес був завершений сигналом, не зміг запуститися або інша «нештатна» ситуація).
79
- - Хоча всередині немає `async` й `await`, повертається явно `Promise.resolve(...)`, тож сигнатура асинхронна і викликати функцію можна через `await`.
80
-
81
- **Side effects.**
82
-
83
- - Запускає **зовнішній процес** `npx stylelint --fix ...` через `spawnSync` з `stdio: 'inherit'`. Це означає:
84
- - `stdout`, `stderr`, `stdin` дочірнього процесу наслідуються від батьківського — весь вивід `stylelint` йде безпосередньо в консоль користувача (або в логи CI).
85
- - Функція **блокує** event-loop поточного процесу до завершення `stylelint` (попри асинхронний інтерфейс).
86
- - `stylelint --fix` **модифікує файли на диску** там, де він здатен автоматично виправити порушення стилю.
87
- - Запис у файлову систему здійснюється самим `stylelint`, а не цим модулем напряму.
88
- - Модуль не намагається інсталювати `stylelint` — він повинен бути доступний через `npx` (зазвичай через `package.json` залежність, локальний `node_modules/.bin` або глобально).
89
-
90
- **Поведінкові деталі.**
91
-
92
- - Аргументи `npx` будуються в масив `args`: завжди починається з `['stylelint', '--fix']`, далі або додається один елемент-glob `**/*.{css,scss,vue}`, або розпаковується список відфільтрованих файлів через spread.
93
- - Glob-патерн `**/*.{css,scss,vue}` передається без екранування — його **розкриває сам `stylelint`** (а не shell), оскільки `spawnSync` викликається без `shell: true`. Тобто це не shell-glob, а аргумент, який `stylelint` парсить як glob-патерн.
94
- - У режимі «quick» з порожнім результатом фільтрації функція не викликає `npx` взагалі — це оптимізація для випадків, коли в наборі змінених файлів немає жодного стильового файлу (типово для PR, що зачіпає тільки JS/TS-код).
95
-
96
- ## Залежності
97
-
98
- ### Зовнішні npm-пакети
99
-
100
- Прямих імпортів з npm немає.
101
-
102
- ### Node.js вбудовані модулі
103
-
104
- - `node:child_process` — імпорт `{ spawnSync }`. Використовується для синхронного запуску `npx stylelint ...`.
105
-
106
- ### Зовнішні бінарники / системні залежності
107
-
108
- - `npx` — має бути в `PATH`. Це стандартний компаньйон `npm` / `bun` / `pnpm`.
109
- - `stylelint` — має бути запускний через `npx` (через локальний `node_modules` або глобально). Конкретна версія й конфіг (`.stylelintrc*`) знаходяться поза межами цього модуля й керуються рівнем монорепо.
110
-
111
- ### Внутрішні модульні зв'язки
112
-
113
- Сам файл нічого не імпортує з інших файлів проєкту. Натомість його імпортують:
114
-
115
- - сусідній `tooling.mjs` (оркестратор правила `style-lint`),
116
- - та/або тести в підтеці `tests/`.
117
-
118
- ## Потік виконання / Використання
119
-
120
- ### Типовий сценарій 1: quick-режим (локальний розробник)
121
-
122
- ```js
123
- import { lint } from './lint.mjs'
124
-
125
- const changed = ['src/components/Button.vue', 'src/utils/dom.ts', 'src/styles/main.scss']
126
-
127
- const code = await lint(changed)
128
- process.exit(code)
129
- ```
130
-
131
- Що відбудеться:
132
-
133
- 1. `filterStyleFiles(changed)` поверне `['src/components/Button.vue', 'src/styles/main.scss']`.
134
- 2. Сформується команда `npx stylelint --fix src/components/Button.vue src/styles/main.scss`.
135
- 3. `spawnSync` запустить `npx`, `stylelint` обробить тільки ці два файли, виправить що зможе, лог піде в консоль.
136
- 4. Функція поверне promise з exit-кодом `stylelint` (`0` — все добре; ненульовий — лишилися невиправні порушення або помилка конфігу).
137
-
138
- ### Типовий сценарій 2: ci-режим (повний прогін)
139
-
140
- ```js
141
- import { lint } from './lint.mjs'
142
-
143
- const code = await lint(undefined, process.cwd())
144
- process.exit(code)
145
- ```
146
-
147
- Що відбудеться:
148
-
149
- 1. `files === undefined`, тому в `args` додається літерал `**/*.{css,scss,vue}`.
150
- 2. Сформується команда `npx stylelint --fix '**/*.{css,scss,vue}'` (без shell-escaping — це аргумент).
151
- 3. `stylelint` сам розкриває glob від `cwd` і обходить весь проєкт.
152
- 4. Функція повертає його exit-код.
153
-
154
- ### Сценарій 3: quick-режим без жодного стильового файлу
155
-
156
- ```js
157
- const code = await lint(['README.md', 'src/index.ts'])
158
- // code === 0, npx навіть не запускався
159
- ```
160
-
161
- Що відбудеться:
162
-
163
- 1. `filterStyleFiles` поверне `[]`.
164
- 2. Гілка `if (style.length === 0) return Promise.resolve(0)` поверне `0` миттєво.
165
- 3. Жодного дочірнього процесу не створюється — це швидкий «no-op».
12
+ filterStyleFiles
13
+ Вибирає файли, що мають розширення .css, .scss або .vue.
166
14
 
167
- ### Як вписується в загальну архітектуру
15
+ lint
16
+ Запускає команду stylelint з опцією --fix для перевірки та виправлення стилів.
168
17
 
169
- Цей файл — реалізаційна одиниця «quick» кроку правила `style-lint`. Правило в монорепо має дві площини запуску:
18
+ ## Поведінка
170
19
 
171
- - **quick** (швидкий) — викликається після зміни файлів локально, працює тільки по зміненому списку для мінімального часу відгуку.
172
- - **ci** викликається в неперервній інтеграції, проганяє по всьому glob-у щоб гарантовано перевірити весь репозиторій.
20
+ filterStyleFiles
21
+ фільтрує список файлів, повертаючи лише ті, що закінчуються на .css, .scss або .vue
173
22
 
174
- Файл `lint.mjs` уніфікує обидва режими в одній функції, де перемикач режиму — це `files === undefined` (ci) vs `files: string[]` (quick).
23
+ lint
24
+ запускає команду stylelint з опцією --fix для перевірки та виправлення стилів
175
25
 
176
- ### Контракти й гарантії
26
+ ## Публічний API
177
27
 
178
- - Функція `lint` **синхронно** виконує дочірній процес, але повертає `Promise<number>` — це навмисно, щоб уніфікувати інтерфейс з іншими «крок-функціями» в системі правил, які можуть бути по-справжньому асинхронні. Caller завжди робить `await lint(...)`.
179
- - `lint` не кидає виключень: будь-який збій `npx` (включаючи відсутній бінарник) перетвориться в exit-код `1` через гілку `typeof r.status === 'number' ? r.status : 1`. Це робить функцію передбачуваною для оркестратора, який оперує тільки числовими кодами.
180
- - `filterStyleFiles` — стабільна чиста функція, придатна для незалежного юніт-тестування (саме тому винесена як окремий експорт).
28
+ filterStyleFiles відбирає файли за стилем
181
29
 
182
- ## Rebuild Test
30
+ ## Гарантії поведінки
183
31
 
184
- Документація відповідає коду версії на момент написання: 35 рядків, два експорти (`filterStyleFiles`, `lint`), одна приватна регулярка (`STYLE_EXT_RE`), одна імпортована функція з `node:child_process` (`spawnSync`). Якщо файл буде переписано (наприклад, додасться третій експорт, зміниться сигнатура `lint`, з'явиться нова гілка для `--config`, або `spawnSync` буде замінено на асинхронний `spawn`), цей документ потребує перегенерації.
32
+ - Read-only: файл не виконує операцій запису у файлову систему.
33
+ - Не звертається до мережі.
@@ -1,194 +1,29 @@
1
- # tooling.mjs
2
-
3
- ## Огляд
4
-
5
- Модуль `tooling.mjs` реалізує **JS-частину перевірки правила `style-lint.mdc`** — тобто тих аспектів CSS/SCSS-лінтингу через `stylelint`, які **не вкриваються** Rego-політиками (`npx @nitra/cursor check`) і які потребують **файлової системи / cross-file** знання.
6
-
7
- Конкретно перевіряє:
8
-
9
- 1. Наявність **конфігу stylelint** — або як поле `stylelint` у `package.json`, або як зовнішній файл (`.stylelintrc.json`, `.stylelintrc.js`, `stylelint.config.js`). Ця перевірка cross-file: треба порівняти, чи поле є, і якщо нема — чи є зовнішній файл.
10
- 2. Наявність файлу `.stylelintignore` у корені репозиторію.
11
- 3. Наявність workflow-файлу `.github/workflows/lint-style.yml` (структуру окремо валідовує rego-пакет `style_lint.lint_style_yml`).
12
-
13
- Що **вже** покрила Rego (тому тут НЕ повторюється):
14
-
15
- - `npm/policy/style_lint/package_json/` — наявність скрипта `lint-style` через `npx stylelint`, `@nitra/stylelint-config` у `devDependencies`, поле `stylelint.extends`.
16
- - `npm/policy/style_lint/lint_style_yml/` — рядок `npx stylelint` у `run` workflow-файлу.
17
- - `npm/policy/style_lint/vscode_extensions/` — `stylelint.vscode-stylelint` у `recommendations` файлу `.vscode/extensions.json`.
18
- - `npm/policy/style_lint/vscode_settings/` — `css.validate`/`scss.validate`/`less.validate: false` у `.vscode/settings.json`.
19
-
20
- JS-копії перевірок VS Code було **видалено**, щоб не було двох джерел істини — все, що може Rego, лишається тільки у Rego.
21
-
22
- ## Експорти / API
23
-
24
- | Експорт | Тип | Призначення |
25
- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
26
- | `check` | `async function (cwd?: string) => Promise<number>` | Основна точка входу: запускає всі перевірки конфігурації stylelint у заданому корені репозиторію та повертає exit-код (0 — OK, 1 — є проблеми). |
27
-
28
- Внутрішня (НЕ експортується) функція:
29
-
30
- | Функція | Призначення |
31
- | --------------------------------------------- | -------------------------------------------------------------------------------------- |
32
- | `checkStylelintConfigPresence(reporter, cwd)` | Перевіряє наявність конфігурації stylelint (поле в `package.json` або зовнішній файл). |
33
-
34
- ## Функції
35
-
36
- ### `check(cwd?)`
37
-
38
- **Сигнатура:**
39
-
40
- ```js
41
- export async function check(cwd = process.cwd()): Promise<number>
42
- ```
43
-
44
- **Параметри:**
45
-
46
- - `cwd` (`string`, опціональний) — абсолютний шлях до кореня репозиторію, який треба перевірити. За замовчуванням використовується `process.cwd()` (поточна робоча директорія процесу).
47
-
48
- **Повертає:**
49
-
50
- - `Promise<number>` — exit-код процесу:
51
- - `0` — усі перевірки пройдено (відсутні `fail`-події у репортера);
52
- - `1` — хоч одна перевірка зафейлилась.
53
-
54
- Конкретне значення береться з виклику `reporter.getExitCode()`, який інкапсульований у `createCheckReporter()`.
55
-
56
- **Що робить:**
57
-
58
- 1. Створює репортер через `createCheckReporter()` — він збирає події `pass`/`fail` і виводить їх у консоль під час виконання.
59
- 2. Викликає `checkStylelintConfigPresence(reporter, cwd)` — перевірка №1 (конфіг stylelint).
60
- 3. Перевіряє наявність файлу `.stylelintignore` у корені:
61
- - якщо є — звітує `pass('.stylelintignore існує')`;
62
- - якщо нема — `fail('.stylelintignore не існує — створи з вмістом: dist/')`.
63
- 4. Перевіряє наявність workflow-файлу `.github/workflows/lint-style.yml`:
64
- - якщо є — `pass` із зауваженням, що структуру файлу валідовує `npx @nitra/cursor fix → style_lint.lint_style_yml`;
65
- - якщо нема — `fail` із вимогою його створити.
66
- 5. Повертає `reporter.getExitCode()`.
67
-
68
- **Side effects:**
69
-
70
- - Виконує **синхронні** виклики `existsSync` (читає файлову систему).
71
- - Через репортер пише у консоль (stdout/stderr) повідомлення `pass`/`fail` (поведінка інкапсульована у `check-reporter.mjs`).
72
- - Не змінює файли. Не виконує мережевих запитів. Не змінює стану процесу (не викликає `process.exit`) — повертає exit-код, а викликаюча сторона сама вирішує, як його використати.
73
-
1
+ ---
2
+ docgen:
3
+ source: npm/rules/style-lint/js/tooling.mjs
4
+ crc: 631f5de8
5
+ score: 80
74
6
  ---
75
7
 
76
- ### `checkStylelintConfigPresence(reporter, cwd)` _(внутрішня)_
77
-
78
- **Сигнатура:**
79
-
80
- ```js
81
- async function checkStylelintConfigPresence(
82
- reporter: CheckReporter,
83
- cwd: string,
84
- ): Promise<void>
85
- ```
86
-
87
- **Параметри:**
88
-
89
- - `reporter` (`CheckReporter`) — об'єкт-репортер, створений `createCheckReporter()`, з полями `{ pass, fail, getExitCode }`. У функції використовуються лише `pass` і `fail`.
90
- - `cwd` (`string`) — корінь репозиторію.
91
-
92
- **Повертає:**
93
-
94
- - `Promise<void>` — нічого не повертає; результат виражається через виклики `reporter.pass(...)` / `reporter.fail(...)`.
95
-
96
- **Логіка:**
97
-
98
- 1. Будує шлях до `package.json` через `join(cwd, 'package.json')`.
99
- 2. Якщо `package.json` **немає** — мовчки повертається з функції (`return`). Це означає: для тек без `package.json` перевірка пропускається (вона нерелевантна).
100
- 3. Читає `package.json` через `readFile(pkgPath, 'utf8')` і парсить як JSON.
101
- 4. Перевіряє `hasField` — `pkg.stylelint && typeof pkg.stylelint === 'object'` (саме поле-об'єкт; формат `extends: "@nitra/stylelint-config"` валідовує Rego).
102
- 5. Перевіряє `hasExternalCfg` — наявність хоча б одного з файлів:
103
- - `.stylelintrc.json`
104
- - `.stylelintrc.js`
105
- - `stylelint.config.js`
106
- 6. Якщо `hasField || hasExternalCfg` — `pass('Конфіг stylelint є — у package.json або окремим файлом')`.
107
- 7. Інакше — `fail('Немає конфігу stylelint — додай "stylelint": { "extends": "@nitra/stylelint-config" } до package.json')`.
108
-
109
- **Side effects:**
110
-
111
- - Синхронно: `existsSync` для `package.json` та для трьох можливих зовнішніх конфіг-файлів.
112
- - Асинхронно: `readFile` для `package.json`.
113
- - Через репортер пише до консолі результат.
114
- - Може кинути виняток, якщо `package.json` існує, але містить невалідний JSON (`JSON.parse` кине `SyntaxError`) — функція **не** обробляє цю помилку.
115
-
116
- **Зауваження щодо файлів-конфігів:**
117
-
118
- Список перевірюваних зовнішніх конфігів **не** охоплює всі можливі формати, які підтримує stylelint (наприклад, `.stylelintrc`, `.stylelintrc.yaml`, `.stylelintrc.yml`, `.stylelintrc.cjs`). Перевіряються лише три найпопулярніші: `.stylelintrc.json`, `.stylelintrc.js`, `stylelint.config.js`.
119
-
120
- ## Залежності
121
-
122
- ### Імпорти із Node.js
123
-
124
- | Модуль | Що використовується |
125
- | ------------------ | --------------------------------------------------- |
126
- | `node:fs` | `existsSync` — синхронна перевірка існування файлу. |
127
- | `node:fs/promises` | `readFile` — асинхронне читання файлу як рядка. |
128
- | `node:path` | `join` — крос-платформне склеювання шляхів. |
129
-
130
- ### Внутрішні імпорти
131
-
132
- | Шлях | Що дає |
133
- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
134
- | `../../../scripts/lib/check-reporter.mjs` | `createCheckReporter()` — фабрика репортера, який має методи `pass(msg)`, `fail(msg)` та `getExitCode()`. Тип `CheckReporter` тягнеться JSDoc-посиланням `import('../../../scripts/lib/check-reporter.mjs').CheckReporter`. |
135
-
136
- ### Зв'язані артефакти (НЕ імпортуються, але важливі контекстно)
137
-
138
- - `npm/rules/style-lint/style-lint.mdc` — людино-зрозуміле формулювання правила.
139
- - `npm/policy/style_lint/package_json/` — Rego-пакет, що покриває валідацію формату полів `package.json`.
140
- - `npm/policy/style_lint/lint_style_yml/` — Rego-пакет, що валідовує вміст workflow-файлу.
141
- - `npm/policy/style_lint/vscode_extensions/` — Rego для `.vscode/extensions.json`.
142
- - `npm/policy/style_lint/vscode_settings/` — Rego для `.vscode/settings.json`.
143
-
144
- ## Потік виконання / Використання
145
-
146
- ### Контекст виклику
147
-
148
- Модуль є частиною ланцюжка перевірок правил `@nitra/cursor`. Експортована функція `check` викликається диспетчером перевірок (зазвичай через CLI `npx @nitra/cursor check`), який ітерує rule-теки і для кожної шукає файл `js/tooling.mjs` з експортованим `check`.
149
-
150
- ### Послідовність дій усередині `check`
151
-
152
- 1. **Створення репортера:**
153
- ```js
154
- const reporter = createCheckReporter()
155
- const { pass, fail } = reporter
156
- ```
157
- (`pass`/`fail` деструктуруються, але в `check` напряму не використовуються — лише як алії; всередині `checkStylelintConfigPresence` вони беруться зі свого деструктурування.)
158
- 2. **Перевірка конфігу stylelint** — `await checkStylelintConfigPresence(reporter, cwd)`.
159
- 3. **Перевірка `.stylelintignore`** — `existsSync(join(cwd, '.stylelintignore'))`.
160
- 4. **Перевірка workflow `lint-style.yml`** — `existsSync(join(cwd, '.github/workflows/lint-style.yml'))`.
161
- 5. **Повернення exit-коду** — `return reporter.getExitCode()`.
162
-
163
- ### Приклад використання
164
-
165
- ```js
166
- import { check } from '@nitra/cursor/rules/style-lint/js/tooling.mjs'
167
-
168
- const exitCode = await check(process.cwd())
169
- process.exit(exitCode)
170
- ```
8
+ # tooling.mjs
171
9
 
172
- Або через CLI-обгортку:
10
+ ## Огляд
173
11
 
174
- ```bash
175
- npx @nitra/cursor check
176
- ```
12
+ Файл виконує перевірку конфігурації stylelint та файлів, пов'язаних з лінтуванням. Перевірка включає наявність конфігурації stylelint у `package.json` або зовнішньому файлі, файлів конфігу stylelint у директорії, файлів ігнорування stylelint та файлу workflow для лінтування.
177
13
 
178
- (CLI сам знайде цей модуль за конвенцією `npm/rules/<rule>/js/tooling.mjs` і викличе `check()` без аргументів, тож буде використано `process.cwd()`.)
14
+ ## Поведінка
179
15
 
180
- ### Гарантії та межі відповідальності
16
+ 1. Перевірити наявність конфігурації stylelint у package.json або зовнішньому файлі
17
+ 2. Перевірити наявність файлів конфігу stylelint у директорії
18
+ 3. Перевірити наявність файлів ігнорування stylelint
19
+ 4. Перевірити наявність файлу workflow для лінтування
181
20
 
182
- - Модуль **не змінює** файли (немає `fix`-режиму) — він тільки **репортує**.
183
- - Він **не дублює** перевірок, які вже робить Rego. Розділення: FS / cross-file → JS (тут); формат / структура одного файлу → Rego.
184
- - Виклик `check` із `cwd`, де немає `package.json`, — валідний сценарій: перевірка конфігу stylelint буде пропущена (мовчки), решта перевірок (`.stylelintignore`, workflow) — виконається.
185
- - Якщо `package.json` містить невалідний JSON — функція впаде з `SyntaxError` (це не пере́хоплюється навмисно: гнилий JSON — це самостійна проблема, яку треба чути одразу).
21
+ ## Публічний API
186
22
 
187
- ## Rebuild Test
23
+ check Перевіряє відповідність проєкту правилам style-lint.mdc
188
24
 
189
- З цього документа можна повністю відновити поведінку файлу:
25
+ ## Гарантії поведінки
190
26
 
191
- - Знаючи список перевірок (конфіг stylelint, `.stylelintignore`, `lint-style.yml`), повідомлення `pass`/`fail` і допустимі імена файлів-конфігів реалізація відтворюється 1:1.
192
- - Деталі контракту функцій (типи параметрів, тип повернення, side effects, поведінка за відсутності `package.json`) описані явно.
193
- - Експорти та їх кількість (єдиний експорт `check`) зафіксовано.
194
- - Імпорти Node-модулів і внутрішні залежності перераховано вичерпно.
27
+ - Read-only: файл не виконує операцій запису у файлову систему.
28
+ - Свідомо пропускає шляхи: `.github`, `.git`.
29
+ - Не звертається до мережі.