@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,183 +1,39 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/rules/changelog/fix.mjs
4
- crc: 12fc1644
4
+ crc: 38cf876b
5
+ score: 100
5
6
  ---
6
7
 
7
- # fix.mjs — точка входу правила `changelog`
8
+ # fix.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Файл `npm/rules/changelog/fix.mjs` тонкий **entry-point** для правила `changelog` у складі пакета `@nitra/cursor`. Він виконує дві ролі одночасно:
12
+ Виконує застосування JS-занепокоєних на наданому контексті прогону. Застосовує визначену політику та генерує посилання MDC. Повертає результат прогону.
12
13
 
13
- 1. **Library mode** — експортує функцію `run(ctx)`, яку викликає зовнішній CLI-оркестратор (`scripts/cli/fix.mjs` або аналог), коли користувач запускає `npx @nitra/cursor fix changelog` (чи прогін усіх правил `fix`). У цьому режимі `runStandardRule` отримує контекст із кешем обходу файлової системи (`walkCache`), shared summary тощо.
14
- 2. **Standalone mode** — якщо файл запущено напряму (`bun npm/rules/changelog/fix.mjs`), виконується повноцінний CLI-сценарій із завантаженням конфігу, whitelist-фільтрацією й friendly summary — тобто еквівалент `npx @nitra/cursor fix changelog`.
14
+ ## Поведінка
15
15
 
16
- Сам файл **не містить бізнес-логіки** правила: вся перевірка/автофікс ділиться між суб-модулями (`applies` → `JS-concerns` → `policy` → `mdc-refs`), які підтягуються конвенційно через `runStandardRule(import.meta.dirname, ctx)`. Поведінка повністю детермінована директорією, в якій лежить `fix.mjs` (`import.meta.dirname` вказує на `npm/rules/changelog/`).
16
+ 1. Запуск правила.
17
+ * Приймає контекст прогону.
18
+ * Виконує застосування JS-занепокоєних.
19
+ * Застосовує політику.
20
+ * Генерує посилання MDC.
21
+ * Повертає результат прогону.
22
+ 2. Виконання у режимі CLI.
23
+ * Виконується як окремий скрипт.
24
+ * Еквівалент команди `npx @nitra/cursor fix <id>`.
25
+ * Виконує завантаження конфігурації.
26
+ * Виконує перевірку дозволених елементів.
27
+ * Генерує зведену інформацію.
28
+ * Виконує повний еквівалент `fix.mjs`.
17
29
 
18
- Це шаблонний файл-обгортка — він повторюється для **кожного** правила в `npm/rules/<rule-id>/fix.mjs`. Зміни тут зазвичай небажані; натомість конкретна перевірка живе у сусідніх теках (`js/`, `lib/`, `meta.json`, `changelog.mdc`).
30
+ ## Публічний API
19
31
 
20
- ## Експорти / API
32
+ run запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
33
+ Library mode — викликається CLI orchestration через `import + run`.
21
34
 
22
- | Експорт | Тип | Призначення |
23
- | ------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
24
- | `run` | `function (ctx?: RuleContext) => Promise<number>` | Library-функція для виклику з зовнішнього CLI; повертає exit-code `0` (OK) або `1` (є порушення). |
35
+ ## Гарантії поведінки
25
36
 
