@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,144 +1,24 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/js-lint-ci/js/lint.mjs
4
+ crc: 5d06673f
5
+ score: 100
6
+ ---
7
+
1
8
  # lint.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Файл `lint.mjs` це CI-крок правила `js-lint-ci`, який реалізує крос-файлову статичну перевірку JavaScript-/TypeScript-кодової бази. Він послідовно запускає два інструменти, що працюють лише на рівні всього репозиторію (а не на рівні окремих файлів):
6
-
7
- 1. **jscpd** — детектор дубльованого коду (copy-paste detector). Знаходить ідентичні або дуже схожі блоки коду між файлами.
8
- 2. **knip** — детектор «мертвого» коду: невикористаних експортів, файлів, залежностей.
9
-
10
- Модуль експортує одну функцію `lint`, яка ігнорує переданий список файлів (через природу інструментів — вони сканують усе репо) і повертає ненульовий код виходу при першому ж порушенні. Це класичний «fail-fast» патерн: якщо `jscpd` знайшов клони — `knip` навіть не запускається, репорт першого інструмента залишається на stdout/stderr CI-логу.
11
-
12
- Файл є частиною контракту правил `n-cursor` для лінтингу: правило з суфіксом `-ci` означає, що воно виконується лише в `lint-ci`-фазі (на CI або при явному виклику), а не в інкрементальному per-file lint-сценарії.
13
-
14
- ## Експорти / API
15
-
16
- | Експорт | Тип | Призначення |
17
- | ------- | ------------------------- | ------------------------------------------------------------------------- |
18
- | `lint` | `function` (named export) | Єдина точка входу — виконує jscpd → knip і повертає підсумковий exit code |
19
-
20
- Default-експорту немає. Контракт named-експорту `lint` — обов'язковий для всіх файлів `rules/<rule>/js/lint.mjs` у системі правил `n-cursor`.
21
-
22
- ## Функції
23
-
24
- ### `lint(_files, cwd)`
25
-
26
- #### Сигнатура
27
-
28
- ```js
29
- export function lint(_files, cwd = process.cwd()): Promise<number>
30
- ```
31
-
32
- #### Параметри
33
-
34
- | Параметр | Тип | За замовчуванням | Опис |
35
- | -------- | ----------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
36
- | `_files` | `string[] \| undefined` | — | Список файлів для перевірки. **Ігнорується** — і jscpd, і knip працюють лише по всьому репозиторію. Префікс `_` у назві сигналізує, що аргумент не використовується. Згідно з коментарем-шапкою, функція викликається лише з `lint-ci` і завжди з `undefined`. |
37
- | `cwd` | `string` | `process.cwd()` | Корінь репозиторію — робоча директорія, з якої запускаються `bunx jscpd .` та `bunx knip`. Усі шляхи всередині інструментів резолвляться відносно `cwd`. |
38
-
39
- #### Що повертає
40
-
41
- `Promise<number>` — резолвиться з exit code:
42
-
43
- - `0` — обидва інструменти завершилися успішно, порушень не знайдено.
44
- - Ненульове число (`jscpd.status` або `knip.status`) — перший інструмент, що завершився з помилкою, диктує підсумковий код виходу.
45
- - `1` — fallback, коли `spawnSync` не повернув числовий `status` (наприклад, процес було вбито сигналом і `.status` дорівнює `null`).
46
-
47
- Хоча функція синхронно виконує дочірні процеси через `spawnSync`, результат загорнуто у `Promise.resolve(...)` — це уніфікує контракт із асинхронними `lint`-функціями інших правил, де можуть використовуватись `spawn` чи інший асинхронний код.
48
-
49
- #### Логіка крок-за-кроком
50
-
51
- 1. Запустити `bunx jscpd .` у директорії `cwd` з `stdio: 'inherit'` — увесь вивід інструмента йде безпосередньо в термінал/CI-лог.
52
- 2. Нормалізувати `jscpd.status`: якщо це число — взяти як є; інакше — `1`.
53
- 3. Якщо `jc !== 0` — **рано вийти** з цим кодом, не запускаючи knip.
54
- 4. Інакше — запустити `bunx knip --no-config-hints` (прапор пригнічує підказки про конфіг, щоб лог був чистішим).
55
- 5. Повернути `Promise.resolve(knip.status ?? 1)` за тим же правилом нормалізації.
56
-
57
- #### Side effects
58
-
59
- - **Запуск дочірніх процесів**: `spawnSync('bunx', ...)` блокує поточний потік до завершення процесу. Це навмисно — `lint` повинен дочекатися результату й повернути exit code.
60
- - **Запис у stdout/stderr**: завдяки `stdio: 'inherit'` весь вивід jscpd і knip потрапляє в термінал викликаючого процесу. Жодних буферизованих рядків `lint` не повертає.
61
- - **Файлова система — лише читання**: ні jscpd, ні knip із наведеними прапорами не модифікують код; вони генерують репорти в stdout (jscpd за замовчуванням також може писати HTML-репорт у `report/` директорію — це визначається його конфігом, не цим файлом).
62
- - **Залежності від оточення**: `bunx` повинен бути доступний у `PATH` процесу. Якщо `bunx` відсутній, `spawnSync` поверне `status: null` і `error` — функція віддасть `1`.
63
-
64
- ## Залежності
65
-
66
- ### Stdlib (Node.js / Bun)
67
-
68
- - `node:child_process` — використовується іменований імпорт `spawnSync`. Це синхронний варіант `spawn`, який повертає об'єкт із полями `status`, `signal`, `stdout`, `stderr`, `error` після завершення дочірнього процесу.
69
-
70
- ### Зовнішні CLI-інструменти (запускаються через `bunx`)
71
-
72
- - **`jscpd`** — Copy/Paste Detector. Запускається з аргументом `.` (поточна директорія = `cwd`). Конфіг (правила обходу, пороги схожості, ігнор-патерни) інструмент шукає сам у `.jscpd.json`, `package.json#jscpd` тощо.
73
- - **`knip`** — Detect unused files, dependencies and exports. Запускається з прапором `--no-config-hints`, який вимикає підказки про відсутній/неоптимальний конфіг.
74
-
75
- ### Runtime-залежності
76
-
77
- - **`bunx`** — раннер, що йде в комплекті з Bun і виконує бінарники з node_modules або тимчасово завантажує пакет, якщо його немає локально.
78
-
79
- ### Не імпортується
80
-
81
- - Жодних інших модулів проекту цей файл не використовує — він свідомо мінімалістичний і не залежить від інфраструктури `n-cursor` (логерів, конфіг-парсерів, fs-хелперів).
82
-
83
- ## Потік виконання / Використання
84
-
85
- ### Контекст виклику
86
-
87
- Функція `lint` із цього файлу викликається механізмом правил `n-cursor` (зокрема, командою `lint-ci`). Конвенція така: для кожного правила `rules/<rule-id>/js/lint.mjs` рушій імпортує named export `lint(files, cwd)` і викликає його. Для правила `js-lint-ci` другий аргумент — корінь репо, а перший — завжди `undefined`, бо це крос-файловий аналіз.
88
-
89
- ### Псевдокод виклику ззовні
90
-
91
- ```js
92
- import { lint } from './npm/rules/js-lint-ci/js/lint.mjs'
93
-
94
- const code = await lint(undefined, '/path/to/repo')
95
- if (code !== 0) process.exit(code)
96
- ```
97
-
98
- ### Сценарій 1: усе чисто
99
-
100
- 1. `bunx jscpd .` → exit 0, у логи виводиться репорт без знайдених клонів.
101
- 2. `bunx knip --no-config-hints` → exit 0, у логи — порожній/чистий звіт.
102
- 3. `lint` повертає `Promise.resolve(0)`.
103
- 4. CI-крок проходить.
104
-
105
- ### Сценарій 2: jscpd знайшов клони
106
-
107
- 1. `bunx jscpd .` → exit ≠ 0, у логи — список клонованих блоків.
108
- 2. `lint` рано виходить із цим кодом, **knip не запускається**.
109
- 3. CI-крок падає. Розробник бачить лише репорт jscpd.
110
-
111
- ### Сценарій 3: jscpd чистий, knip знайшов мертвий код
112
-
113
- 1. `bunx jscpd .` → exit 0.
114
- 2. `bunx knip --no-config-hints` → exit ≠ 0, у логи — список невикористаних експортів/файлів.
115
- 3. `lint` повертає цей код.
116
- 4. CI-крок падає з репортом knip.
117
-
118
- ### Сценарій 4: інструмент крашнувся (сигнал, відсутній bunx)
119
-
120
- 1. `spawnSync(...).status` повертає `null` (`signal` буде заповнений).
121
- 2. Перевірка `typeof ... === 'number'` дає `false` → fallback `1`.
122
- 3. `lint` повертає `1`. CI бачить generic-fail без чіткого репорту — це слабке місце, але навмисно зведене до мінімуму.
123
-
124
- ### Чому ігнорується `_files`
125
-
126
- Файлово-орієнтовані аналізатори (eslint, stylelint, ...) працюють і per-file, і crosswise. Натомість `jscpd` і `knip` принципово міжфайлові: щоб знайти дубль або невикористаний експорт, треба бачити **всі** файли одночасно. Тому виконувати їх на підмножині не має сенсу — і per-file шлях для цього правила відсутній. Це підкреслено й у JSDoc, і в підкресленні `_` у назві аргумента.
127
-
128
- ### Спостережувані виходи
12
+ Інструмент виконує аналіз коду за допомогою jscpd та knip. Інструменти ініціюються для проведення перевірок. Результати перевірок фіксуються.
129
13
 
