@nitra/cursor 5.3.3 → 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 (157) 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 +17 -0
  4. package/bin/n-cursor.js +43 -22
  5. package/lib/docs/llm.md +23 -12
  6. package/lib/docs/models.md +29 -18
  7. package/lib/docs/omlx-trace.md +51 -0
  8. package/lib/docs/omlx.md +31 -15
  9. package/lib/omlx.mjs +2 -5
  10. package/package.json +1 -1
  11. package/rules/abie/docs/fix.md +17 -11
  12. package/rules/adr/docs/fix.md +25 -140
  13. package/rules/bun/docs/fix.md +18 -151
  14. package/rules/capacitor/docs/fix.md +16 -13
  15. package/rules/capacitor/js/docs/platforms.md +31 -43
  16. package/rules/changelog/docs/fix.md +25 -169
  17. package/rules/ci4/docs/fix.md +11 -14
  18. package/rules/doc-files/doc-files.mdc +60 -0
  19. package/rules/doc-files/docs/fix.md +31 -0
  20. package/rules/doc-files/fix.mjs +19 -0
  21. package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
  22. package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
  23. package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
  24. package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
  25. package/rules/doc-files/js/docs/docgen-extract-anchors.md +45 -0
  26. package/rules/doc-files/js/docs/docgen-extract.md +39 -0
  27. package/rules/doc-files/js/docs/docgen-files-batch.md +35 -0
  28. package/rules/doc-files/js/docs/docgen-gen.md +46 -0
  29. package/rules/doc-files/js/docs/docgen-ignore.md +37 -0
  30. package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
  31. package/rules/doc-files/js/docs/docgen-scan.md +54 -0
  32. package/rules/doc-files/js/docs/lint.md +36 -0
  33. package/rules/doc-files/js/docs/units-js.md +31 -0
  34. package/rules/doc-files/js/docs/units-rs.md +35 -0
  35. package/rules/doc-files/js/docs/units.md +30 -0
  36. package/rules/doc-files/js/lint.mjs +96 -0
  37. package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
  38. package/rules/doc-files/lint/docs/lint.md +37 -0
  39. package/rules/doc-files/lint/lint.mjs +105 -0
  40. package/rules/doc-files/meta.json +1 -0
  41. package/rules/docker/docs/fix.md +21 -161
  42. package/rules/efes/docs/fix.md +23 -194
  43. package/rules/feedback/docs/fix.md +10 -8
  44. package/rules/ga/docs/fix.md +10 -5
  45. package/rules/graphql/docs/fix.md +23 -119
  46. package/rules/hasura/docs/fix.md +19 -5
  47. package/rules/hasura/js/docs/internal_urls.md +34 -307
  48. package/rules/image-avif/docs/fix.md +16 -127
  49. package/rules/image-compress/docs/fix.md +20 -141
  50. package/rules/image-compress/js/docs/package_setup.md +22 -182
  51. package/rules/js-bun-db/docs/fix.md +23 -139
  52. package/rules/js-bun-db/js/docs/safety.md +33 -221
  53. package/rules/js-bun-redis/docs/fix.md +25 -114
  54. package/rules/js-bun-redis/js/docs/imports.md +18 -166
  55. package/rules/js-lint/docs/fix.md +30 -108
  56. package/rules/js-lint/js/docs/lint-findings.md +37 -17
  57. package/rules/js-lint/js/docs/lint.md +22 -238
  58. package/rules/js-lint/js/docs/tooling.md +34 -331
  59. package/rules/js-lint-ci/docs/fix.md +16 -149
  60. package/rules/js-lint-ci/js/docs/lint.md +16 -136
  61. package/rules/js-mssql/docs/fix.md +18 -123
  62. package/rules/js-mssql/js/docs/deps.md +28 -251
  63. package/rules/js-run/docs/fix.md +23 -138
  64. package/rules/js-run/js/docs/runtime.md +24 -378
  65. package/rules/k8s/docs/fix.md +18 -123
  66. package/rules/nginx-default-tpl/docs/fix.md +22 -118
  67. package/rules/nginx-default-tpl/js/docs/template.md +38 -360
  68. package/rules/npm-module/docs/fix.md +27 -89
  69. package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
  70. package/rules/npm-module/js/docs/package_structure.md +36 -258
  71. package/rules/npm-module/js/docs/rule_meta.md +25 -127
  72. package/rules/npm-module/js/docs/skill_meta.md +18 -180
  73. package/rules/php/docs/fix.md +21 -98
  74. package/rules/php/js/docs/tooling.md +20 -143
  75. package/rules/python/docs/fix.md +25 -157
  76. package/rules/python/js/docs/applies.md +20 -98
  77. package/rules/python/js/docs/tooling.md +27 -144
  78. package/rules/rego/docs/fix.md +24 -112
  79. package/rules/rego/js/docs/applies.md +20 -164
  80. package/rules/rego/js/docs/lint.md +15 -110
  81. package/rules/release/docs/fix.md +16 -114
  82. package/rules/rust/docs/fix.md +24 -119
  83. package/rules/rust/js/docs/applies.md +20 -129
  84. package/rules/security/docs/fix.md +21 -78
  85. package/rules/security/js/docs/sample_secret.md +23 -182
  86. package/rules/security/js/docs/trufflehog.md +19 -128
  87. package/rules/style-lint/docs/fix.md +16 -150
  88. package/rules/style-lint/js/docs/lint.md +21 -172
  89. package/rules/style-lint/js/docs/tooling.md +19 -184
  90. package/rules/tauri/docs/fix.md +26 -152
  91. package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
  92. package/rules/tauri/js/docs/tooling.md +20 -217
  93. package/rules/test/docs/fix.md +19 -127
  94. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
  95. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
  96. package/rules/test/js/docs/cargo_mutants_config.md +24 -164
  97. package/rules/test/js/docs/location.md +24 -126
  98. package/rules/test/js/docs/no-process-chdir.md +20 -151
  99. package/rules/test/js/docs/no-relative-fs-path.md +24 -261
  100. package/rules/test/js/docs/stryker_config.md +48 -148
  101. package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
  102. package/rules/text/docs/fix.md +25 -113
  103. package/rules/text/js/docs/forbidden-prettier.md +21 -132
  104. package/rules/text/js/docs/formatting.md +60 -251
  105. package/rules/text/js/docs/lint.md +17 -114
  106. package/rules/vue/docs/fix.md +25 -118
  107. package/rules/vue/js/docs/packages.md +25 -323
  108. package/rules/worktree/docs/fix.md +31 -150
  109. package/scripts/coverage-classify/docs/index.md +23 -209
  110. package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
  111. package/scripts/dispatcher/docs/trace.md +35 -0
  112. package/scripts/docs/auto-rules.md +37 -361
  113. package/scripts/docs/lint-cli.md +12 -13
  114. package/scripts/docs/post-tool-use-fix.md +16 -15
  115. package/scripts/docs/skills-cli.md +26 -23
  116. package/scripts/docs/sync-claude-config.md +94 -34
  117. package/scripts/docs/worktree-cli.md +11 -34
  118. package/scripts/lib/docs/assert-project-root.md +14 -16
  119. package/scripts/lib/docs/changed-files.md +24 -139
  120. package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
  121. package/scripts/lib/docs/rule-predicates.md +20 -17
  122. package/scripts/lib/docs/run-rule-cli.md +14 -18
  123. package/scripts/lib/docs/run-rule.md +13 -20
  124. package/scripts/lib/docs/run-standard-rule.md +12 -15
  125. package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
  126. package/scripts/lib/rule-predicates.mjs +1 -1
  127. package/scripts/sync-claude-config.mjs +4 -1
  128. package/scripts/utils/docs/with-lock.md +19 -12
  129. package/scripts/utils/with-lock.mjs +4 -2
  130. package/skills/doc-aggregate/SKILL.md +2 -2
  131. package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
  132. package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
  133. package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
  134. package/skills/doc-files/.changes/260612-0012.md +5 -0
  135. package/skills/doc-files/.changes/260612-0031.md +5 -0
  136. package/skills/doc-files/.changes/260612-0036.md +5 -0
  137. package/skills/doc-files/.changes/260612-0114.md +5 -0
  138. package/skills/doc-files/SKILL.md +6 -6
  139. package/skills/fix/js/docs/llm-worker.md +17 -15
  140. package/skills/fix/js/docs/orchestrator.md +30 -23
  141. package/skills/fix/js/docs/t0.md +26 -16
  142. package/skills/start-check/js/docs/check.md +26 -22
  143. package/skills/taze/js/docs/diff.md +44 -20
  144. package/skills/doc-files/js/docs/docgen-extract-anchors.md +0 -27
  145. package/skills/doc-files/js/docs/docgen-extract.md +0 -29
  146. package/skills/doc-files/js/docs/docgen-files-batch.md +0 -25
  147. package/skills/doc-files/js/docs/docgen-gen.md +0 -30
  148. package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
  149. package/skills/doc-files/js/docs/docgen-scan.md +0 -25
  150. package/skills/doc-files/js/docs/units-rs.md +0 -35
  151. /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
  152. /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
  153. /package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +0 -0
  154. /package/{skills → rules}/doc-files/js/docgen-gen.mjs +0 -0
  155. /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
  156. /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
  157. /package/{skills → rules}/doc-files/js/units.mjs +0 -0