26
- Сторонніх іменованих експортів немає. Default export відсутній.
27
-
28
- ### Side-effect при імпорті
29
-
30
- Файл містить **top-level умовний блок**:
31
-
32
- ```js
33
- if (isRunAsCli(import.meta.url)) {
34
- process.exit(await runRuleCli(import.meta.dirname))
35
- }
36
- ```
37
-
38
- — якщо модуль виконується як точка входу процесу (`process.argv[1]` відповідає `import.meta.url`), він **завершить процес** через `process.exit(...)`. У звичайному library-імпорті (`import { run } from '.../fix.mjs'`) `isRunAsCli` повертає `false`, отже `process.exit` НЕ викликається — імпорт безпечний.
39
-
40
- Зверніть увагу на `await` на top-level — файл потребує підтримки top-level await (ESM, Node ≥ 14.8 / Bun).
41
-
42
- ## Функції
43
-
44
- ### `run(ctx)`
45
-
46
- ```js
47
- /**
48
- *
49
- */
50
- export function run(ctx) {
51
- return runStandardRule(import.meta.dirname, ctx)
52
- }
53
- ```
54
-
55
- - **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
56
- - **Параметри:**
57
- - `ctx` _(optional)_ — об'єкт `RuleContext`, тип якого імпортується з `../../scripts/lib/run-standard-rule.mjs`. Зазвичай несе спільний стан між кількома правилами: кеш обходу файлів (`walkCache`), accumulator для summary, прапорці dry-run/auto-fix тощо. Якщо `ctx` не передано — `runStandardRule` створить дефолтний контекст всередині.
58
- - **Повертає:** `Promise<number>` — exit-code правила:
59
- - `0` — порушень немає (або всі автоматично виправлені);
60
- - `1` — є невиправні порушення / помилки.
61
- - **Side effects:**
62
- - Делегує всю роботу до `runStandardRule(dir, ctx)`. Це може включати: обхід файлової системи (`walkdir`), читання/запис файлів-учасників правила (auto-fix), вивід у `stdout`/`stderr` через спільний логер, мутацію `ctx.walkCache` тощо.
63
- - **Не** викликає `process.exit` напряму.
64
- - **Помилки:** будь-який reject від `runStandardRule` пробрасується нагору (caller відповідає за `try/catch`).
65
-
66
- ### Анонімний CLI-блок (top-level)
67
-
68
- ```js
69
- if (isRunAsCli(import.meta.url)) {
70
- process.exit(await runRuleCli(import.meta.dirname))
71
- }
72
- ```
73
-
74
- - **Тригер:** виконується **лише** коли файл — точка входу процесу. Використовує `isRunAsCli(import.meta.url)` для надійного визначення (порівняння `import.meta.url` з `process.argv[1]` через `pathToFileURL`).
75
- - **Дія:** делегує до `runRuleCli(import.meta.dirname)` — повноцінного CLI-обгортача, який:
76
- - завантажує конфіг (`.cursor/cursor.json` чи аналог);
77
- - застосовує whitelist/blacklist;
78
- - збирає friendly summary;
79
- - запускає `runStandardRule` всередині.
80
- - **Завершення:** `process.exit(<exit-code>)` — пробрасує код у shell для CI/IDE-інтеграцій.
81
- - **ESLint disables:**
82
- - `n/no-process-exit` та `unicorn/no-process-exit` свідомо вимкнено коментарем — standalone entry-point **зобов'язаний** повертати exit-code для CI/IDE.
83
-
84
- ## Залежності
85
-
86
- ### Внутрішні (relative imports)
87
-
88
- | Модуль | Що використано | Призначення |
89
- | ----------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90
- | `../../scripts/lib/run-rule-cli.mjs` | `isRunAsCli`, `runRuleCli` | Хелпери standalone-режиму: детект "запущено як CLI" та повноцінна CLI-обгортка. |
91
- | `../../scripts/lib/run-standard-rule.mjs` | `runStandardRule` | Універсальний раннер, що виконує "стандартну" послідовність етапів правила: `applies → JS-concerns → policy → mdc-refs`. Також експортує тип `RuleContext` (через JSDoc-`import`). |
92
-
93
- Шлях `../../` веде з `npm/rules/changelog/` до `npm/scripts/lib/`.
94
-
95
- ### Сусідні артефакти правила `changelog`
96
-
97
- Не імпортуються напряму з цього файлу, але **використовуються `runStandardRule`** конвенційно (за іменами файлів у тій самій теці):
98
-
99
- - `npm/rules/changelog/meta.json` — метадані правила (id, опис, теги, прапорці `worktree`/`policy`).
100
- - `npm/rules/changelog/changelog.mdc` — людинозрозумілий зміст правила (Cursor MDC).
101
- - `npm/rules/changelog/js/` — JS-concerns (перевірки/фікси для коду).
102
- - `npm/rules/changelog/lib/` — допоміжні модулі правила.
103
-
104
- ### Зовнішні (Node/runtime)
105
-
106
- - `import.meta.url` — стандарт ESM, для детекту CLI-режиму.
107
- - `import.meta.dirname` — потребує Node ≥ 20.11 або Bun (Bun підтримує). Передається в обидва раннери як корінь правила.
108
- - `process.exit` — глобал Node/Bun.
109
- - Top-level `await` — ESM-фіча, потребує сумісного runtime.
110
-
111
- ## Потік виконання / Використання
112
-
113
- ### Library mode (типовий — виклик з оркестратора `fix`)
114
-
115
- ```text
116
- npx @nitra/cursor fix
117
-
118
-
119
- scripts/cli/fix.mjs (orchestrator)
120
- │ для кожного правила з whitelist:
121
-
122
- import { run } from 'npm/rules/<id>/fix.mjs'
123
-
124
-
125
- run(ctx)
126
-
127
-
128
- runStandardRule(import.meta.dirname, ctx)
129
-
130
-
131
- applies → JS-concerns → policy → mdc-refs
132
-
133
-
134
- Promise<0 | 1>
135
- ```
136
-
137
- Приклад програмного виклику:
138
-
139
- ```js
140
- import { run } from '@nitra/cursor/npm/rules/changelog/fix.mjs'
141
-
142
- const code = await run({ walkCache: new Map(), summary: [] })
143
- if (code !== 0) {
144
- // є порушення — обробити в caller
145
- }
146
- ```
147
-
148
- ### Standalone mode (ручний запуск/debug)
149
-
150
- ```bash
151
- bun npm/rules/changelog/fix.mjs
152
- # еквівалент:
153
- npx @nitra/cursor fix changelog
154
- ```
155
-
156
- Послідовність:
157
-
158
- 1. ESM-модуль завантажується як entry-point.
159
- 2. Виконуються імпорти.
160
- 3. Експорт `run` реєструється (але ніхто не викликає).
161
- 4. Виконується умова `isRunAsCli(import.meta.url)` → `true`.
162
- 5. `await runRuleCli(import.meta.dirname)` — завантажує конфіг, фільтрує whitelist (тут — лише поточне правило, бо `dirname` фіксує id), запускає `runStandardRule`, друкує summary.
163
- 6. `process.exit(<code>)` — повертає exit-code у shell.
164
-
165
- ### Чому два режими в одному файлі?
166
-
167
- - **DRY** — не дублювати entry-point на кожне правило.
168
- - **DevEx** — розробник може дебажити одне правило: `bun npm/rules/<id>/fix.mjs`.
169
- - **CI** — оркестратор `fix.mjs` імпортує `run` гуртом, ділить кеш обходу між правилами для прискорення.
170
-
171
- ## Rebuild Test (контекстна незалежність)
172
-
173
- Файл можна відтворити, маючи лише цю документацію:
174
-
175
- 1. Створіть `npm/rules/changelog/fix.mjs`.
176
- 2. Імпортуйте `isRunAsCli` та `runRuleCli` з `../../scripts/lib/run-rule-cli.mjs`.
177
- 3. Імпортуйте `runStandardRule` з `../../scripts/lib/run-standard-rule.mjs`.
178
- 4. Експортуйте функцію `run(ctx)`, яка повертає результат `runStandardRule(import.meta.dirname, ctx)`.
179
- 5. Додайте JSDoc до `run` з типом `RuleContext` (через `import('../../scripts/lib/run-standard-rule.mjs').RuleContext`) і `Promise<number>` на повернення.
180
- 6. Внизу додайте умовний блок `if (isRunAsCli(import.meta.url)) { process.exit(await runRuleCli(import.meta.dirname)) }`.
181
- 7. Поряд із `process.exit(...)` додайте eslint-disable коментар для `n/no-process-exit` та `unicorn/no-process-exit` із обґрунтуванням "standalone entry-point має повертати exit-code для CI/IDE".
182
-
183
- Результат має бути ідентичним за поведінкою оригіналу: library-імпорт безпечний, standalone-запуск завершує процес коректним exit-code.
37
+ - Read-only: файл не виконує операцій запису у файлову систему.
38
+ - Кешує результати в межах одного прогону.
39
+ - Не звертається до мережі.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/rules/ci4/fix.mjs
4
- crc: 12fc1644
4
+ crc: 38cf876b
5
5
  score: 100
