@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,176 +1,28 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/js-bun-redis/js/imports.mjs
4
+ crc: 678c233c
5
+ score: 100
6
+ ---
7
+
1
8
  # imports.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль реалізує AST/текстову перевірку правила `js-bun-redis.mdc` для JavaScript/TypeScript-джерел проєкту. Його завдання гарантувати, що в усіх JS/TS-файлах репозиторію відсутні заборонені статичні чи динамічні імпорти (а також CommonJS `require`) Redis-клієнтів `ioredis`, `node-redis`, `redis` і підпакетів `@redis/*` / підшляхів `ioredis/...` / `redis/...`. Замість них код повинен використовувати Bun native Redis API: `import { redis } from 'bun'` (див. <https://bun.com/docs/runtime/redis>).
6
-
7
- Модуль експортує одну головну функцію `check()`, яка:
8
-
9
- 1. Перевіряє наявність `package.json` у корені репозиторію (інакше перевірка пропускається як неактуальна).
10
- 2. Завантажує список ігнорованих шляхів через cursor-конфіг.
11
- 3. Обходить дерево репозиторію, збираючи JS/TS-джерела, придатні для скану.
12
- 4. Сканує кожне зібране джерело шукачем заборонених імпортів і генерує звіт через стандартний check-reporter.
13
-
14
- Перевірка `package.json` (заборона залежностей `ioredis` / `node-redis` / `redis` / `@redis/*`) реалізована окремо — у Rego-полісі `npm/policy/js_bun_redis/package_json/`, яку запускає `npx @nitra/cursor check`. Поточний файл відповідає виключно за AST/текстовий скан коду.
15
-
16
- ## Експорти / API
17
-
18
- | Експорт | Тип | Призначення |
19
- | ------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
20
- | `check` | `async function(): Promise<number>` | Головна точка входу check-скрипта правила `js-bun-redis`. Повертає код виходу: `0` — порушень немає, `1` — є порушення або є інша помилка, зафіксована репортером. |
21
-
22
- Інші функції (`findAllSourcePathsForRedisScan`, `scanSourcesForRedisImports`) є приватними допоміжними і не експортуються.
23
-
24
- ## Функції
25
-
26
- ### `findAllSourcePathsForRedisScan(repoRoot, ignorePaths)`
27
-
28
- Збирає список абсолютних шляхів JS/TS-джерел, які треба просканувати на заборонені redis-імпорти.
29
-
30
- - Сигнатура: `async function findAllSourcePathsForRedisScan(repoRoot: string, ignorePaths: string[]): Promise<string[]>`
31
- - Параметри:
32
- - `repoRoot` — абсолютний шлях до кореня репозиторію, від якого формуються відносні шляхи.
33
- - `ignorePaths` — масив абсолютних шляхів каталогів, повністю виключених з обходу `walkDir`.
34
- - Повертає: `Promise<string[]>` — абсолютні шляхи знайдених файлів, відсортовані за їх відносним шляхом (локалекомпаратор за `relative(repoRoot, ...)`).
35
- - Поведінка / логіка:
36
- 1. Створює локальний масив `paths`.
37
- 2. Викликає `walkDir(repoRoot, callback, ignorePaths)`. Для кожного абсолютного шляху callback:
38
- - Будує відносний шлях `relative(repoRoot, absPath)` і нормалізує сепаратори (Windows `\\` → `/`).
39
- - Якщо `isRedisScanSourceFile(rel)` повертає `true` (тобто це JS/TS-подібне джерело, цільове для скану) і `shouldSkipFileForRedisScan(rel)` повертає `false` — додає `absPath` у `paths`.
40
- 3. Сортує `paths` за відносним шляхом через `String.prototype.localeCompare`.
41
- - Side effects: лише читання структури директорій через `walkDir` (синхронні чи асинхронні `stat`/`readdir` за реалізацією утиліти). Файли не читаються на цьому етапі.
42
-
43
- ### `scanSourcesForRedisImports(sourcePaths, repoRoot, fail)`
44
-
45
- Сканує текстовий вміст кожного з переданих файлів на заборонені redis-імпорти та звітує про порушення.
46
-
47
- - Сигнатура: `async function scanSourcesForRedisImports(sourcePaths: string[], repoRoot: string, fail: (msg: string) => void): Promise<number>`
48
- - Параметри:
49
- - `sourcePaths` — абсолютні шляхи джерел, отримані з `findAllSourcePathsForRedisScan`.
50
- - `repoRoot` — абсолютний шлях до кореня репозиторію (для нормалізації відносного шляху у повідомленнях).
51
- - `fail` — callback репортера, який треба викликати з повідомленням про кожне порушення; саме він контролює exitCode.
52
- - Повертає: `Promise<number>` — загальну кількість виявлених порушень (`violations`).
53
- - Поведінка / логіка:
54
- 1. Ініціалізує лічильник `violations = 0`.
55
- 2. Для кожного `absPath` зі `sourcePaths`:
56
- - Обчислює `rel = relative(repoRoot, absPath)` з нормалізацією `\\` → `/`.
57
- - Читає файл `await readFile(absPath, 'utf8')`.
58
- - Викликає `findRedisImportsInText(content, rel)` і ітерує його результат `v` (об’єкти з полями `line`, `module`, `snippet`).
59
- - Для кожного `v` інкрементує `violations` і викликає `fail(...)` з форматованим повідомленням:
60
- `js-bun-redis: <rel>:<line> — заміни '<module>' на Bun native Redis (import { redis } from 'bun', https://bun.com/docs/runtime/redis): <snippet>`.
61
- 3. Повертає підсумкову `violations`.
62
- - Side effects:
63
- - Читання файлів з диска (`readFile`) — потенційно великий I/O залежно від розміру репозиторію.
64
- - Виклик `fail` має побічний ефект: змінює внутрішній стан репортера так, що його `getExitCode()` поверне ненульовий код.
65
-
66
- ### `check()` (експортована)
67
-
68
- Головна точка входу check-скрипта правила `js-bun-redis`.
69
-
70
- - Сигнатура: `export async function check(): Promise<number>`
71
- - Параметри: відсутні. Робочий каталог визначається через `process.cwd()`.
72
- - Повертає: `Promise<number>` — фінальний код виходу: `0` — все гаразд, `1` (або інший ненульовий за реалізацією репортера) — є порушення або інші зафіксовані помилки.
73
- - Поведінка / логіка:
74
- 1. Створює репортер `reporter = createCheckReporter()` і деструктурує з нього `pass`, `fail`.
75
- 2. Визначає `repoRoot = process.cwd()`.
76
- 3. Перевіряє наявність `package.json`: якщо `existsSync(join(repoRoot, 'package.json'))` повертає `false` — викликає `pass('js-bun-redis: package.json у корені відсутній — перевірку пропущено')` і повертає `reporter.getExitCode()` (рання гілка).
77
- 4. Завантажує `ignorePaths` через `await loadCursorIgnorePaths(repoRoot)`.
78
- 5. Збирає `sourcePaths = await findAllSourcePathsForRedisScan(repoRoot, ignorePaths)`.
79
- 6. Якщо `sourcePaths.length === 0` — викликає `pass('js-bun-redis: немає JS/TS файлів для скану імпортів ioredis / node-redis / redis')` і повертає `reporter.getExitCode()`.
80
- 7. Інакше викликає `violations = await scanSourcesForRedisImports(sourcePaths, repoRoot, fail)`.
81
- 8. Якщо `violations === 0` — викликає `pass('js-bun-redis: немає імпортів \'ioredis\' / \'node-redis\' / \'redis\' / \'@redis/*\' у джерелах (використовується Bun native Redis або redis взагалі не задіяно)')`.
82
- 9. Повертає `reporter.getExitCode()`.
83
- - Side effects:
84
- - Читання файлової системи (`existsSync`, `walkDir`, `readFile`).
85
- - Виведення повідомлень через репортер (через `pass`/`fail` — у консоль або інше призначене місце, що визначається реалізацією `createCheckReporter`).
86
- - Залежить від поточного робочого каталогу процесу (`process.cwd()`).
87
-
88
- ## Залежності
89
-
90
- ### Зовнішні (node:\* / runtime)
91
-
92
- - `node:fs`
93
- - `existsSync` — синхронна перевірка наявності `package.json` у корені.
94
- - `node:fs/promises`
95
- - `readFile` — асинхронне читання вмісту кожного JS/TS-файлу у кодуванні `utf8`.
96
- - `node:path`
97
- - `join` — побудова шляху до `package.json`.
98
- - `relative` — обчислення відносних шляхів для логування та сортування.
99
-
100
- ### Внутрішні (проєктні)
101
-
102
- - `../../../scripts/lib/check-reporter.mjs`
103
- - `createCheckReporter` — фабрика стандартного репортера для check-скриптів правил. Дає API `{ pass, fail, getExitCode }`.
104
- - `../../../scripts/lib/load-cursor-config.mjs`
105
- - `loadCursorIgnorePaths` — завантажує абсолютні шляхи, які слід виключити з обходу (з cursor-конфігу/ignore-файлів).
106
- - `../lib/redis-imports.mjs`
107
- - `findRedisImportsInText(text, relPath)` — шукає у тексті заборонені redis-імпорти/`require`/динамічні `import()`; повертає масив порушень з полями `line`, `module`, `snippet`.
108
- - `isRedisScanSourceFile(relPath)` — предикат: чи цей відносний шлях належить до набору JS/TS-джерел, придатних для скану.
109
- - `shouldSkipFileForRedisScan(relPath)` — предикат: чи слід пропустити конкретний файл (наприклад, тестові фікстури, генеровані файли тощо).
110
- - `../../../scripts/utils/walkDir.mjs`
111
- - `walkDir(rootAbs, visit, ignorePaths)` — асинхронний обхід директорії з викликом `visit(absPath)` для кожного файлу та пропуском заданих `ignorePaths`.
112
-
113
- ## Потік виконання / Використання
114
-
115
- Файл є частиною інфраструктури check-скриптів правил Cursor для проєкту. Очікувано він викликається оркестратором, який імпортує `check` із цього модуля і запускає її з робочою директорією, що дорівнює кореню репозиторію.
116
-
117
- Узагальнений потік виконання `check()`:
118
-
119
- 1. Інстанціювання репортера `createCheckReporter()`.
120
- 2. Гілка раннього виходу: відсутній кореневий `package.json` → `pass(...)` → `return reporter.getExitCode()`.
121
- 3. Завантаження `ignorePaths` через `loadCursorIgnorePaths(repoRoot)`.
122
- 4. Збір кандидатів через `findAllSourcePathsForRedisScan(repoRoot, ignorePaths)`:
123
- - Обхід `walkDir` з відсіюванням за `isRedisScanSourceFile` і `shouldSkipFileForRedisScan`.
124
- - Детермінований порядок через `localeCompare` за відносним шляхом.
125
- 5. Гілка раннього виходу: порожній список кандидатів → `pass(...)` → `return reporter.getExitCode()`.
126
- 6. Скан кожного джерела через `scanSourcesForRedisImports`:
127
- - Читання `readFile(..., 'utf8')`.
128
- - Виклик `findRedisImportsInText(content, rel)`.
129
- - На кожне порушення — `fail('js-bun-redis: <rel>:<line> — заміни \'<module>\' на Bun native Redis (...): <snippet>')` та `violations++`.
130
- 7. Якщо `violations === 0` — повідомлення про успіх через `pass(...)`.
131
- 8. Фінальне повернення `reporter.getExitCode()`:
132
- - `0` — лише `pass`/нуль порушень.
133
- - Ненульове значення — щонайменше один `fail`.
134
-
135
- Приклад типового підключення з оркестратора правил (схематично):
136
-
137
- ```js
138
- import { check } from './imports.mjs'
139
-
140
- const code = await check()
141
- process.exit(code)
142
- ```
12
+ Файл виконує збір та перевірку джерел коду. Він завантажує конфігурації пропущених шляхів з `package.json`, збирає абсолютні шляхи джерел та перевіряє їх на наявність заборонених імпортів пакетів. Перевірка проводиться відповідно до правила, визначеного у https://bun.com/docs/runtime/redis.
143
13
 