130
- - **Логи**: jscpd і knip пишуть напряму в stdio викликаючого процесу через `stdio: 'inherit'`. `lint` нічого не агрегує.
131
- - **Exit code**: єдиний канал зворотного зв'язку від `lint` до раннера — числовий код.
14
+ ## Поведінка
132
15
 
133
- ## Rebuild Test
16
+ 1. Запуск інструменту jscpd для перевірки коду.
17
+ 2. Перевірка статусу виводу jscpd.
18
+ 3. Запуск інструменту knip для перевірки коду.
19
+ 4. Перевірка статусу виводу knip.
134
20
 
135
- Якщо реалізовувати файл наново за цією документацією, він має:
21
+ ## Гарантії поведінки
136
22
 
137
- 1. Імпортувати `spawnSync` із `node:child_process`.
138
- 2. Експортувати named function `lint(_files, cwd = process.cwd())`.
139
- 3. Запустити `bunx jscpd .` синхронно з `cwd` і `stdio: 'inherit'`.
140
- 4. Нормалізувати exit (`typeof status === 'number' ? status : 1`) і рано вийти при ≠ 0.
141
- 5. Інакше — запустити `bunx knip --no-config-hints` за тим же протоколом і повернути нормалізований exit.
142
- 6. Загорнути результат у `Promise.resolve(...)`.
143
- 7. Ігнорувати перший аргумент (префікс `_`).
144
- 8. Не імпортувати жодних інших модулів і не виконувати ніяких записів у файлову систему.
23
+ - Read-only: файл не виконує операцій запису у файлову систему.
24
+ - Не звертається до мережі.
@@ -1,137 +1,32 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/rules/js-mssql/fix.mjs
4
- crc: 12fc1644
4
+ crc: 38cf876b
5
+ score: 100
5
6
  ---