6
6
  ---
7
7
 
@@ -9,26 +9,23 @@ docgen:
9
9
 
10
10
  ## Огляд
11
11
 
12
- Модуль виконує бізнес-процес трансформації даних. Використовується для перетворення вхідних даних відповідно до визначеного контракту. Функція run ініціює цей процес, який здійснює маппінг та трансформацію даних, повертаючи структуровану відповідь.
12
+ Огляд
13
+ Файл надає функціонал для виконання визначених правил. Публічні методи забезпечують запуск цих правил, повертаючи отримані результати. Дозволяє запускати правила у режимі командного рядка, керуючи виходом процесу на основі отриманих даних.
13
14
 
14
15
  ## Поведінка
15
16
 
16
- 1. Виклик функції run передає контекст прогону для виконання правила.
17
+ 1. Запуск правила.
18
+ * Виклик runStandardRule з контекстом.
19
+ * Повернення результату.
17
20
 
18
- 2. Виконання правила відбувається через стандартний механізм перевірки.
19
-
20
- 3. У режимі бібліотеки функція викликає основну логіку перевірки, яка включає застосування правил, перевірку конфігурації та формування посилань.
21
-
22
- 4. Якщо виконання відбувається у режимі командного рядка, функція виконує повний еквівалент інструментального прогону.
23
-
24
- 5. У режимі командного рядка функція виконує команду, яка включає завантаження конфігурації, перевірку дозволених елементів та формування зведення.
25
-
26
- 6. У режимі командного рядка результат виконання передається для негайного завершення процесу, що використовується для інструментальних середовищ.
21
+ 2. Запуск правила у режимі CLI.
22
+ * Виклик runRuleCli з директорією модуля.
23
+ * Вихід з процесом залежно від результату.
27
24
 