144
- Команда `npx @nitra/cursor check` запускає цей скрипт у пайплайні разом із Rego-полісом `npm/policy/js_bun_redis/package_json/`, який перевіряє відсутність заборонених redis-пакетів у `dependencies`/`devDependencies`/`peerDependencies` будь-якого `package.json` у репозиторії. Цей файл доповнює полісі рівнем скану реальних імпортів у коді, бо самих лише обмежень у `package.json` недостатньо: пакет може бути транзитивно встановлений або підвантажений з підшляху.
14
+ ## Поведінка
145
15
 
146
- Особливості та граничні випадки:
16
+ 1. Завантажити конфігурації пропущених шляхів з `package.json`
17
+ 2. Зібрати абсолютні шляхи JS/TS джерел у репозиторії
18
+ 3. Просканувати джерела на заборонені імпорти пакетів `ioredis` / `node-redis` / `redis`
19
+ 4. Перевірити відповідність проєкту правилу `js-bun-redis.mdc`
147
20
 
148
- - Шляхи нормалізуються до прямих слешів (`/`) перед тим як прогнатись через предикати, щоб логіка `isRedisScanSourceFile` / `shouldSkipFileForRedisScan` працювала однаково на Linux/macOS і Windows.
149
- - Сортування результатів `findAllSourcePathsForRedisScan` забезпечує стабільний детермінований порядок виводу повідомлень про порушення, що корисно для CI-діффів.
150
- - Якщо у файлі знайдено кілька порушень — кожне репортується окремим повідомленням, але сумарний `violations` повертається з усієї пробіжки.
151
- - `check()` свідомо не кидає винятків самостійно: усі помилки оформлюються як `fail(...)` для коректного коду виходу через `reporter.getExitCode()`. Винятки від `readFile`/`walkDir` будуть проксі через `await` і призведуть до rejected promise (це залишається на відповідальності оркестратора).
21
+ ## Публічний API
152
22
 
