@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,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
+ - Не звертається до мережі.