28
25
  ## Публічний API
29
26
 
30
- run — Запускає послідовність перевірок: applies до mdc-refs через policy та JS-concerns.
31
- Library mode — Викликається через CLI оркестрацію за допомогою імпорту та функції run.
27
+ run — запускає правило: applies JS-concerns policy mdc-refs (через runStandardRule).
28
+ Library mode — викликається CLI orchestration через `import + run`.
32
29
 
33
30
  ## Гарантії поведінки
34
31
 
@@ -0,0 +1,60 @@
1
+ ---
2
+ description: Файлова документація — обовʼязковий крок задачі (як lint); детермінований детектор застарілості за CRC джерела (lint-doc-files), генерація local-only конвеєром (fix-doc-files)
3
+ globs: "**/*.{js,mjs,ts,vue,py,rs},**/docs/**"
4
+ alwaysApply: true
5
+ version: '1.0'
6
+ ---
7
+
8
+ Кожен кодовий файл (`.js .mjs .ts .vue .py .rs`, крім тестів і `.d.ts`) має **актуальну**
9
+ файлову доку поряд: `<dir>/docs/<stem>.md`. Це **обовʼязковий крок кожної задачі**, нарівні
10
+ з lint. Актуальність детермінується за **CRC** джерела, записаним у frontmatter доки.
11
+
12
+ ## Дві відповідальності — дві команди
13
+
14
+ - **`lint-doc-files`** — детермінований **детектор**: знаходить кодові файли без актуальної
15
+ доки. **0 викликів LLM**, працює локально, в hook'ах і в CI.
16
+ - **`fix-doc-files`** — **генератор**: створює/оновлює доки local-only конвеєром (omlx) зі
17
+ штампом CRC. Потребує локальної моделі; у CI **не** запускається.
18
+
19
+ Це та сама пара, що `/n-lint` (детект) проти `/n-fix` (закриття) у решті проєкту.
20
+
21
+ ## Stale = `missing` ∪ `crc-mismatch`
22
+
23
+ Дока застаріла, якщо її **немає** (`missing`) або `crc(джерело) ≠ crc` у frontmatter
24
+ (`crc-mismatch`). **Degraded** (низький score, але CRC свіжий) — **не** stale; це борг, видимий
25
+ через `lint-doc-files --degraded` і закривається `fix-doc-files --retry-degraded`.
26
+
27
+ Алгоритм детекту (кандидати, ignore-дерево, CRC, реверс-мапінг доки→джерело) повністю в
28
+ `js/docgen-scan.mjs` / `js/docgen-crc.mjs` / `js/docgen-ignore.mjs` і адаптері `js/lint.mjs`;
29
+ тут — лише людинозрозумілий контракт, без дублювання логіки.
30
+
31
+ ## Мапа команд
32
+
33
+ | Команда | Exit | Семантика |
34
+ | --- | --- | --- |
35
+ | `lint-doc-files` | 1 — є stale | повний детект, людиночитний список stale |
36
+ | `lint-doc-files [paths…]` | 1 | точковий детект заданих джерел |
37
+ | `lint-doc-files --missing-only` | 1 | лише `missing`, без `crc-mismatch` |
38
+ | `lint-doc-files --json` | 0 | JSON-лістинг усіх кандидатів зі станом |
39
+ | `lint-doc-files --hook` | 2 — stale | PostToolUse: stdin JSON, один файл |
40
+ | `lint-doc-files --git [--max N]` | 2 — stale | Stop-гейт: `git diff` HEAD; понад поріг (`N_CURSOR_DOC_FILES_GATE_MAX`, дефолт 50) — warn + exit 0 |
41
+ | `lint-doc-files --degraded` | 0 | звіт про доки зі score < порогу |
42
+ | `fix-doc-files [--limit/--from/--overwrite/--retry-degraded]` | 0/1 | local-only генерація зі штампом CRC |
43
+ | `fix-doc-files --stamp` | 0/1 | детерміноване перештампування `source`+`crc` без LLM |
44
+
45
+ Exit-коди: повний прогін — **1** (конвенція `lint-*`); `--hook`/`--git` — **2** (hook-протокол
46
+ Claude Code: blocking feedback).
47
+
48
+ ## Hook'и
49
+
50
+ PostToolUse (`lint-doc-files --hook`) **сигналить** про дрейф після правки кодового файлу;
51
+ Stop-гейт (`lint-doc-files --git`) **блокує завершення** задачі за наявності застарілих док
52
+ (виняток — масовий прогін понад поріг). Регенерація — `/doc-files` (JS-оркестрована, не диспатч
53
+ субагентів). Агрегуюча дока (module-summary, доменні) — окремий скіл `/doc-aggregate`.
54
+
55
+ ## Серіалізація
56
+
57
+ Повний `lint-doc-files` і `fix-doc-files` серіалізуються через `runStandardLint` /
58
+ `runStandardRule` (ключі `lint-doc-files` / `fix-doc-files`, виводяться зі шляху каталогу).
59
+ `--hook` / `--git` — окрема форма **без локу** (швидкий точковий вердикт). Деталі —
60
+ `.cursor/rules/scripts.mdc`, секція «Серіалізація важких CLI-команд».
@@ -0,0 +1,31 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/doc-files/fix.mjs
4
+ crc: 9df3e88d
5
+ score: 100
6
+ ---
7
+
8
+ # fix.mjs
9
+
10
+ ## Огляд
11
+
12
+ Точка входу правила doc-files для каналу `n-cursor fix doc-files`. Перевіряє структурні вимоги
13
+ правила (наявність потрібного GA-workflow і скрипта в `package.json` через policy-канал), не
14
+ чіпаючи вміст самих док.
15
+
16
+ ## Поведінка
17
+
18
+ Делегує стандартному оркестратору правил: applies → JS-concerns → policy → перевірка
19
+ markdown-посилань. Контентні порушення (відсутні чи застарілі файлові доки) свідомо поза цим
20
+ каналом — їх закриває окрема команда генерації `fix-doc-files`, а не загальний `fix`.
21
+
22
+ ## Публічний API
23
+
24
+ `run` — виконує перевірку правила і повертає код виходу (`0` — без зауважень, `1` — є порушення).
25
+ При прямому запуску файлу працює як повний еквівалент `npx @nitra/cursor fix doc-files` із
26
+ завантаженням конфігу та підсумком.
27
+
28
+ ## Гарантії поведінки
29
+
30
+ - Серіалізується спільним локом, тож паралельні запуски того самого правила дедуплікуються.
31
+ - Не виконує генерацію документації — лише структурну перевірку.
@@ -0,0 +1,19 @@
1
+ import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
2
+ import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
3
+
4
+ /**
5
+ * Запускає правило doc-files: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
6
+ * Структурні concerns (наявність workflow lint-doc-files.yml, скрипт у package.json) закриває
7
+ * policy-канал; контентні порушення (відсутні/застарілі доки) — поза `n-cursor fix`, їх закриває
8
+ * `fix-doc-files` (генерація). Library mode: викликається через `import + run(ctx)`.
9
+ * @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону
10
+ * @returns {Promise<number>} 0 — OK, 1 — порушення
11
+ */
12
+ export function run(ctx) {
13
+ return runStandardRule(import.meta.dirname, ctx)
14
+ }
15
+
16
+ if (isRunAsCli(import.meta.url)) {
17
+ // Standalone: bun rules/doc-files/fix.mjs — еквівалент `npx @nitra/cursor fix doc-files`.
18
+ process.exitCode = await runRuleCli(import.meta.dirname)
19
+ }
@@ -213,26 +213,32 @@ function extractMarkers(src) {
213
213
 
214
214
  // ── Rust-екстрактор ──────────────────────────────────────────────────────────
215
215
 
216
- // Модульний //! doc-коментар (inner doc)
217
- const RS_MODULE_DOC_RE = /^(?:[ \t]*\/\/![ \t]?(.*)\n)*/m
218
-
219
216
  // pub fn / pub struct / pub enum / pub trait (та fn із exposure-атрибутом)
220
- const RS_PUB_ITEM_RE = /^[ \t]*(pub(?:\([^)]*\))?\s+)?(?:async\s+)?(?:unsafe\s+)?(fn|struct|enum|trait|type)\s+(\w+)/gm
217
+ // матчаться у два кроки по trim-нутому рядку — прості регекспи без бектрекінгу:
218
+ // спершу опційний pub(...)-префікс, потім сама декларація
219
+ const RS_PUB_PREFIX_RE = /^pub(?:\([^)]*\))?\s+/
220
+ const RS_ITEM_DECL_RE = /^(?:async\s+)?(?:unsafe\s+)?(fn|struct|enum|trait|type)\s+(\w+)/
221
+
222
+ // fn-декларація у trim-нутому рядку одразу після exposure-атрибута
223
+ const RS_FN_AFTER_ATTR_RE = /^(?:pub\s+)?(?:async\s+)?(?:unsafe\s+)?fn\s+/
224
+
225
+ // Будь-яка fn-декларація без pub (для приватних localSymbols)
226
+ const RS_PRIVATE_FN_RE = /^[ \t]*(?:async\s+)?(?:unsafe\s+)?fn\s+(\w+)/
221
227
 