153
- ## Rebuild Test
23
+ check перевіряє відповідність проєкту правилу `js-bun-redis.mdc`.
154
24
 
155
- Якщо за цією документацією треба відновити модуль, він повинен:
25
+ ## Гарантії поведінки
156
26
 
157
- 1. Імпортувати з `node:fs` `existsSync`; з `node:fs/promises` `readFile`; з `node:path` — `join`, `relative`.
158
- 2. Імпортувати з `../../../scripts/lib/check-reporter.mjs` — `createCheckReporter`.
159
- 3. Імпортувати з `../../../scripts/lib/load-cursor-config.mjs` — `loadCursorIgnorePaths`.
160
- 4. Імпортувати з `../lib/redis-imports.mjs` — `findRedisImportsInText`, `isRedisScanSourceFile`, `shouldSkipFileForRedisScan`.
161
- 5. Імпортувати з `../../../scripts/utils/walkDir.mjs` — `walkDir`.
162
- 6. Оголосити приватну `findAllSourcePathsForRedisScan(repoRoot, ignorePaths)`, що:
163
- - обходить `walkDir(repoRoot, cb, ignorePaths)`;
164
- - усередині callback нормалізує `relative(repoRoot, absPath)` до прямих слешів, фільтрує через `isRedisScanSourceFile && !shouldSkipFileForRedisScan` і пушить у локальний масив;
165
- - сортує масив за `relative(repoRoot, x).localeCompare(...)`;
166
- - повертає його.
167
- 7. Оголосити приватну `scanSourcesForRedisImports(sourcePaths, repoRoot, fail)`, що:
168
- - ітерує `sourcePaths`, для кожного читає `readFile(..., 'utf8')`, нормалізує `rel`, прогоняє `findRedisImportsInText` і на кожне порушення інкрементує лічильник + викликає `fail(...)` з повідомленням формату `js-bun-redis: <rel>:<line> — заміни '<module>' на Bun native Redis (import { redis } from 'bun', https://bun.com/docs/runtime/redis): <snippet>`;
169
- - повертає кількість порушень.
170
- 8. Експортувати `async function check()`, що:
171
- - створює `reporter = createCheckReporter()`, бере `pass`/`fail` з нього;
172
- - якщо `package.json` у `process.cwd()` відсутній — `pass('... перевірку пропущено')` і повертає `reporter.getExitCode()`;
173
- - завантажує `ignorePaths` через `loadCursorIgnorePaths(repoRoot)`;
174
- - збирає `sourcePaths`, якщо порожньо — `pass('... немає JS/TS файлів для скану ...')` і вихід;
175
- - інакше викликає `scanSourcesForRedisImports`, на нуль порушень — `pass('... немає імпортів ioredis / node-redis / redis / @redis/* ...')`;
176
- - повертає `reporter.getExitCode()`.
27
+ - Read-only: файл не виконує операцій запису у файлову систему.
28
+ - Не звертається до мережі.
@@ -1,117 +1,39 @@
1
- # fix.mjs — точка входу правила `js-lint`
1
+ ---
2
+ docgen:
3
+ source: npm/rules/js-lint/fix.mjs
4
+ crc: 38cf876b
5
+ score: 90
6
+ ---
2
7
 