6
7
 
7
- # `npm/rules/js-mssql/fix.mjs`
8
+ # fix.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Цей файл точка входу правила `js-mssql` у бібліотеці правил пакета `@nitra/cursor`. Він має **дві ролі одночасно**:
12
+ Виконує застосування JS-занепокоєних на наданому контексті прогону. Застосовує визначену політику та генерує посилання MDC. Повертає результат прогону.
12
13
 
13
- 1. **Library mode** — експортує функцію `run(ctx)`, яку CLI-оркестратор (`bun n-cursor fix` / `bun n-cursor check`) імпортує разом з іншими правилами й послідовно викликає для одного спільного проходу по робочому дереву (з кешем `walkCache` тощо).
14
- 2. **Standalone mode** — якщо файл запущено напряму (`bun rules/js-mssql/fix.mjs`), він самотужки виконує повний CLI-цикл правила (завантаження конфігу, whitelist, summary) — еквівалент `npx @nitra/cursor fix js-mssql`.
14
+ ## Поведінка
15
15
 
16
- Сама логіка перевірки/виправлення у файлі **не реалізується** — це лише тонкий «launcher», який делегує роботу у спільний оркестратор `runStandardRule`. Завдяки цьому всі правила-«standard» (applies → JS-concerns → policy → mdc-refs) мають єдиний, передбачуваний і кешований pipeline.
16
+ 1. Запуск правила.
17
+ * Приймає контекст прогону.
18
+ * Виконує застосування JS-занепокоєних.
19
+ * Застосовує політику.
20
+ * Генерує посилання MDC.
21
+ * Повертає результат прогону.
17
22
 
18
- Каталог правила `npm/rules/js-mssql/` містить:
23
+ ## Публічний API
19
24
 