222
228
  // Exposure-атрибути (#[tauri::command] тощо)
223
229
  const RS_EXPOSURE_ATTR_RE = /#\[(?:tauri::command|wasm_bindgen|uniffi::export|pyo3::pyfunction|napi)/gm
224
230
 
225
- // /// line-doc перед елементом
226
- const RS_LINE_DOC_RE = /(?:[ \t]*\/\/\/[ \t]?.*\n)*/
227
-
228
231
  // use crate::module::{A, B} або use std::..;
229
232
  const RS_USE_RE = /^[ \t]*use\s+([\w:]+(?:::\{[^}]+\})?(?:::\*)?(?:::\w+)?)\s*;/gm
230
233
 
231
234
  // Файловий запис: fs::write / File::create / remove_file / create_dir / write_all
232
235
  const RS_WRITE_RE = /fs::write|File::create|remove_file|create_dir|BufWriter::new|OpenOptions[^;]*\.write\s*\(\s*true/
233
236
 
234
- // Обробка помилок (але не просто `?`)
235
- const RS_CATCH_RE = /\.unwrap_or(?:_else|_default)?|if\s+let\s+Err\s*\(|match\s+\S+.*\{\s*[\s\S]*?Err\s*\(|\.map_err\s*\(|\.ok\s*\(\)/
237
+ // Обробка помилок (але не просто `?`): прості маркери; випадок
238
+ // «match з Err(-гілкою» — віконним обходом рядків у rsHasMatchWithErrArm
239
+ const RS_CATCH_SIMPLE_RES = [/\.unwrap_or(?:_else|_default)?/, /if\s+let\s+Err\s*\(/, /\.map_err\s*\(/, /\.ok\s*\(\)/]
240
+ const RS_MATCH_KW_RE = /\bmatch\s/
241
+ const RS_ERR_ARM_RE = /\bErr\s*\(/
236
242
 
237
243
  // Функції, що повертають Result або Option
238
244
  const RS_RESULT_RE = /->\s*(?:Result|Option)\s*</
@@ -243,6 +249,21 @@ const RS_NETWORK_RE = /reqwest|hyper::|TcpStream|UdpSocket|tokio::net/
243
249
  // Кешування
244
250
  const RS_CACHE_RE = /\bcache\b|\bCache\b|lazy_static!|OnceCell|OnceLock|DashMap/i
245
251
 
252
+ /**
253
+ * Чи містить джерело `match`-вираз із `Err(`-гілкою неподалік (вікно 12 рядків).
254
+ * Замінює бектрекінг-вразливу регулярку детермінованим обходом рядків.
255
+ * @param {string[]} srcLines рядки файлу
256
+ * @returns {boolean} true, якщо за `match` слідує `Err(`
257
+ */
258
+ function rsHasMatchWithErrArm(srcLines) {
259
+ for (let i = 0; i < srcLines.length; i++) {
260
+ if (!RS_MATCH_KW_RE.test(srcLines[i])) continue
261
+ const end = Math.min(i + 12, srcLines.length)
262
+ for (let j = i; j < end; j++) if (RS_ERR_ARM_RE.test(srcLines[j])) return true
263
+ }
264
+ return false
265
+ }
266
+
246
267
  /**
247
268
  * Видобуває `///` doc-рядки перед рядком `lineIdx` (назад через `#[...]` та пусті рядки).
248
269
  * @param {string[]} lines рядки файлу
@@ -254,8 +275,9 @@ function rsDocBefore(lines, lineIdx) {
254
275
  for (let i = lineIdx - 1; i >= 0; i--) {
255
276
  const t = lines[i].trim()
256
277
  if (t.startsWith('///')) doc.unshift(t.slice(3).trim())
257
- else if (t.startsWith('#[') || t.startsWith('#![') || t === '') { /* skip */ }
258
- else break
278
+ else if (t.startsWith('#[') || t.startsWith('#![') || t === '') {
279
+ /* skip */
280
+ } else break
259
281
  }
260
282
  return doc.join(' ').trim()
261
283
  }
@@ -289,7 +311,7 @@ function extractFactsRust(src, relPath) {
289
311
  for (let nli = li + 1; nli < Math.min(li + 5, srcLines.length); nli++) {
290
312
  const t = srcLines[nli].trim()
291
313
  if (t.startsWith('#[') || t === '') continue
292
- if (/^(?:pub\s+)?(?:async\s+)?(?:unsafe\s+)?fn\s+/.test(t)) exposedLineSet.add(nli)
314
+ if (RS_FN_AFTER_ATTR_RE.test(t)) exposedLineSet.add(nli)
293
315
  break
294
316
  }
295
317
  break
@@ -303,12 +325,14 @@ function extractFactsRust(src, relPath) {
303
325
  let lineOffset = 0
304
326
  for (let li = 0; li < srcLines.length; li++) {
305
327
  const line = srcLines[li]
306
- const m = line.match(/^[ \t]*(pub(?:\([^)]*\))?\s+)?(?:async\s+)?(?:unsafe\s+)?(fn|struct|enum|trait|type)\s+(\w+)/)
328
+ const trimmed = line.trimStart()
329
+ const pubM = trimmed.match(RS_PUB_PREFIX_RE)
330
+ const m = (pubM ? trimmed.slice(pubM[0].length) : trimmed).match(RS_ITEM_DECL_RE)
307
331
  if (m) {
308
- const isPub = Boolean(m[1]) || exposedLineSet.has(li)
332
+ const isPub = Boolean(pubM) || exposedLineSet.has(li)
309
333
  if (isPub) {
310
334
  const desc = rsDocBefore(srcLines, li)
311
- exports.push({ name: m[3], kind: m[2], desc })
335
+ exports.push({ name: m[2], kind: m[1], desc })
312
336
  }
313
337
  }
314
338
  lineOffset += line.length + 1
@@ -316,9 +340,8 @@ function extractFactsRust(src, relPath) {
316
340
 
317
341
  // localSymbols — приватні fn (не pub і не exposed) — не документуємо як публічний API
318
342
  const localSymbols = []
319
- for (let li = 0; li < srcLines.length; li++) {
320
- const line = srcLines[li]
321
- const m = line.match(/^[ \t]*(?:async\s+)?(?:unsafe\s+)?fn\s+(\w+)/)
343
+ for (const line of srcLines) {
344
+ const m = line.match(RS_PRIVATE_FN_RE)
322
345
  if (m && !exports.some(e => e.name === m[1])) localSymbols.push(m[1])
323
346
  }
324
347
 
@@ -336,7 +359,7 @@ function extractFactsRust(src, relPath) {
336
359
  // markers
337
360
  const markers = {
338
361
  readOnly: !RS_WRITE_RE.test(src),
339
- catchesErrors: RS_CATCH_RE.test(src),
362
+ catchesErrors: RS_CATCH_SIMPLE_RES.some(re => re.test(src)) || rsHasMatchWithErrArm(srcLines),
340
363
  returnsFalsyOnFail: RS_RESULT_RE.test(src),
341
364
  network: RS_NETWORK_RE.test(src),
342
365
  caches: RS_CACHE_RE.test(src),
@@ -18,7 +18,8 @@ export const DOCGEN_IGNORE_GLOBS = Object.freeze([
18
18
  '**/demo/**',
19
19
  '**/docs/**',
20
20
  'npm/reports/**',
21
- 'npm/bin/**'
21
+ 'npm/bin/**',
22
+ 'npm/rules/k8s/js/manifests.mjs'
22
23
  ])
23
24
 
24
25
  const IGNORE_MATCHERS = DOCGEN_IGNORE_GLOBS.map(glob => picomatch(glob, { dot: true }))
@@ -265,8 +265,16 @@ export async function runDocFilesCheckCli(argv) {
265
265
  } else if (gitMode) {
266
266
  sources = gitChangedSources(root)
267
267
  } else {
268
+ // Значення прапорців виключаємо за індексом: порівняння за значенням при
269
+ // відсутньому `--max` (maxIdx = -1) викидало argv[0] — перший шлях губився
270
+ const flagValueIdxs = new Set(
271
+ ['--max', '--root']
272
+ .map(f => argv.indexOf(f))
273
+ .filter(i => i !== -1)
274
+ .map(i => i + 1)
275
+ )
268
276
  sources = argv
269
- .filter(a => !a.startsWith('--') && a !== argv[maxIdx + 1])
277
+ .filter((a, i) => !a.startsWith('--') && !flagValueIdxs.has(i))
270
278
  .map(a => toRelSource(root, a))
271
279
  .filter(rel => rel && isDocCandidate(root, rel) && existsSync(join(root, rel)))
272
280
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  docgen:
3
- source: npm/skills/doc-files/js/docgen-crc.mjs
3
+ source: npm/rules/doc-files/js/docgen-crc.mjs
4
4
  crc: 54e8e12b
5
5
  ---
6
6
 
@@ -0,0 +1,45 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/doc-files/js/docgen-extract-anchors.mjs
4
+ crc: 49749e9c
5
+ score: 80
6
+ ---
7
+
8
+ # docgen-extract-anchors.mjs
9
+
10
+ ## Огляд
11
+
12
+ Витягує анкори з вихідного коду файлу.
13
+
14
+ Витягує анкори з вихідного коду файлу.
15
+
16
+ Формує плоский список анкор-токенів для перевірки покриття.
17
+
18
+ Форматує анкори у компактний текст для system-промпта.
19
+
20
+ ## Поведінка
21
+
22
+ X
23
+ Витягує анкори з вихідного коду файлу
24
+
25
+ extractAnchors
26
+ Витягує анкори з вихідного коду файлу
27
+
28
+ anchorTokens
29
+ Формує плоский список анкор-токенів для перевірки покриття
30
+
31
+ anchorsToPrompt
32
+ Форматує анкори у компактний текст для system-промпта
33
+
34
+ ## Публічний API
35
+
36
+ X — витягує анкори з вихідного коду файлу.
37
+ extractAnchors — витягує анкори з вихідного коду файлу.
38
+ anchorTokens — плоский список анкор-токенів, які мають з'явитися в документі.
39
+ anchorsToPrompt — форматує анкори у компактний текст для system-промпта.
40
+
41
+ ## Гарантії поведінки
42
+
43
+ - Read-only: файл не виконує операцій запису у файлову систему.
44
+ - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
45
+ - Не звертається до мережі.
@@ -0,0 +1,39 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/doc-files/js/docgen-extract.mjs
4
+ crc: e790ff64
5
+ score: 100
6
+ ---
7
+
8
+ # docgen-extract.mjs
9
+
10
+ ## Огляд
11
+
12
+ Файл витягує факти про конфігурацію та структуру проекту. Визначає мову та заголовок файлу. Витягує публічні експорти та імпорти з різних джерел. Витягує внутрішні та локальні символи. Документація перевіряє наявність операцій запису, обробки помилок, повернення хибних значень при невдачах, мережевих викликів, механізмів кешування та пропуск певних шляхів.
13
+
14
+ ## Поведінка
15
+
16
+ 1. Витягується факт про файл.
17
+ 2. Визначається мова файлу.
18
+ 3. Витягується заголовок файлу.
19
+ 4. Витягуються публічні експорти.
20
+ 5. Витягуються імпорти, класифіковані за джерелом.
21
+ 6. Витягуються внутрішні символи, імпортовані з внутрішніх модулів.
22
+ 7. Витягуються локальні символи, неекспортовані функції.
23
+ 8. Визначаються евристичні маркери.
24
+ * readOnly: перевірка на наявність операцій запису.
25
+ * catchesErrors: перевірка на наявність обробки помилок.
26
+ * returnsFalsyOnFail: перевірка на повернення хибних значень при невдачах.
27
+ * network: перевірка на наявність мережевих викликів.
28
+ * caches: перевірка на наявність механізмів кешування.
29
+ * skips: пропуск шляхів .github, .git, node_modules, base/, ua/, .firebase.
30
+
31
+ ## Публічний API
32
+
33
+ extractFacts — код файлу перетворює на список фактів
34
+
35
+ ## Гарантії поведінки
36
+
37
+ - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
38
+ - Кешує результати в межах одного прогону.
39
+ - Свідомо пропускає шляхи: `.github`, `.git`, `node_modules`, `base/`, `ua/`, `.firebase`.