3
- ## Огляд
4
-
5
- Файл `npm/rules/js-lint/fix.mjs` — це тонкий ентрі-поінт (entry-point) правила з ідентифікатором `js-lint` для CLI `@nitra/cursor`. Він не містить власної логіки перевірок: уся механіка прогону правила інкапсульована у бібліотечних модулях `run-standard-rule.mjs` (стандартний пайплайн правил) та `run-rule-cli.mjs` (CLI-обгортка).
6
-
7
- Модуль виконує **подвійну роль**:
8
-
9
- 1. **Library mode** — експортує функцію `run(ctx)`, яку імпортують інші частини оркестратора правил. У цьому режимі правило виконується в межах єдиного процесу, отримує контекст (`ctx`) із кешем обходу файлової системи (`walkCache`) та інших спільних структур, і повертає exit-код як значення Promise.
10
- 2. **Standalone mode** — якщо файл запущено напряму як CLI (`bun rules/js-lint/fix.mjs`), виконується повноцінний CLI-цикл: завантаження конфігурації, застосування whitelist-фільтрів, виведення підсумків і завершення процесу з відповідним exit-кодом (повний еквівалент команди `npx @nitra/cursor fix js-lint`).
11
-
12
- Стандартний пайплайн, який стоїть за `runStandardRule`, складається з чотирьох послідовних фаз: `applies` (визначення цільових файлів) → `JS-concerns` (специфічні для правила перевірки/фікси) → `policy` (агрегування політик) → `mdc-refs` (узгодження з `.mdc`-метаописами правил).
13
-
14
- ## Експорти / API
15
-
16
- | Символ | Тип | Призначення |
17
- | ------ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
18
- | `run` | `function(ctx?): Promise<number>` | Library-API: запускає правило `js-lint` в межах поточного процесу, повертає exit-код (0 — OK, 1 — порушення). Експортується як іменований експорт через `export function run(ctx)`. |
19
-
20
- Default-експорт відсутній. Інших іменованих експортів немає.
21
-
22
- ## Функції
23
-
24
- ### `run(ctx)`
25
-
26
- ```js
27
- export function run(ctx)
28
- ```
29
-
30
- - **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
31
- - **Параметри:**
32
- - `ctx` (необовʼязковий) — обʼєкт контексту прогону правила типу `RuleContext` (визначений у `../../scripts/lib/run-standard-rule.mjs`). Зазвичай містить кешовані структури на кшталт `walkCache` (кеш обходу файлової системи), що дозволяє оркестратору перевикористовувати дані між послідовними правилами без повторного обходу диску. Якщо аргумент відсутній — кеші ініціалізуються всередині `runStandardRule`.
33
- - **Повертає:** `Promise<number>` — exit-код прогону правила:
34
- - `0` — правило не знайшло порушень або всі знайдені порушення були автоматично виправлені;
35
- - `1` — присутні порушення, які залишилися після фази fix (тобто потрібне ручне втручання або правило в режимі lint-only).
36
- - **Реалізація:** повертає результат виклику `runStandardRule(import.meta.dirname, ctx)`. Перший аргумент `import.meta.dirname` — абсолютний шлях до директорії, у якій лежить `fix.mjs` (тобто `.../npm/rules/js-lint`). Саме за цим шляхом `runStandardRule` знаходить решту артефактів правила (наприклад, `applies.mjs`, `policy.mjs`, `mdc`-довідники, та власне fix-логіку).
37
- - **Side effects:** делегуються до `runStandardRule`. Стандартно включають читання вихідних файлів проєкту, можливе перезаписування файлів коду під час фази fix, читання конфігурації правил, а також виведення прогресу/підсумків у stdout/stderr (залежить від конкретної реалізації стандартного пайплайна).
8
+ # fix.mjs
38
9
 