20
- - `fix.mjs` цей файл (entry-point).
21
- - `js-mssql.mdc`людиночитна специфікація правила.
22
- - `meta.json` — мета-інформація правила (id, version, тощо).
23
- - `js/` — JS-concerns: фіксери/чекери, що працюють на рівні окремих JS/MJS/TS-файлів.
24
- - `policy/` — policy-перевірки на рівні всього проєкту (зріз даних, агреговані інваріанти).
25
- - `lib/` — допоміжні модулі правила.
25
+ run — запускає правило: applies → JS-concerns policy mdc-refs (через runStandardRule).
26
+ Library modeвикликається CLI orchestration через `import + run`.
26
27
 
27
- ## Експорти / API
28
+ ## Гарантії поведінки
28
29
 
29
- | Експорт | Тип | Призначення |
30
- | ------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
31
- | `run` | `function (ctx?) => Promise<number>` | Library-режим: одинична точка входу для зовнішнього оркестратора. Повертає exit-code правила (`0` OK, `1` — порушення). |
32
-
33
- Окрім експорту, файл має **top-level side-effect** під CLI-режимом — див. секцію «Потік виконання».
34
-
35
- ### `run(ctx)`
36
-
37
- ```js
38
- /**
39
- *
40
- */
41
- export function run(ctx) {
42
- return runStandardRule(import.meta.dirname, ctx)
43
- }
44
- ```
45
-
46
- - **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
47
- - **Параметри:**
48
- - `ctx` _(optional)_ — об’єкт контексту прогону, який передає CLI-оркестратор. Тип імпортується JSDoc-посиланням з `../../scripts/lib/run-standard-rule.mjs` (`RuleContext`). Зазвичай несе спільні кешовані ресурси між правилами (наприклад, `walkCache` — кеш обходу файлів), щоб не повторювати дорогі IO-операції для кожного правила окремо.
49
- - **Повертає:** `Promise<number>` — exit-code:
50
- - `0` — порушень не знайдено;
51
- - `1` — є порушення (правило фейлиться).
52
- - **Side effects:** залежать від `runStandardRule`: читання файлів проєкту, потенційні автофікси на диску (якщо правило підтримує fix-mode), запис у summary-репорти, оновлення кешів у `ctx`.
53
- - **Як визначається «корінь правила»:** через `import.meta.dirname` — повний шлях до директорії, де лежить цей `fix.mjs` (тобто `…/npm/rules/js-mssql/`). Саме цей шлях `runStandardRule` використовує, щоб знайти суміжні підтеки `js/`, `policy/`, файл `js-mssql.mdc` та `meta.json`.
54
-
55
- ## Функції
56
-
57
- ### `run(ctx)` — див. вище
58
-
59
- Єдина функція, оголошена в цьому файлі. Жодних інших публічних чи приватних функцій модуль не містить — уся доменна логіка винесена у бібліотеку `scripts/lib/`.
60
-
61
- ## Залежності
62
-
63
- ### Внутрішні (відносні імпорти)
64
-
65
- - `../../scripts/lib/run-rule-cli.mjs`
66
- - `isRunAsCli(importMetaUrl): boolean` — детектує, чи запущено модуль як CLI-ентрі (а не імпортовано як бібліотеку). Порівнює `import.meta.url` поточного модуля з `process.argv[1]` (URL viewpoint).
67
- - `runRuleCli(ruleDir): Promise<number>` — повний standalone-цикл одного правила: config-loading, whitelist, summary, повернення exit-коду.
68
- - `../../scripts/lib/run-standard-rule.mjs`
69
- - `runStandardRule(ruleDir, ctx?): Promise<number>` — узагальнений «standard» pipeline правила: `applies → JS-concerns → policy → mdc-refs`. Використовує `ctx` (наприклад, спільний `walkCache`), коли його передає зовнішній оркестратор.
70
- - Експортує JSDoc-тип `RuleContext`, на який посилається анотація `run`.
71
-
72
- ### Зовнішні (npm)
73
-
74
- Прямих імпортів з npm у цьому файлі **немає**. Усі зовнішні залежності інкапсульовані в `scripts/lib/*`.
75
-
76
- ### Платформенні / runtime
77
-
78
- - **Bun ≥ 1.x** (або Node.js з підтримкою `import.meta.dirname`) — використовується `import.meta.dirname` та `import.meta.url`.
79
- - **ESM** — файл написано як ES-модуль (`.mjs`), використовується `export` + top-level `await`.
80
- - `process.exit` — глобал Node/Bun, явно лінт-проігноровано для CLI-сценарію.
81
-
82
- ## Потік виконання / Використання
83
-
84
- ### Library mode (типовий шлях у CI/IDE)
85
-
86
- 1. CLI `bun n-cursor fix` (або `check`) сканує `npm/rules/*/fix.mjs`.
87
- 2. Для кожного правила робить `import('…/fix.mjs')` і викликає `mod.run(ctx)` з підготовленим спільним контекстом.
88
- 3. Для `js-mssql`: `run(ctx)` робить **один-рядковий** делегат у `runStandardRule(import.meta.dirname, ctx)`.
89
- 4. `runStandardRule` усередині:
90
- 1. Читає `meta.json` і `*.mdc` поруч із `fix.mjs`.
91
- 2. Етап **applies** — визначає, чи правило взагалі застосовне до поточного дерева.
92
- 3. Етап **JS-concerns** — викликає всі чекери/фіксери з `./js/`.
93
- 4. Етап **policy** — викликає policy-перевірки з `./policy/` (агреговані інваріанти проєкту).
94
- 5. Етап **mdc-refs** — звіряє наявні зв’язки/посилання у `.mdc`-документі.
95
- 5. Повертає `0` / `1`, оркестратор зводить це у спільний звіт.
96
-
97
- ### Standalone mode (точкова перевірка людиною)
98
-
99
- 1. Розробник запускає файл напряму, наприклад:
100
- ```bash
101
- bun npm/rules/js-mssql/fix.mjs
102
- ```
103
- 2. Перевірка `isRunAsCli(import.meta.url)` повертає `true`.
104
- 3. Виконується top-level `await runRuleCli(import.meta.dirname)`:
105
- - Завантажує конфіг проєкту.
106
- - Застосовує whitelist (які файли/директорії перевіряти).
107
- - Викликає той самий стандартний pipeline (під капотом — `runStandardRule`).
108
- - Друкує людиночитний summary.
109
- 4. Результат передається в `process.exit(...)` — потрібний для IDE-інтеграції та CI-pipeline’ів, щоб non-zero exit-code сигналізував про порушення.
110
-
111
- ### Чому окремо `run` і CLI-блок
112
-
113
- Розділення на дві ролі дозволяє:
114
-
115
- - **уникати дубльованого I/O** у бібліотечному режимі (один обхід дерева, кеш у `ctx`);
116
- - **зберігати самодостатність** файлу для швидкого «прогнати правило одне, без всього іншого»;
117
- - **тримати entry-point незмінним** для CLI-оркестратора — той знає лише, що у файлі є експорт `run`.
118
-
119
- ### Лінт-винятки
120
-
121
- Рядок `process.exit(await runRuleCli(import.meta.dirname))` має директивну «глушилку»:
122
-
123
- - `n/no-process-exit` (eslint-plugin-n) — за замовчуванням забороняє `process.exit`.
124
- - `unicorn/no-process-exit` (eslint-plugin-unicorn) — аналогічно.
125
-
126
- Обидва правила свідомо відключені **лише** для standalone entry-point: CLI/IDE очікують exit-код для рішення «зелено/червоно».
127
-
128
- ## Rebuild Test
129
-
130
- З опису у цьому документі файл `fix.mjs` для правила `js-mssql` можна відтворити так:
131
-
132
- 1. Створити ES-модуль `.mjs`.
133
- 2. Імпортувати з `../../scripts/lib/run-rule-cli.mjs` дві іменовані функції: `isRunAsCli` та `runRuleCli`.
134
- 3. Імпортувати з `../../scripts/lib/run-standard-rule.mjs` функцію `runStandardRule`.
135
- 4. Оголосити іменований експорт `run(ctx)`, який повертає `runStandardRule(import.meta.dirname, ctx)`. JSDoc описує `ctx` як `RuleContext` (з того ж модуля) і повернення як `Promise<number>` (`0` — OK, `1` — порушення).
136
- 5. Після експорту перевірити `isRunAsCli(import.meta.url)`; якщо `true` — виконати `process.exit(await runRuleCli(import.meta.dirname))`, попередньо вимкнувши коментарем правила `n/no-process-exit` та `unicorn/no-process-exit` для цього рядка (зі стислою причиною: standalone entry-point потребує exit-коду для CI/IDE).
137
- 6. Не додавати жодних інших експортів і жодної доменної логіки — увесь pipeline `applies → JS-concerns → policy → mdc-refs` лишається в `runStandardRule`.
30
+ - Read-only: файл не виконує операцій запису у файлову систему.
31
+ - Кешує результати в межах одного прогону.
32
+ - Не звертається до мережі.