@@ -1,143 +1,32 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/text/js/forbidden-prettier.mjs
4
+ crc: a5dae608
5
+ score: 100
6
+ ---
7
+
1
8
  # forbidden-prettier.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль `forbidden-prettier.mjs` — це FS-перевірка (suspect FS-check) з категорії правил `text`, яка стежить за тим, щоб у корені проєкту не з'являвся жоден файл, який Prettier автоматично підхоплює як конфігурацію чи ignore-список.
6
-
7
- Правило `text.mdc` (див. однойменну категорію `.cursor/rules/`) повністю забороняє використання Prettier, пакета `@nitra/prettier-config` і будь-яких прив'язок до Prettier у проєкті — заміна Prettier у репозиторії — це форматер `oxfmt`. Перевірка package.json-сторони (поля `scripts`, `dependencies`, `devDependencies`) виконується Rego-полісі `text.package_json`, а ця перевірка доповнює її і ловить саме FS-сторону: фізично присутні у корені файли конфігів і `.prettierignore`, які runner Prettier зчитує автоматично.
8
-
9
- Список заборонених імен синхронізовано з документацією Prettier 3.x (https://prettier.io/docs/configuration). Якщо Prettier додасть новий формат конфігу — у константу треба додати відповідний рядок.
10
-
11
- Файл є ES-модулем (`.mjs`). Експортує єдину функцію `check`, яка повертає exit code (0 — успіх, 1 — провал), що дозволяє запустити її з CLI або іншого скрипта-агрегатора перевірок.
12
-
13
- ## Експорти / API
14
-
15
- | Експорт | Тип | Призначення |
16
- | ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------- |
17
- | `check(cwd?)` | `function(string=): number` | Іменований експорт. Запускає перевірку відсутності Prettier-артефактів у вказаному корені й повертає exit code. |
18
-
19
- Інших публічних експортів модуль не має. Константа `FORBIDDEN_PRETTIER_FILES` оголошена локально у модулі і назовні не експортується.
20
-
21
- ## Функції
22
-
23
- ### `check(cwd = process.cwd())`
24
-
25
- Сигнатура:
26
-
27
- ```js
28
- export function check(cwd = process.cwd()): number
29
- ```
30
-
31
- Параметри:
32
-
33
- - `cwd` — `string`, опційний. Абсолютний шлях до кореня репозиторію (або іншої теки), в якому потрібно шукати Prettier-артефакти. Якщо не передано, використовується поточна робоча тека процесу (`process.cwd()`).
34
-
35
- Повертає:
36
-
37
- - `number` — exit code, отриманий від `reporter.getExitCode()`. За контрактом `createCheckReporter`:
38
- - `0` — у корені не знайдено жодного забороненого Prettier-файлу;
39
- - `1` — знайдено хоча б один заборонений файл; кожен факт повідомлено окремим `fail(...)`-рядком.
40
-
41
- Side effects:
42
-
43
- - Виводить повідомлення про статус перевірки через репортер (`pass` / `fail`). Конкретний канал виводу й формат рядків визначає реалізація `createCheckReporter()` (як правило — `stdout`/`stderr` з префіксами).
44
- - Звертається до файлової системи: для кожного імені зі списку викликає `existsSync(join(cwd, file))`. Жодних читань вмісту файлів, жодних записів чи видалень не виконується — перевірка лише на факт існування шляху.
45
- - Не змінює змінні оточення, не модифікує `process` (крім читання `process.cwd()` як дефолтного значення параметра).
46
-
47
- Алгоритм:
48
-
49
- 1. Створити репортер через `createCheckReporter()`; з нього взяти методи `pass` і `fail`.
50
- 2. Ініціалізувати локальний прапорець `anyFound = false`.
51
- 3. Для кожного імені `file` зі списку `FORBIDDEN_PRETTIER_FILES`:
52
- - обчислити повний шлях `join(cwd, file)`;
53
- - якщо `existsSync(...)` повертає `true` — викликати `fail` з повідомленням виду `"<file> заборонено — Prettier не використовуємо, перейди на oxfmt (text.mdc)"` і виставити `anyFound = true`. Цикл не переривається — перевіряємо всі імена, щоб репорт містив повний список знайдених порушень за один прогін.
54
- 4. Якщо після циклу `anyFound === false` — викликати `pass('Prettier-конфігів і .prettierignore немає в корені')` (єдиний підсумковий success-рядок).
55
- 5. Повернути `reporter.getExitCode()`.
56
-
57
- ## Залежності
58
-
59
- ### Зовнішні (стандартна бібліотека Node.js)
60
-
61
- - `node:fs` — імпортується `existsSync` для синхронної перевірки існування шляху.
62
- - `node:path` — імпортується `join` для безпечного склеювання `cwd` з іменем файлу (працює коректно на всіх ОС).
63
-
64
- ### Внутрішні
65
-
66
- - `../../../scripts/lib/check-reporter.mjs` — модуль із фабрикою `createCheckReporter()`. Фабрика повертає об'єкт із принаймні полями:
67
- - `pass(message: string): void` — повідомити про успіх;
68
- - `fail(message: string): void` — повідомити про порушення;
69
- - `getExitCode(): number` — підсумковий exit code (зазвичай 0 при відсутності `fail` і 1 — якщо `fail` був хоча б раз).
70
-
71
- Контракт репортера спільний для всіх FS-перевірок у `npm/rules/`, тож формат повідомлень уніфіковано.
72
-
73
- ### Дотичні правила
74
-
75
- - `text.mdc` (`.cursor/rules/n-text.mdc` у проєкті) — джерело заборони Prettier. У повідомленнях `fail` явно посилається користувача на цей файл.
76
- - Rego-полісі `text.package_json` — додаткова перевірка package.json-сторони (доповнює дану FS-перевірку, але не викликається з цього модуля).
77
-
78
- ## Потік виконання / Використання
79
-
80
- Модуль розрахований на виклик із CLI-обгортки чи з агрегатора перевірок, який послідовно проганяє правила з категорії `text`.
81
-
82
- Типовий сценарій використання:
83
-
84
- 1. Скрипт-агрегатор (або CLI на кшталт `n-cursor check` чи окремий runner) імпортує функцію:
85
-
86
- ```js
87
- import { check } from './npm/rules/text/js/forbidden-prettier.mjs'
88
- ```
89
-
90
- 2. Викликає `check()` без аргументів (тоді корінь = `process.cwd()` процесу-агрегатора) або з явним коренем, наприклад при перевірці іншого workspace:
91
-
92
- ```js
93
- const exitCode = check('/abs/path/to/repo/root')
94
- ```
95
-
96
- 3. Отриманий `exitCode` агрегатор підсумовує з іншими перевірками; на CI ненульовий код завалює job.
97
-
98
- Локальний запуск як standalone-скрипта (за бажанням, оскільки модуль не має блоку `if (import.meta.url === ...)`) можна організувати тонкою обгорткою або запустити `check` через `node -e`:
99
-
100
- ```sh
101
- node --input-type=module -e "import('./npm/rules/text/js/forbidden-prettier.mjs').then(m => process.exit(m.check()))"
102
- ```
103
-
104
- Семантика результату:
105
-
106
- - `0` — у корені немає жодного з 18 заборонених імен (різні формати `.prettierrc.*`, `prettier.config.*`, `.prettierignore`). Користувач бачить один success-рядок.
107
- - `1` — знайдено N ≥ 1 файлів. Користувач бачить N окремих fail-рядків (по одному на кожен знайдений артефакт) і нульових success-рядків. Це дозволяє за одним прогоном CI-перевірки одразу побачити повний список того, що треба прибрати.
12
+ Огляд
108
13
 
109
- Чого функція **не** робить (важливо для контексту):
14
+ Файл виконує перевірку наявність заборонених файлів у корені проєкту. Перевірка здійснюється на відповідність конфігураціям, визначеним у файлі `.prettierrc.json`.
110
15
 
111
- - не зчитує вмісту конфігів — лише факт їх присутності;
112
- - не намагається автоматично видаляти знайдені файли (це задача користувача — мігрувати на `oxfmt` і прибрати артефакти);
113
- - не перевіряє вкладені теки/workspaces — рекурсивного обходу немає, контролюється лише корінь `cwd`;
114
- - не реагує на наявність полів `prettier` у `package.json` — це інша зона відповідальності (Rego `text.package_json`).
16
+ ## Поведінка
115
17
 
116
- ## Константи
18
+ 1. Перевірити наявність заборонених файлів у корені проєкту.
19
+ 2. Для кожного файлу з переліку перевірити наявність у корені проєкту.
20
+ 3. Якщо знайдено файл з переліку, повідомити про порушення.
21
+ 4. Повідомити про порушення використання Prettier-конфігів.
22
+ 5. Повідомити про успішне завершення перевірки, якщо заборонені файли відсутні.
23
+ 6. Повертати код виходу для системи.
117
24
 
118
- ### `FORBIDDEN_PRETTIER_FILES`
25
+ ## Публічний API
119
26
 
120
- Локальний `const`-масив рядків повний перелік імен, які Prettier 3.x шукає у корені проєкту. На момент створення модуля містить такі імена (у порядку оригіналу):
27
+ checkперевіряє відсутність Prettier-конфігів чи ignore-файлів у корені проєкту (text.mdc).
121
28
 
122
- - `.prettierignore`
123
- - `.prettierrc`
124
- - `.prettierrc.json`
125
- - `.prettierrc.jsonc`
126
- - `.prettierrc.json5`
127
- - `.prettierrc.yaml`
128
- - `.prettierrc.yml`
129
- - `.prettierrc.toml`
130
- - `.prettierrc.js`
131
- - `.prettierrc.cjs`
132
- - `.prettierrc.mjs`
133
- - `.prettierrc.ts`
134
- - `.prettierrc.cts`
135
- - `.prettierrc.mts`
136
- - `prettier.config.js`
137
- - `prettier.config.cjs`
138
- - `prettier.config.mjs`
139
- - `prettier.config.ts`
140
- - `prettier.config.cts`
141
- - `prettier.config.mts`
29
+ ## Гарантії поведінки
142
30
 
143
- Поясняюча нотатка з коментаря у файлі: «Список синхронізовано з конфіг-форматами Prettier 3.x (https://prettier.io/docs/configuration). Якщо Prettier додасть новий формат — додай рядок.» — підтримка списку ручна; при апгрейді Prettier (як майбутньої версії) перевір документацію і за потреби розшир константу.
31
+ - Read-only: файл не виконує операцій запису у файлову систему.
32
+ - Не звертається до мережі.
@@ -1,256 +1,65 @@
1
- # `formatting.mjs` — перевірка текстового стека й форматування за правилом `text.mdc`
2
-
3
- ## Огляд
4
-
5
- Модуль `formatting.mjs` реалізує **JS-частину** перевірки правила `n-text.mdc` / `npm/mdc/text.mdc` для пакета `@nitra/cursor`. Його роль — **доповнити** Rego-перевірки тими аспектами, які не вдається коректно описати декларативно: наявність файлів на файловій системі, вміст plain-text файлу `.v8rignore`, наявність абзацу про український апостроф у markdown-тексті правила, форма скрипта `lint-text` у `package.json` та виклик `bun run lint-text` у GitHub Actions workflow.
6
-
7
- Модуль експортує функцію `check(cwd)`, яка повертає код виходу процесу (`0` — все ок, `1` — є порушення). Усі повідомлення про успіх/провал агрегує `createCheckReporter()` зі спільної бібліотеки `scripts/lib/check-reporter.mjs`.
8
-
9
- Розподіл відповідальностей JS ↔ Rego (зафіксований у JSDoc-коментарі на початку файлу):
10
-
11
- - **JS (цей файл):**
12
- - `.v8rignore` (текстовий формат, рядки шляхів);
13
- - наявність FS-файлів `.oxfmtrc.json`, `.cspell.json`, `.markdownlint-cli2.jsonc`, `.vscode/extensions.json`, `.vscode/settings.json`, `package.json`;
14
- - абзац про український апостроф у `.cursor/rules/n-text.mdc` / `npm/mdc/text.mdc` (markdown-текст);
15
- - перевірка скрипта `lint-text` у `package.json`;
16
- - наявність кроку `bun run lint-text` у workflow `lint-text.yml`.
17
- - **Rego (`npx @nitra/cursor check`):**
18
- - `npm/policy/text/oxfmtrc/` — обовʼязкові ключі `.oxfmtrc.json` і канонічні значення (`semi`/`singleQuote`/`tabWidth`/`useTabs`/`printWidth`) + канонічні `ignorePatterns`;
19
- - `npm/policy/text/cspell/` — `.cspell.json` (`version "0.2"`, `language`, імпорт `@nitra/cspell-dict`, заборона `@cspell/dict-*`, обовʼязкові `ignorePaths`);
20
- - `npm/policy/text/markdownlint/` — `.markdownlint-cli2.jsonc` (`gitignore: true`, валідний JSON без коментарів);
21
- - `npm/policy/text/package_json/` — заборона Prettier (`prettier` поле + `prettier`/`@nitra/prettier-config` у залежностях), `@nitra/cspell-dict ^2.0.0+` у `devDependencies`, заборона `markdownlint-cli2` у залежностях;
22
- - `npm/policy/bun/package_json/` — у `devDependencies` лише пакети з `@nitra/*`;
23
- - `text.vscode_extensions` / `text.vscode_settings` — вміст `.vscode/extensions.json` та `.vscode/settings.json`.
24
-
25
- ## Експорти / API
26
-
27
- | Назва | Тип | Опис |
28
- | ------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
29
- | `check` | `(cwd?: string) => Promise<number>` | Єдиний публічний експорт. Виконує всі перевірки текстового стека й повертає код виходу: `0` — порушень немає, `1` — є хоча б одне. |
30
-
31
- Решта функцій (`verifyUkApostropheRuleParagraph`, `checkV8rIgnore`, `checkTextConfigsExistence`, `checkPackageJsonText`, `checkLintTextScript`) — внутрішні, не експортуються.
32
-
33
- Також у файлі є модульна константа:
34
-
35
- | Назва | Значення | Призначення |
36
- | ----------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------- |
37
- | `UK_APOSTROPHE_HEADING` | `'**Український апостроф:**'` | Заголовок абзацу про апостроф у `text.mdc` / `n-text.mdc`, по якому ведеться пошук у вмісті правила. |
38
-
39
- ## Функції
40
-
41
- ### `verifyUkApostropheRuleParagraph(filePath, body, failFn, passFn)`
42
-
43
- **Сигнатура:** `(filePath: string, body: string, failFn: (msg: string) => void, passFn: (msg: string) => void) => void`
44
-
45
- **Параметри:**
46
-
47
- - `filePath` — шлях до файлу `.mdc`, використовується лише для повідомлень.
48
- - `body` — вміст `.mdc` у кодуванні UTF-8 (рядок).
49
- - `failFn` — callback, який реєструє порушення (фактично змушує `check()` повернути `1`).
50
- - `passFn` — callback успіху для звіту.
51
-
52
- **Повертає:** `void`. Чистих значень не повертає; вплив — виключно через callback-и.
53
-
54
- **Поведінка:**
55
-
56
- 1. Якщо в тексті немає підрядка `**Український апостроф:**` — `failFn` з підказкою «додай абзац» і одразу `return`.
57
- 2. Якщо немає згадки `U+0027` **або** `U+2019` — `failFn`, `return`.
58
- 3. Якщо у вмісті немає символу `’` (типографська одинарна лапка U+2019) — `failFn`, `return`.
59
- 4. Інакше — `passFn('… абзац про український апостроф на місці')`.
60
-
61
- **Side effects:** виклики `failFn` / `passFn` (запис у звіт `check-reporter`).
62
-
63
1
  ---
64
-
65
- ### `checkV8rIgnore(passFn, failFn, cwd)`
66
-
67
- **Сигнатура:** `async (passFn: (msg: string) => void, failFn: (msg: string) => void, cwd: string) => Promise<void>`
68
-
69
- **Параметри:**
70
-
71
- - `passFn`, `failFn` — callback-и звіту.
72
- - `cwd` — корінь репозиторію.
73
-
74
- **Повертає:** `Promise<void>`.
75
-
76
- **Поведінка:**
77
-
78
- 1. Будує шлях `cwd + '.v8rignore'` через `path.join`.
79
- 2. Якщо файлу немає (`existsSync` → `false`) — `failFn` з підказкою про мінімально потрібний вміст, `return`.
80
- 3. Читає файл `readFile(..., 'utf8')`.
81
- 4. Парсить рядки: розбиває за `\n`, обрізає пробіли (`trim`), відкидає порожні й коментарі (рядки, що починаються з `#`), кладе результат у `Set`.
82
- 5. Для кожного з обовʼязкових шляхів `.vscode/extensions.json`, `.vscode/settings.json` перевіряє наявність у `Set`: знайдено → `passFn`, ні → `failFn` з підказкою додати рядок.
83
-
84
- **Side effects:** читання файлу `.v8rignore` з диска (`fs/promises.readFile`), виклики `failFn` / `passFn`.
85
-
86
- ---
87
-
88
- ### `checkTextConfigsExistence(passFn, failFn, cwd)`
89
-
90
- **Сигнатура:** `(passFn: (msg: string) => void, failFn: (msg: string) => void, cwd: string) => Promise<void>`
91
-
92
- Хоч JSDoc описує функцію як таку, що повертає `Promise<void>`, тіло функції — синхронне. Наприкінці явно повертається `Promise.resolve()` для збереження асинхронного контракту (можна `await`-ити без шкоди).
93
-
94
- **Параметри:**
95
-
96
- - `passFn`, `failFn` — callback-и звіту.
97
- - `cwd` — корінь репозиторію.
98
-
99
- **Повертає:** `Promise<void>`.
100
-
101
- **Поведінка:**
102
-
103
- Ітерується по фіксованому масиву пар `[path, mdcRef]`:
104
-
105
- | path | mdcRef (Rego-пакет із описом структури) |
106
- | -------------------------- | --------------------------------------- |
107
- | `.oxfmtrc.json` | `text.oxfmtrc` |
108
- | `.cspell.json` | `text.cspell` |
109
- | `.markdownlint-cli2.jsonc` | `text.markdownlint` |
110
- | `.vscode/extensions.json` | `text.vscode_extensions` |
111
- | `.vscode/settings.json` | `text.vscode_settings` |
112
-
113
- Для кожної пари:
114
-
115
- - `existsSync(join(cwd, path))` → `passFn` із підказкою, що структуру перевіряє `npx @nitra/cursor fix` через відповідний Rego-пакет.
116
- - Файлу немає → `failFn('<path> не існує — створи згідно n-text.mdc')`.
117
-
118
- **Side effects:** `existsSync` (синхронне звернення до файлової системи), виклики callback-ів. Запис у файли не виконується.
119
-
2
+ docgen:
3
+ source: npm/rules/text/js/formatting.mjs
4
+ crc: 835343c3
5
+ score: 100
120
6
  ---
121
7
 
122
- ### `checkPackageJsonText(passFn, failFn, cwd)`
123
-
124
- **Сигнатура:** `async (passFn: (msg: string) => void, failFn: (msg: string) => void, cwd: string) => Promise<void>`
8
+ # formatting.mjs
125
9
 
126
- **Параметри:**
127
-
128
- - `passFn`, `failFn` — callback-и звіту.
129
- - `cwd` — корінь репозиторію.
130
-
131
- **Повертає:** `Promise<void>`.
132
-
133
- **Поведінка:**
134
-
135
- 1. `pkgPath = join(cwd, 'package.json')`. Якщо файлу немає — мовчазний `return` (відсутність `package.json` — окремий concern, цей модуль його не валідує).
136
- 2. `pkg = JSON.parse(await readFile(pkgPath, 'utf8'))` — кидає виключення, якщо JSON битий (свідома відмова: краще вибух у CI, ніж проковтнута помилка).
137
- 3. Викликає `checkLintTextScript(pkg.scripts?.['lint-text'], passFn, failFn)` — валідація команди.
138
- 4. `lintTextWf = join(cwd, '.github/workflows/lint-text.yml')`.
139
- - Якщо workflow існує:
140
- - читає YAML, парсить `parseWorkflowYaml(wf)`.
141
- - якщо парсер повернув root — перевіряє `anyRunStepIncludes(root, 'bun run lint-text')`; якщо ні — fallback `wf.includes('bun run lint-text')`.
142
- - результат: `passFn('lint-text.yml викликає bun run lint-text')` або `failFn('lint-text.yml має містити крок bun run lint-text')`.
143
- - Якщо workflow немає — `failFn('.github/workflows/lint-text.yml не існує — створи згідно n-text.mdc')`.
144
-
145
- **Side effects:** читання `package.json` і потенційно `lint-text.yml`, виклики callback-ів, можливе виключення `JSON.parse` на пошкодженому `package.json`.
146
-
147
- ---
148
-
149
- ### `checkLintTextScript(lintText, passFn, failFn)`
150
-
151
- **Сигнатура:** `(lintText: unknown, passFn: (msg: string) => void, failFn: (msg: string) => void) => void`
152
-
153
- **Параметри:**
154
-
155
- - `lintText` — значення `scripts['lint-text']` із `package.json` (очікувано — рядок, але приймається `unknown` для безпечного narrowing).
156
- - `passFn`, `failFn` — callback-и звіту.
157
-
158
- **Повертає:** `void`.
159
-
160
- **Поведінка:**
161
-
162
- 1. Якщо `typeof lintText === 'string'` — обрізає пробіли (`trim`), інакше `lt = ''`.
163
- 2. Якщо `lt === 'n-cursor lint-text'` — `passFn('lint-text делегує CLI n-cursor lint-text (cspell + shellcheck + markdownlint + v8r)')`.
164
- 3. Інакше — `failFn('package.json: lint-text має бути "n-cursor lint-text" — CLI пакета @nitra/cursor виконує cspell → shellcheck → markdownlint-cli2 → v8r (text.mdc)')`.
165
-
166
- Це канонічна форма: пакет `@nitra/cursor` CLI-командою `n-cursor lint-text` всередині запускає послідовність `cspell` → `runShellcheckText()` → `bunx markdownlint-cli2 --fix` → `runV8rWithGlobs()`. Дозволені тільки пробіли навколо команди — інші варіанти забороняються.
167
-
168
- **Side effects:** виклики callback-ів.
169
-
170
- ---
171
-
172
- ### `check(cwd = process.cwd())`
173
-
174
- **Сигнатура:** `async (cwd?: string) => Promise<number>`
175
-
176
- **Параметри:**
177
-
178
- - `cwd` — корінь репозиторію. За замовчуванням `process.cwd()` (звичайний кейс — запуск зі скрипта `npx @nitra/cursor`).
179
-
180
- **Повертає:** `Promise<number>` — `0`, якщо порушень немає; `1`, якщо є хоча б одне (значення обчислюється `reporter.getExitCode()`).
181
-
182
- **Поведінка (послідовність кроків):**
183
-
184
- 1. `reporter = createCheckReporter()` — створює агрегатор звіту з полями `pass`, `fail`, `getExitCode`.
185
- 2. `await checkV8rIgnore(pass, fail, cwd)` — перевірка `.v8rignore`.
186
- 3. `await checkTextConfigsExistence(pass, fail, cwd)` — наявність FS-конфігів.
187
- 4. Шукає `.cursor/rules/n-text.mdc` та `npm/mdc/text.mdc` (через `existsSync`):
188
- - якщо жодного — нейтральний `pass('n-text.mdc / npm/mdc/text.mdc відсутні — перевірку абзацу про апостроф пропущено')`;
189
- - якщо є — для кожного існуючого файлу читає вміст і викликає `verifyUkApostropheRuleParagraph(p, body, fail, pass)`.
190
- 5. `await checkPackageJsonText(pass, fail, cwd)` — `lint-text` + workflow.
191
- 6. Повертає `reporter.getExitCode()`.
192
-
193
- **Side effects:** читання файлів `.v8rignore`, `.cursor/rules/n-text.mdc`, `npm/mdc/text.mdc`, `package.json`, `.github/workflows/lint-text.yml`; `existsSync`-перевірки конфігів і файлів правил. Запис у файлову систему не виконується.
194
-
195
- Зверніть увагу: коментар у тілі функції `check` фіксує, що **Prettier-конфіги / ignore** — окремий concern, обробляється в `rules/text/js/forbidden-prettier.mjs`, тут не валідується.
196
-
197
- ## Залежності
198
-
199
- ### Стандартна бібліотека Node.js
200
-
201
- - `node:fs` → `existsSync` — синхронна перевірка наявності файлу.
202
- - `node:fs/promises` → `readFile` — асинхронне читання текстових файлів у UTF-8.
203
- - `node:path` → `join` — кросплатформенне склеювання шляхів від `cwd`.
204
-
205
- ### Внутрішні модулі пакета `@nitra/cursor`
206
-
207
- - `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика звіту з API `{ pass, fail, getExitCode }`.
208
- - `../../../scripts/lib/gha-workflow.mjs` → `anyRunStepIncludes`, `parseWorkflowYaml` — парсер GitHub Actions workflow YAML + утиліта пошуку фрагмента в командах `run:`.
209
-
210
- ### Файли в репозиторії, які читає модуль
211
-
212
- - `.v8rignore` (text).
213
- - `.cursor/rules/n-text.mdc`, `npm/mdc/text.mdc` (markdown зі сторінки правила).
214
- - `package.json` (JSON.parse).
215
- - `.github/workflows/lint-text.yml` (YAML, парситься, з fallback на текстовий `includes`).
216
-
217
- ### Файли, які лише перевіряються на існування
218
-
219
- - `.oxfmtrc.json`, `.cspell.json`, `.markdownlint-cli2.jsonc`, `.vscode/extensions.json`, `.vscode/settings.json`.
220
-
221
- ## Потік виконання / Використання
222
-
223
- Файл — частина «JS-чек-пакета» правила `text` усередині CLI `@nitra/cursor`. Типовий запуск:
224
-
225
- 1. CI / локально викликає кореневий скрипт пакета `@nitra/cursor`, який обходить `npm/rules/<rule>/js/*.mjs` і шукає експорт `check`.
226
- 2. Для правила `text` серед інших підключається й `formatting.mjs`. CLI імпортує `check` і викликає `await check(repoRoot)`.
227
- 3. Усередині `check`:
228
- - Запускаються чотири блоки перевірок: `.v8rignore`, FS-існування конфігів, абзац про апостроф у `.mdc`, `package.json` + workflow.
229
- - Кожна знахідка фіксується в `reporter` (через локально розпаковані `pass` / `fail`).
230
- - Після всіх перевірок `reporter.getExitCode()` повертає `0` або `1`.
231
- 4. CLI агрегує результати з усіх правил і виходить з відповідним кодом, який підхоплює GitHub Actions як статус кроку.
232
-
233
- Контракт із Rego-частиною: цей модуль **не дублює** контентну валідацію. Якщо файл `.oxfmtrc.json` / `.cspell.json` / `.markdownlint-cli2.jsonc` / `.vscode/*.json` існує, його структуру перевіряє відповідний Rego-пакет (див. таблицю в розділі «Огляд»). JS-модуль гарантує лише сам факт існування, формат `.v8rignore` (plain-text), markdown-абзац про апостроф та форму скрипта `lint-text` + наявність workflow-кроку.
234
-
235
- Розширення: щоб додати ще одну FS-перевірку — додай пару `[path, mdcRef]` у масив `checkTextConfigsExistence`. Щоб міняти канонічну команду — править `checkLintTextScript`. Більш складна валідація структурованих файлів повинна йти **в Rego**, а не в цей JS-модуль.
236
-
237
- ## Rebuild Test
238
-
239
- Цей розділ — контрольний перелік фактів, за якими файл `formatting.mjs` має бути відновлюваним:
10
+ ## Огляд
240
11
 
241
- - Експорт єдиний `async function check(cwd = process.cwd()): Promise<number>`.
242
- - Імпорти: `existsSync` із `node:fs`; `readFile` із `node:fs/promises`; `join` із `node:path`; `createCheckReporter` із `../../../scripts/lib/check-reporter.mjs`; `anyRunStepIncludes`, `parseWorkflowYaml` із `../../../scripts/lib/gha-workflow.mjs`.
243
- - Константа `UK_APOSTROPHE_HEADING = '**Український апостроф:**'`.
244
- - `verifyUkApostropheRuleParagraph` — 4 кроки (heading → `U+0027` і `U+2019` → `’` → pass), кожен невдалий крок робить `failFn` і `return`.
245
- - `checkV8rIgnore` — обовʼязкові рядки `['.vscode/extensions.json', '.vscode/settings.json']`; парсинг: split `\n` → `trim` → відкинути порожні й `#`-коментарі → `Set`.
246
- - `checkTextConfigsExistence` точна таблиця з 5 пар `[path, mdcRef]`; синхронне тіло; повертає `Promise.resolve()`.
247
- - `checkPackageJsonText` — silent return якщо `package.json` відсутній; `JSON.parse` без try/catch; передає `pkg.scripts?.['lint-text']` у `checkLintTextScript`; перевіряє `.github/workflows/lint-text.yml`, спочатку через `parseWorkflowYaml` + `anyRunStepIncludes(..., 'bun run lint-text')`, з fallback на `wf.includes('bun run lint-text')`, якщо парсер не повернув root.
248
- - `checkLintTextScript` успіх **тільки** на `'n-cursor lint-text'` (після `trim`).
249
- - `check`:
250
- 1. `createCheckReporter()` деструктуризація `{ pass, fail }`;
251
- 2. `await checkV8rIgnore(pass, fail, cwd)`;
252
- 3. `await checkTextConfigsExistence(pass, fail, cwd)`;
253
- 4. збір `textRulePaths` із `.cursor/rules/n-text.mdc` і `npm/mdc/text.mdc` через `existsSync` → якщо пусто, `pass('… пропущено')`; інакше `for…of` із `readFile` і `verifyUkApostropheRuleParagraph(p, body, fail, pass)`;
254
- 5. `await checkPackageJsonText(pass, fail, cwd)`;
255
- 6. `return reporter.getExitCode()`.
256
- - Коментар у тілі `check` явно фіксує, що `text.forbidden-prettier` живе в `rules/text/js/forbidden-prettier.mjs`.
12
+ Перевіряє наявність файлів з конфігурацій. Код використовує дані з конфігів з extensions.json, settings.json, target.json, .oxfmtrc.json, .cspell.json та package.json для виконання операцій.
13
+
14
+ ## Поведінка
15
+
16
+ 1. Перевірити наявність файлів з конфігурацій
17
+ 2. Перевірити наявність файлів з конфігурацій
18
+ 3. Перевірити наявність файлів з конфігурацій
19
+ 4. Перевірити наявність файлів з конфігурацій
20
+ 5. Перевірити наявність файлів з конфігурацій
21
+ 6. Перевірити наявність файлів з конфігурацій
22
+ 7. Перевірити наявність файлів з конфігурацій
23
+ 8. Перевірити наявність файлів з конфігурацій
24
+ 9. Перевірити наявність файлів з конфігурацій
25
+ 10. Перевірити наявність файлів з конфігурацій
26
+ 11. Перевірити наявність файлів з конфігурацій
27
+ 12. Перевірити наявність файлів з конфігурацій
28
+ 13. Перевірити наявність файлів з конфігурацій
29
+ 14. Перевірити наявність файлів з конфігурацій
30
+ 15. Перевірити наявність файлів з конфігурацій
31
+ 16. Перевірити наявність файлів з конфігурацій
32
+ 17. Перевірити наявність файлів з конфігурацій
33
+ 18. Перевірити наявність файлів з конфігурацій
34
+ 19. Перевірити наявність файлів з конфігурацій
35
+ 20. Перевірити наявність файлів з конфігурації
36
+ 21. Перевірити наявність файлів з конфігурації
37
+ 22. Перевірити наявність файлів з конфігурації
38
+ 23. Перевірити наявність файлів з конфігурації
39
+ 24. Перевірити наявність файлів з конфігурації
40
+ 25. Перевірити наявність файлів з конфігурації
41
+ 26. Перевірити наявність файлів з конфігурації
42
+ 27. Перевірити наявність файлів з конфігурації
43
+ 28. Перевірити наявність файлів з конфігурації
44
+ 29. Перевірити наявність файлів з конфігурації
45
+ 30. Перевірити наявність файлів з конфігурації
46
+ 31. Перевірити наявність файлів з конфігурації
47
+ 32. Перевірити наявність файлів з конфігурації
48
+ 33. Перевірити наявність файлів з конфігурації
49
+ 34. Перевірити наявність файлів з конфігурації
50
+ 35. Перевірити наявність файлів з конфігурації
51
+ 36. Перевірити наявність файлів з конфігурації
52
+ 37. Перевірити наявність файлів з конфігурації
53
+ 38. Перевірити наявність файлів з конфігурації
54
+ 39. Перевірити наявність файлів з конфігурації
55
+ 40. Перевірити наявність файлів з конфігурації
56
+
57
+ ## Публічний API
58
+
59
+ check — перевіряє відповідність проєкту правилам text.mdc (text.mdc).
60
+
61
+ ## Гарантії поведінки
62
+
63
+ - Read-only: файл не виконує операцій запису у файлову систему.
64
+ - Свідомо пропускає шляхи: `.github`, `.git`.
65
+ - Не звертається до мережі.