39
- ### Standalone-блок (top-level)
40
-
41
- ```js
42
- if (isRunAsCli(import.meta.url)) {
43
- process.exit(await runRuleCli(import.meta.dirname))
44
- }
45
- ```
46
-
47
- - **Сигнатура:** не є функцією — це top-level умовний блок, який виконується один раз при завантаженні модуля.
48
- - **Логіка:**
49
- 1. `isRunAsCli(import.meta.url)` визначає, чи файл запущено як головний модуль (через `bun fix.mjs` / `node fix.mjs`) або імпортовано як бібліотеку. Стандартна ідіома: порівнює `import.meta.url` із URL процесу запуску.
50
- 2. Якщо запуск standalone — виконується `await runRuleCli(import.meta.dirname)`, який повертає exit-код. Цей виклик інкапсулює CLI-обвʼязки: парсинг аргументів, завантаження користувацької/проєктної конфігурації, застосування whitelist (фільтра шляхів), виклик `run(ctx)` під капотом і друк фінального підсумку.
51
- 3. `process.exit(...)` гарантовано завершує процес із отриманим exit-кодом — це необхідно для коректної інтеграції з CI-системами та IDE, які орієнтуються на код виходу.
52
- - **Side effects:** завершення процесу Node/Bun. У standalone-режимі правило ніколи не повертає керування викликачу — замість return-у виконується `process.exit`.
53
- - **Зауваження по лінтерам:** перед викликом `process.exit` стоїть директива `// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE` — це свідомий виняток із загальної заборони на `process.exit` для standalone entry-point-ів.
54
-
55
- ## Залежності
56
-
57
- ### Внутрішні (модулі репозиторію)
58
-
59
- - `../../scripts/lib/run-rule-cli.mjs` — імпортуються:
60
- - `isRunAsCli` — детектор режиму запуску (CLI vs library).
61
- - `runRuleCli` — повноцінна CLI-обгортка для правила: парсинг аргументів, конфіг, whitelist, виклик `run`, друк summary; повертає `Promise<number>` (exit-код).
62
- - `../../scripts/lib/run-standard-rule.mjs` — імпортується:
63
- - `runStandardRule` — стандартний пайплайн правил у чотири фази (`applies` → `JS-concerns` → `policy` → `mdc-refs`), приймає шлях до директорії правила та опційний контекст; повертає `Promise<number>`.
64
- - Також звідси типізовано `RuleContext` (через JSDoc-тип `import('../../scripts/lib/run-standard-rule.mjs').RuleContext`).
65
-
66
- ### Зовнішні / runtime
67
-
68
- - `import.meta.dirname` — Node/Bun runtime API (стабільний з Node 20.11). Повертає абсолютний шлях до директорії модуля. Використовується як «адреса» правила для оркестратора.
69
- - `import.meta.url` — URL поточного модуля; передається у `isRunAsCli` для розрізнення CLI-запуску й import-режиму.
70
- - `process.exit` — Node/Bun global, термінує процес із заданим exit-кодом.
71
- - Top-level `await` — використовується для `await runRuleCli(...)`; вимагає ES-modules (`.mjs`) і середовища з підтримкою top-level await.
72
-
73
- Жодних npm-пакетів модуль напряму не імпортує.
74
-
75
- ## Потік виконання / Використання
76
-
77
- ### Сценарій 1: запуск як CLI (standalone)
78
-
79
- ```bash
80
- bun npm/rules/js-lint/fix.mjs
81
- # або еквівалент через головний CLI:
82
- npx @nitra/cursor fix js-lint
83
- ```
10
+ ## Огляд
84
11
 
85
- 1. ES-модуль завантажується, виконуються імпорти `isRunAsCli`, `runRuleCli`, `runStandardRule`.
86
- 2. Оголошується експорт `run` (але одразу не викликається).
87
- 3. Виконується top-level `if (isRunAsCli(import.meta.url))`. У standalone це `true`.
88
- 4. Викликається `await runRuleCli(import.meta.dirname)`:
89
- - читається конфігурація проєкту (whitelist, exclude, опції правил);
90
- - визначається область дії (які файли потрапляють у правило `js-lint`);
91
- - усередині викликається `run(ctx)` із підготовленим контекстом;
92
- - друкується підсумок (порушення, виправлення, час).
93
- 5. `process.exit(<код>)` завершує процес. CI-система отримує `0` (успіх) або `1` (є порушення).
12
+ Файл застосовує визначене правило до вхідного контексту. Виконання відбувається через оркестрацію CLI, яка використовує імпорт та функцію `run`. Для роботи у режимі standalone використовується `runRuleCli` для визначення коду виходу та виконує еквівалент команди `npx @nitra/cursor fix <id>`.
94
13
 
95
- ### Сценарій 2: виклик як бібліотеки (library mode)
14
+ ## Поведінка
96
15
 
97
- ```js
98
- import { run } from './npm/rules/js-lint/fix.mjs'
16
+ 1. Запуск правила.
17
+ * Приймає контекст прогону.
18
+ * Повертає результат прогону.
19
+ 2. Виконання правила.
20
+ * Викликає стандартне правило.
21
+ * Використовує директорію модуля для прогону.
22
+ 3. Режим бібліотеки.
23
+ * Викликається через оркестрацію CLI.
24
+ * Використовує імпорт та функцію `run`.
25
+ 4. Режим standalone.
26
+ * Викликається через CLI.
27
+ * Використовує `runRuleCli` для визначення коду виходу.
28
+ * Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
99
29
 
100
- const ctx = { walkCache: /* спільний кеш */, /* ... */ }
101
- const exitCode = await run(ctx)
102
- if (exitCode !== 0) {
103
- // обробка порушень: повторний прогін, escalation у CI тощо
104
- }
105
- ```
30
+ ## Публічний API
106
31
 
107
- 1. Сторонній модуль (зазвичай головний оркестратор `@nitra/cursor`) імпортує `run`.
108
- 2. `isRunAsCli(import.meta.url)` для `fix.mjs` поверне `false` (бо `import.meta.url` модуля не збігається з URL процесу) — standalone-блок не виконується, `process.exit` не викликається.
109
- 3. Викликач передає у `run(ctx)` готовий контекст із попередньо побудованими кешами.
110
- 4. `run` делегує у `runStandardRule(import.meta.dirname, ctx)`, який виконує чотирифазний пайплайн правила і повертає exit-код.
111
- 5. Викликач сам вирішує, що робити з кодом (агрегувати з іншими правилами, ескалувати, друкувати тощо). Завершення процесу — на боці викликача.
32
+ run запускає правило: applies JS-concerns policy → mdc-refs (через runStandardRule).
33
+ Library mode викликається CLI orchestration через `import + run`.
112
34
 
113
- ### Інтеграція в загальну архітектуру правил
35
+ ## Гарантії поведінки
114
36
 
115
- - Кожне правило в каталозі `npm/rules/<id>/` має власний `fix.mjs` за **однаковим шаблоном**: експортує `run(ctx)`, що делегує у `runStandardRule(import.meta.dirname, ctx)`, плюс standalone-блок із `runRuleCli`. Конкретні перевірки/фікси правила лежать у сусідніх файлах директорії (`applies.mjs`, `policy.mjs`, `check-*.mjs` тощо) і автоматично підхоплюються стандартним пайплайном за конвенцією шляхів.
116
- - Для правила `js-lint` стандартний пайплайн виконує: відбір JS/TS/Vue-файлів (фаза `applies`) → специфічні JS-перевірки (фаза `JS-concerns`, реалізована в інших файлах цієї ж директорії) → агрегування політик (`policy`) → крос-перевірку з `.mdc`-описом правила (`mdc-refs`).
117
- - Контракт «`fix.mjs` = тонка обгортка» уніфікує всі правила: уся складність захована за `runStandardRule` і `runRuleCli`. Завдяки цьому файл `fix.mjs` будь-якого правила залишається маленьким (одиниці рядків коду) і легко піддається ревʼю/документації.
37
+ - Read-only: файл не виконує операцій запису у файлову систему.
38
+ - Кешує результати в межах одного прогону.
39
+ - Не звертається до мережі.
@@ -1,30 +1,50 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/js-lint/js/lint-findings.mjs
4
+ crc: bee587da
5
+ score: 100
6
+ ---
7
+
1
8
  # lint-findings.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Цей файл обробляє результати аналізу коду, отримані з інструментів oXlint та eslint, для визначення, чи є знайдені проблеми нові (в diff) чи існують у файлі з самого початку. Він класифікує ці результати, надаючи інформацію про файл та рядок, де проблема виявлена, що допомагає у відстеженні та вирішенні помилок. Це частина системи беклогу #6, яка автоматизує процес класифікації lint-findings.
12
+ parseOxlint
13
+ Парсить текст у вивід oxlint
14
+
15
+ parseEslint
16
+ Парсить текст у вивід eslint
17
+
18
+ classifyFindings
19
+ Розділяє findings на introduced та preExisting
20
+
21
+ renderFindings
22
+ Форматує та рендерить звіт про findings
6
23
 
7
24
  ## Поведінка
8
25
 
9
- parseOxlint: аналізує JSON-вихід `oxlint --format=json` та повертає список findings з інформацією про файл, рядок, правило та повідомлення.
10
- parseEslint: аналізує JSON-вихід `eslint --format=json` та повертає список findings з інформацією про файл, рядок, правило та повідомлення.
11
- classifyFindings: класифікує findings як introduced або pre-existing на основі доданих рядків, використовуючи Map.
12
- renderFindings: генерує текстовий звіт з розділенням findings на introduced та pre-existing, використовуючи формат `🆕 introduced` та `🗄 pre-existing`.
26
+ parseOxlint
27
+ Парсить текст у вивід oxlint
28
+
29
+ parseEslint
30
+ Парсить текст у вивід eslint
31
+
32
+ classifyFindings
33
+ Розділяє findings на introduced та preExisting
34
+
35
+ renderFindings
36
+ Форматує та рендерить звіт про findings
13
37
 
14
38
  ## Публічний API
15
39
 
16
- - parseOxlint — Перетворює JSON з результатів інструменту Oxlint на внутрішній об'єкт.
17
- - parseEslint — Перетворює JSON з результатів інструменту ESLint на внутрішній об'єкт.
18
- - classifyFindings — Розподіляє знайдені проблеми на нові (introduced) та існуючі (pre-existing).
19
- - renderFindings — Створює звіт, об'єднуючи нові та існуючі проблеми.
40
+ parseOxlint — перетворює JSON у дані або повертає null при невдалій обробці.
41
+ parseEslint — перетворює JSON у дані або повертає null при невдалій обробці.
42
+ classifyFindings — групує знайдені проблеми на категорії доданих/існуючих.
43
+ renderFindings — формує звіт, який включає виправлені проблеми та застарілі проблеми.
20
44
 
21
45
  ## Гарантії поведінки
22
46
 
23
- - Функція `parseOxlint` повертає JSON-об'єкт, що містить список діагностик, або `null` у разі помилки парсингу.
24
- - Функція `parseEslint` повертає масив об'єктів, що містять повідомлення про помилки, або `null` у разі помилки парсингу.
25
- - Функція `classifyFindings` повертає масив об'єктів, що представляють класифіковані результати, або `null` у разі помилки класифікації.
26
- - Функція `renderFindings` повертає рядок, що містить представлення результатів, або `null` у разі помилки рендерингу.
27
- - У разі невдачі будь-якої з функцій, повертається `false`.
28
- - Функції не кидають винятків.
29
- - Шляхи файлів, що передаються вхідним функціям, є абсолютними.
30
- - Результати функцій не кешуються.
47
+ - Read-only: файл не виконує операцій запису у файлову систему.
48
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
49
+ - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
50
+ - Не звертається до мережі.