@nitra/cursor 3.22.0 → 3.23.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 (228) hide show
  1. package/.pi-template/extensions/n-cursor-adr/docs/index.md +181 -0
  2. package/CHANGELOG.md +31 -3
  3. package/bin/docs/n-cursor.md +636 -0
  4. package/bin/docs/rename-yaml-extensions.md +207 -0
  5. package/bin/n-cursor.js +30 -3
  6. package/package.json +1 -1
  7. package/rules/abie/docs/fix.md +18 -0
  8. package/rules/abie/js/docs/applies.md +26 -0
  9. package/rules/abie/js/docs/env_dns.md +32 -0
  10. package/rules/abie/js/docs/firebase_hosting.md +23 -0
  11. package/rules/abie/js/docs/hc_pairing.md +35 -0
  12. package/rules/abie/js/docs/ua_http_route.md +28 -0
  13. package/rules/abie/js/docs/ua_node_selector.md +28 -0
  14. package/rules/abie/lib/docs/enabled.md +29 -0
  15. package/rules/abie/lib/docs/env-dns.md +35 -0
  16. package/rules/abie/lib/docs/hc-yaml.md +33 -0
  17. package/rules/abie/lib/docs/http-route.md +44 -0
  18. package/rules/abie/lib/docs/k8s-tree.md +40 -0
  19. package/rules/abie/lib/docs/kustomization-patches.md +47 -0
  20. package/rules/abie/lib/docs/overlay-paths.md +38 -0
  21. package/rules/abie/lib/docs/yaml.md +29 -0
  22. package/rules/adr/docs/fix.md +148 -0
  23. package/rules/adr/js/docs/hooks.md +259 -0
  24. package/rules/bun/docs/fix.md +156 -0
  25. package/rules/bun/js/docs/layout.md +393 -0
  26. package/rules/capacitor/docs/fix.md +121 -0
  27. package/rules/capacitor/js/docs/platforms.md +295 -0
  28. package/rules/changelog/changelog.mdc +2 -2
  29. package/rules/changelog/docs/fix.md +174 -0
  30. package/rules/changelog/js/consistency.mjs +114 -13
  31. package/rules/changelog/js/docs/consistency.md +387 -0
  32. package/rules/changelog/lib/docs/package-manifest.md +210 -0
  33. package/rules/ci4/docs/fix.md +179 -0
  34. package/rules/ci4/js/docs/marksman_config.md +128 -0
  35. package/rules/docker/docker.mdc +8 -3
  36. package/rules/docker/docs/fix.md +171 -0
  37. package/rules/docker/js/docs/lint.md +258 -0
  38. package/rules/docker/lib/docs/docker-hadolint.md +184 -0
  39. package/rules/docker/lib/docs/docker-mirror.md +247 -0
  40. package/rules/docker/lib/docs/docker-native-addon.md +170 -0
  41. package/rules/docker/lib/docs/docker-nginx-user.md +219 -0
  42. package/rules/docker/lint/docs/lint.md +193 -0
  43. package/rules/efes/docs/fix.md +203 -0
  44. package/rules/feedback/docs/fix.md +140 -0
  45. package/rules/flow/docs/fix.md +152 -0
  46. package/rules/ga/docs/fix.md +158 -0
  47. package/rules/ga/js/docs/lint.md +100 -0
  48. package/rules/ga/js/docs/workflows.md +217 -0
  49. package/rules/ga/lint/docs/lint.md +209 -0
  50. package/rules/ga/policy/clean_merged_branch/clean_merged_branch.rego +11 -2
  51. package/rules/ga/policy/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml +3 -4
  52. package/rules/graphql/docs/fix.md +126 -0
  53. package/rules/graphql/js/docs/tooling.md +264 -0
  54. package/rules/graphql/lib/docs/graphql-gql-scan.md +219 -0
  55. package/rules/hasura/docs/fix.md +120 -0
  56. package/rules/hasura/hasura.mdc +14 -0
  57. package/rules/hasura/js/docs/internal_urls.md +326 -0
  58. package/rules/image-avif/docs/fix.md +132 -0
  59. package/rules/image-avif/js/docs/avif_generation.md +241 -0
  60. package/rules/image-compress/docs/fix.md +150 -0
  61. package/rules/image-compress/js/docs/package_setup.md +191 -0
  62. package/rules/js-bun-db/docs/fix.md +148 -0
  63. package/rules/js-bun-db/js/docs/safety.md +231 -0
  64. package/rules/js-bun-db/js-bun-db.mdc +42 -13
  65. package/rules/js-bun-db/lib/docs/bun-sql-scan.md +347 -0
  66. package/rules/js-bun-redis/docs/fix.md +123 -0
  67. package/rules/js-bun-redis/js/docs/imports.md +176 -0
  68. package/rules/js-bun-redis/lib/docs/redis-imports.md +223 -0
  69. package/rules/js-lint/docs/fix.md +117 -0
  70. package/rules/js-lint/js/docs/lint.md +250 -0
  71. package/rules/js-lint/js/docs/tooling.md +348 -0
  72. package/rules/js-lint/js/docs/utils_imports.md +207 -0
  73. package/rules/js-lint-ci/docs/fix.md +154 -0
  74. package/rules/js-lint-ci/js/docs/lint.md +144 -0
  75. package/rules/js-mssql/docs/fix.md +128 -0
  76. package/rules/js-mssql/js/docs/deps.md +263 -0
  77. package/rules/js-mssql/lib/docs/mssql-pool-scan.md +367 -0
  78. package/rules/js-run/docs/fix.md +144 -0
  79. package/rules/js-run/js/docs/runtime.md +388 -0
  80. package/rules/js-run/lib/docs/bunyan-imports.md +117 -0
  81. package/rules/js-run/lib/docs/check-env-scan.md +433 -0
  82. package/rules/js-run/lib/docs/conn-file-rules.md +300 -0
  83. package/rules/js-run/lib/docs/conn-imports-scan.md +204 -0
  84. package/rules/js-run/lib/docs/promise-settimeout-scan.md +326 -0
  85. package/rules/k8s/docs/fix.md +129 -0
  86. package/rules/k8s/js/docs/manifests.md +344 -0
  87. package/rules/k8s/js/manifests.mjs +6 -2
  88. package/rules/k8s/k8s.mdc +4 -2
  89. package/rules/k8s/lint/docs/lint.md +411 -0
  90. package/rules/k8s/policy/network_policy/template/deployment.snippet.yaml +2 -0
  91. package/rules/k8s/policy/network_policy/template/stateful-set.snippet.yaml +2 -0
  92. package/rules/nginx-default-tpl/docs/fix.md +124 -0
  93. package/rules/nginx-default-tpl/js/docs/template.md +378 -0
  94. package/rules/npm-module/docs/fix.md +98 -0
  95. package/rules/npm-module/js/docs/package_structure.md +274 -0
  96. package/rules/npm-module/js/docs/rule_meta.md +137 -0
  97. package/rules/npm-module/js/docs/skill_meta.md +190 -0
  98. package/rules/php/docs/fix.md +107 -0
  99. package/rules/php/js/docs/tooling.md +152 -0
  100. package/rules/php/lint/docs/lint.md +215 -0
  101. package/rules/python/docs/fix.md +163 -0
  102. package/rules/python/js/docs/applies.md +108 -0
  103. package/rules/python/js/docs/tooling.md +153 -0
  104. package/rules/python/lint/docs/lint.md +322 -0
  105. package/rules/rego/docs/fix.md +121 -0
  106. package/rules/rego/js/docs/applies.md +174 -0
  107. package/rules/rego/js/docs/lint.md +118 -0
  108. package/rules/rego/lint/docs/lint.md +204 -0
  109. package/rules/release/docs/change.md +185 -0
  110. package/rules/release/docs/fix.md +119 -0
  111. package/rules/release/docs/release.md +222 -0
  112. package/rules/release/lib/docs/aggregate.md +246 -0
  113. package/rules/release/lib/docs/change-file.md +200 -0
  114. package/rules/release/lib/docs/fallback.md +203 -0
  115. package/rules/rust/docs/fix.md +129 -0
  116. package/rules/rust/js/docs/applies.md +140 -0
  117. package/rules/rust/lib/docs/has-cargo-toml.md +130 -0
  118. package/rules/security/docs/fix.md +86 -0
  119. package/rules/security/js/docs/lint.md +171 -0
  120. package/rules/security/js/docs/sample_secret.md +190 -0
  121. package/rules/security/js/docs/trufflehog.md +137 -0
  122. package/rules/security/js/lint.mjs +9 -1
  123. package/rules/style-lint/docs/fix.md +155 -0
  124. package/rules/style-lint/js/docs/lint.md +184 -0
  125. package/rules/style-lint/js/docs/tooling.md +194 -0
  126. package/rules/tauri/docs/fix.md +158 -0
  127. package/rules/tauri/js/docs/cargo_mutants_config.md +168 -0
  128. package/rules/tauri/js/docs/tooling.md +228 -0
  129. package/rules/test/coverage/coverage.mjs +15 -3
  130. package/rules/test/docs/fix.md +132 -0
  131. package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +138 -0
  132. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +134 -0
  133. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +160 -0
  134. package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +195 -0
  135. package/rules/test/js/docs/cargo_mutants_config.md +173 -0
  136. package/rules/test/js/docs/location.md +136 -0
  137. package/rules/test/js/docs/no-process-chdir.md +160 -0
  138. package/rules/test/js/docs/no-relative-fs-path.md +271 -0
  139. package/rules/test/js/docs/stryker_config.md +152 -0
  140. package/rules/test/js/docs/vitest-config-pool-forks.md +174 -0
  141. package/rules/text/docs/fix.md +118 -0
  142. package/rules/text/js/docs/forbidden-prettier.md +143 -0
  143. package/rules/text/js/docs/formatting.md +256 -0
  144. package/rules/text/js/docs/lint.md +122 -0
  145. package/rules/text/lint/docs/lint.md +220 -0
  146. package/rules/text/lint/docs/run-dotenv-linter.md +157 -0
  147. package/rules/text/lint/docs/run-shellcheck.md +212 -0
  148. package/rules/text/lint/docs/run-v8r.md +197 -0
  149. package/rules/vue/docs/fix.md +127 -0
  150. package/rules/vue/js/docs/packages.md +335 -0
  151. package/rules/vue/lib/docs/vue-forbidden-imports.md +261 -0
  152. package/rules/worktree/docs/fix.md +161 -0
  153. package/schemas/rule-meta.json +5 -1
  154. package/scripts/auto-rules.mjs +7 -4
  155. package/scripts/coverage-classify/docs/apply.md +202 -0
  156. package/scripts/coverage-classify/docs/cache.md +203 -0
  157. package/scripts/coverage-classify/docs/index.md +218 -0
  158. package/scripts/coverage-classify/docs/prompt.md +132 -0
  159. package/scripts/coverage-classify/docs/verdict-schema.md +169 -0
  160. package/scripts/coverage-fix-extract.mjs +122 -0
  161. package/scripts/coverage-fix.mjs +1 -1
  162. package/scripts/dispatcher/docs/graph.md +346 -0
  163. package/scripts/dispatcher/docs/index.md +236 -0
  164. package/scripts/dispatcher/docs/trace.md +296 -0
  165. package/scripts/dispatcher/index.mjs +1 -1
  166. package/scripts/dispatcher/lib/active.mjs +4 -8
  167. package/scripts/dispatcher/lib/commands.mjs +7 -11
  168. package/scripts/dispatcher/lib/docs/active.md +348 -0
  169. package/scripts/dispatcher/lib/docs/artifact.md +232 -0
  170. package/scripts/dispatcher/lib/docs/budget.md +167 -0
  171. package/scripts/dispatcher/lib/docs/capability.md +196 -0
  172. package/scripts/dispatcher/lib/docs/commands.md +210 -0
  173. package/scripts/dispatcher/lib/docs/events.md +182 -0
  174. package/scripts/dispatcher/lib/docs/executor.md +190 -0
  175. package/scripts/dispatcher/lib/docs/flow-lock.md +161 -0
  176. package/scripts/dispatcher/lib/docs/flow-resolve.md +267 -0
  177. package/scripts/dispatcher/lib/docs/gate.md +231 -0
  178. package/scripts/dispatcher/lib/docs/level.md +335 -0
  179. package/scripts/dispatcher/lib/docs/plan-panel.md +181 -0
  180. package/scripts/dispatcher/lib/docs/plan.md +200 -0
  181. package/scripts/dispatcher/lib/docs/planner.md +269 -0
  182. package/scripts/dispatcher/lib/docs/review.md +255 -0
  183. package/scripts/dispatcher/lib/docs/reviewer.md +240 -0
  184. package/scripts/dispatcher/lib/docs/snapshot.md +247 -0
  185. package/scripts/dispatcher/lib/docs/spec.md +203 -0
  186. package/scripts/dispatcher/lib/docs/state-store.md +303 -0
  187. package/scripts/dispatcher/lib/docs/subagent-runner.md +173 -0
  188. package/scripts/dispatcher/lib/executor.mjs +6 -1
  189. package/scripts/dispatcher/lib/flow-resolve.mjs +3 -1
  190. package/scripts/dispatcher/lib/level.mjs +29 -3
  191. package/scripts/dispatcher/lib/review.mjs +1 -1
  192. package/scripts/dispatcher/lib/subagent-runner.mjs +5 -3
  193. package/scripts/docs/auto-rules.md +376 -0
  194. package/scripts/docs/auto-skills.md +173 -0
  195. package/scripts/docs/build-agents-commands.md +183 -0
  196. package/scripts/docs/cli-entry.md +153 -0
  197. package/scripts/docs/coverage-fix.md +177 -0
  198. package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +189 -0
  199. package/scripts/lib/changed-files.mjs +4 -1
  200. package/scripts/lib/docs/changed-files.md +149 -0
  201. package/scripts/lib/docs/check-mdc-template-refs.md +222 -0
  202. package/scripts/lib/docs/check-reporter.md +175 -0
  203. package/scripts/lib/docs/discover-check-rules-from-cursor.md +157 -0
  204. package/scripts/lib/docs/discover-checkable-rules.md +165 -0
  205. package/scripts/lib/docs/ensure-tool.md +254 -0
  206. package/scripts/lib/docs/generated-markdown.md +275 -0
  207. package/scripts/lib/docs/gha-workflow.md +326 -0
  208. package/scripts/lib/docs/inline-template-links.md +303 -0
  209. package/scripts/lib/docs/list-rule-ids.md +156 -0
  210. package/scripts/lib/docs/load-cursor-config.md +147 -0
  211. package/scripts/lib/docs/mirror-parity.md +167 -0
  212. package/scripts/lib/worktree.mjs +26 -0
  213. package/scripts/worktree-cli.mjs +12 -2
  214. package/skills/coverage-fix/SKILL.md +34 -45
  215. package/skills/docgen/SKILL.md +44 -23
  216. package/skills/docgen/bench/etalon/firebase_hosting.md +19 -0
  217. package/skills/docgen/bench/etalon/k8s-tree.md +24 -0
  218. package/skills/docgen/bench/etalon/overlay-paths.md +24 -0
  219. package/skills/docgen/js/docgen-ignore.mjs +54 -0
  220. package/skills/docgen/js/docgen-scan.mjs +37 -21
  221. package/skills/llm-patch/SKILL.md +23 -2
  222. package/skills/start-check/SKILL.md +26 -53
  223. package/skills/start-check/js/check.mjs +211 -0
  224. package/skills/taze/SKILL.md +9 -3
  225. package/skills/taze/js/diff.mjs +154 -0
  226. package/types/bin/n-cursor.d.ts +1 -1
  227. package/skills/fix-tests/SKILL.md +0 -119
  228. package/skills/fix-tests/meta.json +0 -1
@@ -0,0 +1,44 @@
1
+ # http-route.mjs
2
+
3
+ ## Огляд
4
+
5
+ Cross-документна аналітика abie `HTTPRoute`-маніфестів: рахує посилання (`backendRefs`) на спільні `-hl`-сервіси у base-шарі пакета (поза overlay `ua`) і водночас фіксує порушення `namespace`. Слугує джерелом істини для `ua_http_route`-концерну, який звіряє кількість namespace-patch-ів в overlay із кількістю base-reference.
6
+
7
+ ## Поведінка
8
+
9
+ 1. Обходить переданий перелік YAML-файлів під k8s-каталогом, лишаючи тільки ті, що належать base-шару abie-пакета й не входять до overlay `ua`.
10
+ 2. Кожен відібраний файл читається й безпечно парситься як набір YAML-документів; документи з помилками парсингу пропускаються (інші документи в тому ж файлі продовжують аналізуватися).
11
+ 3. Враховуються лише документи з `kind: HTTPRoute`. Інші види та структурно некоректні корені дають нульовий внесок.
12
+ 4. Для `HTTPRoute` обхід заходить у `spec.rules[].backendRefs[]` і для кожного посилання перевіряє, чи його `name` належить набору спільних cross-namespace сервісів.
13
+ 5. Спільними вважаються рівно два сервіси: `auth-run-hl` та `file-link-hl`. Кожне таке посилання збільшує загальний лічильник посилань на 1.
14
+ 6. Якщо посилання на спільний сервіс не має `namespace: dev`, додається помилка виду `<rel>: HTTPRoute backendRefs до <name> має містити namespace: dev (abie.mdc)`.
15
+ 7. Підсумок по всьому пакету повертається як агрегований лічильник посилань (`refCount`) і список base-помилок (`baseErrors`).
16
+
17
+ Приклад спільного backend-посилання, яке проходить перевірку:
18
+
19
+ ```yaml
20
+ kind: HTTPRoute
21
+ spec:
22
+ rules:
23
+ - backendRefs:
24
+ - name: auth-run-hl
25
+ namespace: dev
26
+ ```
27
+
28
+ ## Публічний API
29
+
30
+ - `analyzeAbieSharedBackendRefsInPackageK8s` — за коренем репозиторію, шляхом каталогу пакета й переліком YAML-файлів повертає сумарну кількість base-посилань на спільні `-hl`-сервіси та список порушень `namespace` у base-шарі.
31
+ - `ABIE_SHARED_CROSS_NS_BACKEND_NAMES` — заморожений перелік імен спільних cross-namespace сервісів (`auth-run-hl`, `file-link-hl`), за якими ведеться підрахунок.
32
+
33
+ ## Де використовується
34
+
35
+ Споживається `ua_http_route`-концерном (`npm/rules/abie/js/ua_http_route.mjs`) для синхронізації числа namespace-patch-ів в overlay `ua` із кількістю base-reference.
36
+
37
+ ## Гарантії поведінки
38
+
39
+ - Read-only: файли лише читаються, аналіз нічого не пише на диск.
40
+ - Парсинг fail-safe: помилки читання/розбору YAML придушуються, а документи з помилками не враховуються — некоректний файл не зриває аналіз пакета.
41
+ - Структурна стійкість: `null`, масиви та поля неочікуваного типу на будь-якому рівні (корінь, `spec`, `rules`, окреме посилання) дають нульовий внесок без винятків.
42
+ - Лічильник рахує тільки посилання на два визначені спільні сервіси; інші backend-сервіси ігноруються.
43
+ - Перелік спільних імен заморожений і не може бути змінений споживачами.
44
+ - Шляхи у повідомленнях нормалізовані до `/`, тож вихід однаковий на POSIX і Windows.
@@ -0,0 +1,40 @@
1
+ # k8s-tree
2
+
3
+ ## Огляд
4
+
5
+ Модуль обходить дерево репозиторію й постачає правилу `abie` два набори даних про Kubernetes-маніфести: усі YAML-файли під сегментом `k8s/` та каталоги, що містять `Deployment`. Результати кешуються на час одного прогону (module-level singleton), тож кілька перевірок у межах однієї сесії перевикористовують єдиний обхід замість повторного I/O.
6
+
7
+ ## Поведінка
8
+
9
+ Пошук YAML-файлів під `k8s/`:
10
+
11
+ 1. Рекурсивно обходить дерево від кореня репозиторію, поважаючи передані шляхи-виключення.
12
+ 2. Каталог `.github/` свідомо пропускається — він належить іншому правилу (`ga.mdc`).
13
+ 3. До результату потрапляє файл лише якщо його шлях містить сегмент `k8s/` і має розширення `.yaml` чи `.yml`.
14
+ 4. Повертає абсолютні шляхи, відсортовані за алфавітом (детермінований вивід).
15
+
16
+ Пошук каталогів із `Deployment`:
17
+
18
+ 1. Приймає набір абсолютних шляхів до YAML-файлів (зазвичай результат попереднього кроку).
19
+ 2. Кожен файл читається й розбивається на окремі YAML-документи.
20
+ 3. Документ враховується лише якщо розпарсився без помилок і є маніфестом `kind: Deployment`.
21
+ 4. Каталог кожного такого файлу додається до результуючого набору унікальних каталогів.
22
+ 5. Пошкоджені або непарсабельні YAML за замовчуванням мовчки пропускаються; формальний reporter помилок caller може передати окремо.
23
+
24
+ ## Публічний API
25
+
26
+ - `findK8sYamlFiles` — повертає відсортований список абсолютних шляхів до YAML-файлів під `k8s/`, з урахуванням виключень і пропуском `.github/`.
27
+ - `collectDeploymentDirs` — за набором YAML-файлів повертає множину абсолютних каталогів, де знайдено хоча б один `Deployment`-маніфест.
28
+
29
+ Обидві точки повертають Promise. Результат кожної кешується за стабільним ключем (для пошуку файлів — за коренем і набором виключень; для пошуку каталогів — за коренем і набором YAML-шляхів), тож повторний виклик із тими самими аргументами не виконує повторного обходу чи читання. У кеші зберігається сам Promise, тому конкурентні виклики з однаковим ключем склеюються в один реальний обхід файлової системи.
30
+
31
+ ## Де використовується
32
+
33
+ Допоміжний модуль правила `abie` (`npm/rules/abie/`), що постачає спільні дані про Kubernetes-деплойменти для його перевірок.
34
+
35
+ ## Гарантії поведінки
36
+
37
+ - Read-only: модуль лише читає файлову систему, нічого не змінює.
38
+ - Детермінований вивід: списки результатів і ключі кешу сортуються, тож результат не залежить від порядку обходу чи порядку переданих аргументів.
39
+ - Fail-safe щодо вмісту: документи з помилками парсингу ігноруються, а пошкоджені YAML за замовчуванням не зривають обхід — без переданого reporter про них просто мовчиться.
40
+ - Кеш діє в межах життя процесу й не має інвалідації: у межах одного прогону файлова система вважається незмінною, а між прогонами процес стартує заново.
@@ -0,0 +1,47 @@
1
+ # kustomization-patches.mjs
2
+
3
+ ## Огляд
4
+
5
+ Модуль розпізнає inline JSON6902-патчі всередині `kustomization.yaml` для abie ua-overlay і перевіряє, що вони відповідають вимогам правила `abie.mdc`. Обслуговує два сценарії: патч `nodeSelector` на `Deployment` (закріплення подів на не-preemptible вузлах) і патчі `HTTPRoute` (домени, namespace для `parentRefs` і `backendRefs`). Тіло `patch:` у YAML — це рядок із вкладеним JSON6902, тому розпізнавання спирається на пошук характерних підрядків (`path: …`, `value: …`), а не на повторний парсинг.
6
+
7
+ ## Поведінка
8
+
9
+ Спільний препроцесинг тексту `kustomization.yaml`: знімається BOM; якщо перший рядок — editor-modeline, його відкидають; решта розбирається як набір YAML-документів (можливо кілька через `---`). Будь-яка помилка розбору перехоплюється і дає безпечний результат (`false` або порожній рядок).
10
+
11
+ ### Перевірка nodeSelector-патча для Deployment
12
+
13
+ 1. Серед документів шукають той, де `kind: Kustomization` і є масив `patches`.
14
+ 2. Підходить елемент `patches`, у якого `target.kind` дорівнює `Deployment`, а текст патча містить одночасно шлях `/spec/template/spec/nodeSelector` і ключ `preem: false` (з лапками або без).
15
+ 3. Якщо хоча б один такий патч знайдено — результат позитивний.
16
+
17
+ ### Збір і валідація HTTPRoute-патчів
18
+
19
+ 1. З усіх документів `Kustomization` збираються тексти патчів, у яких `target.kind` дорівнює `HTTPRoute` і `target.name` непорожній; зібрані фрагменти склеюються в один текст.
20
+ 2. Об'єднаний текст перевіряється послідовно. Кожна невдала умова повертає конкретне україномовне повідомлення з посиланням на `abie.mdc`; повний успіх — `null`:
21
+ - текст не може бути порожнім;
22
+ - має бути шлях `/spec/hostnames`;
23
+ - серед значень `hostnames` має бути хоча б один з доменів abie: `abie.app`, `vybeerai.com.ua`, `*.abie.app`, `*.vybeerai.com.ua`;
24
+ - має бути шлях `/spec/parentRefs/0/namespace` зі значенням `ua` (дозволено й `ua-*`, напр. `ua-b2b`);
25
+ - якщо в base-HTTPRoute є cross-namespace `backendRefs` до спільних сервісів (`auth-run-hl`, `file-link-hl`), то на кожен такий ref має бути окремий патч `path: /spec/rules/.../backendRefs/.../namespace` зі значенням `ua[-…]`; якщо патчів менше очікуваного — помилка з числами «потрібно/є».
26
+
27
+ Очікувана кількість cross-namespace патчів передається ззовні (з аналізу base-маніфестів). Некоректне чи від'ємне значення нормалізується до невід'ємного цілого; `0` означає, що ця перевірка пропускається.
28
+
29
+ Приклади namespace, що проходять: `ua`, `ua-b2b`.
30
+
31
+ ## Публічний API
32
+
33
+ - `kustomizationHasAbieDeploymentNodeSelectorPatch(raw, mode)` — за повним текстом `kustomization.yaml` повертає `true`, якщо в ньому є коректний inline-патч `nodeSelector` (`preem: false`) на `Deployment` для overlay `ua`.
34
+ - `getCombinedNginxRunPatchTextFromKustomization(raw)` — повертає об'єднаний текст усіх inline JSON6902-фрагментів HTTPRoute (з непорожнім `target.name`); порожній рядок, якщо таких немає або файл не розбирається.
35
+ - `validateAbieNginxRunHttpRoutePatches(combined, mode, _fullKustomizationRaw, sharedCrossNsBackendRefCount)` — перевіряє об'єднаний текст HTTPRoute-патчів на відповідність abie.mdc; повертає `null` при успіху або повідомлення про помилку. Параметр `_fullKustomizationRaw` лишений лише для сумісності сигнатури й не використовується.
36
+
37
+ ## Де використовується
38
+
39
+ - `npm/rules/abie/js/ua_node_selector.mjs` — перевірка наявності nodeSelector-патча в ua-overlay.
40
+ - `npm/rules/abie/js/ua_http_route.mjs` — збирає об'єднаний текст HTTPRoute-патчів і валідує його з урахуванням кількості спільних cross-namespace backendRefs.
41
+
42
+ ## Гарантії поведінки
43
+
44
+ - Read-only: модуль лише обробляє переданий текст, нічого не змінює, не звертається до файлової системи чи мережі — IO виконують виклики на рівні правила.
45
+ - Стійкість до поганого вводу: помилки розбору YAML перехоплюються (предикат → `false`, збирач → `''`); некоректні чи відсутні поля (`patches` не масив, відсутній `target`, нерядкове тіло `patch`) безпечно ігноруються.
46
+ - Враховується тільки рядкове тіло `patch:` — елементи зі структурованим (об'єктним) патчем пропускаються.
47
+ - Логіка розрахована лише на `mode === 'ua'` (і похідні `ua-*`); для інших значень HTTPRoute-підрахунок повертає `0`.
@@ -0,0 +1,38 @@
1
+ # overlay-paths
2
+
3
+ ## Огляд
4
+
5
+ Набір path-хелперів для перевірок правила abie, що працює з k8s-структурою пакетів монорепо. Розрізняє base-шар пакета та `ua/` overlay, виводить каталог пакета зі шляху overlay і визначає, які додаткові вимоги (HTTPRoute, Deployment) застосовуються до конкретного overlay. Усі хелпери — чисті обчислення над шляхами без побічних ефектів, окрім перевірок наявності файлів `vite.config.*` на диску.
6
+
7
+ ## Поведінка
8
+
9
+ Очікувана структура пакета, з якою працює модуль:
10
+
11
+ ```
12
+ <пакет>/
13
+ k8s/
14
+ base/... ← base-шар
15
+ ua/
16
+ kustomization.yaml ← abie overlay
17
+ vite.config.{js,mjs,ts} ← опційно, ознака Vite-пакета
18
+ ```
19
+
20
+ 1. Розпізнавання overlay-маніфесту: шлях, що закінчується на `…/ua/kustomization.yaml`, вважається abie overlay. Перед матчингом backslash-роздільники нормалізуються в `/`, тож перевірка однакова на Windows і POSIX.
21
+
22
+ 2. Виведення каталогу пакета: для overlay вигляду `…/k8s/ua/kustomization.yaml` обчислюється абсолютний шлях до каталогу пакета (батько `k8s/`). Якщо шлях не відповідає цьому шаблону — повертається `null`, що сигналізує, що це не валідний overlay-маніфест abie-пакета.
23
+
24
+ 3. Gate на HTTPRoute за наявністю Vite: вимога HTTPRoute застосовується до overlay лише тоді, коли в каталозі пакета присутній один із `vite.config.js`, `vite.config.mjs` або `vite.config.ts`. Для не-Vite пакетів вимога не вмикається. Якщо каталог пакета вивести не вдалося — вимога теж не вмикається.
25
+
26
+ 4. Наявність Deployment у дереві пакета: перевіряється, чи серед заздалегідь зібраного набору каталогів із Deployment є хоча б один усередині `k8s/`-піддерева цього пакета (сам корінь `k8s/` або будь-який вкладений каталог). Набір каталогів передається ззовні — модуль сам файлову систему не сканує.
27
+
28
+ 5. Розрізнення base vs overlay для yaml-файлу:
29
+ - швидка ознака base-шару — наявність сегмента `base/` будь-де у шляху;
30
+ - точніша перевірка приналежності до base конкретного пакета — yaml має лежати під `<пакет>/k8s/`, але поза піддеревом `ua/`. Файли overlay (`ua/`) виключаються.
31
+
32
+ ## Гарантії поведінки
33
+
34
+ - Хелпери read-only щодо вмісту файлів; єдина взаємодія з ФС — перевірка існування `vite.config.*`. Вони не читають, не пишуть і не модифікують файли.
35
+ - Шляхи з `\` нормалізуються в `/` перед порівнянням, тож результати не залежать від ОС.
36
+ - Якщо overlay-шлях не відповідає очікуваному шаблону `…/k8s/ua/kustomization.yaml`, обчислення каталогу пакета повертає `null`, а похідні від нього перевірки (HTTPRoute, Deployment) безпечно повертають `false` замість помилки.
37
+ - Кінцевий слеш у переданому каталозі пакета ігнорується при перевірці приналежності yaml до base-шару.
38
+ - Перевірка приналежності до `k8s/`-піддерева враховує точний збіг кореня й порівнює з межею `/`, тож не дає хибних спрацювань на сусідніх каталогах із подібним префіксом.
@@ -0,0 +1,29 @@
1
+ # yaml.mjs
2
+
3
+ ## Огляд
4
+
5
+ Спільний набір YAML-хелперів для перевірок правила `abie`. Інкапсулює читання й розбір YAML-файлів Kubernetes-маніфестів так, щоб усі abie-перевірки розбирали вміст однаково: з прибиранням BOM, ігноруванням службового modeline-рядка `# yaml-language-server: $schema=` і fail-safe-поведінкою при пошкоджених файлах.
6
+
7
+ ## Поведінка
8
+
9
+ Читання й розбір YAML-документів з файлу:
10
+
11
+ 1. Намагається прочитати файл за абсолютним шляхом. Якщо читання не вдалося — викликає переданий обробник помилок із повідомленням, що включає відносний шлях і причину, і повертає `null`.
12
+ 2. Прибирає BOM на початку вмісту, якщо він є.
13
+ 3. Якщо перший рядок — це YAML-language-server modeline (`# yaml-language-server: $schema=...`), пропускає його перед розбором; решта вмісту парситься без нього. Інакше парситься весь вміст.
14
+ 4. Розбирає всі YAML-документи у файлі (мультидокументні файли з `---` підтримуються). При помилці розбору викликає обробник помилок із повідомленням і повертає `null`; інакше повертає масив розібраних документів.
15
+
16
+ Окремо надає предикат розпізнавання маніфестів `Deployment`: документ вважається `Deployment`, лише якщо це звичайний об'єкт (не масив, не `null`) із полем `kind` рівним `'Deployment'`.
17
+
18
+ Передбачено готовий «тихий» обробник помилок — для викликів, які мають мовчки повертати порожній результат при поганому вводі, бо пошкоджені файли діагностує окрема перевірка (`check-k8s`), а не abie.
19
+
20
+ ## Де використовується
21
+
22
+ Хелпери імпортуються іншими модулями abie, що аналізують Kubernetes-маніфести, зокрема `lib/k8s-tree.mjs`, `lib/kustomization-patches.mjs`, `lib/http-route.mjs`, `lib/hc-yaml.mjs` та перевіркою `js/hc_pairing.mjs`.
23
+
24
+ ## Гарантії поведінки
25
+
26
+ - Read-only: модуль лише читає й розбирає файли, не змінює їх.
27
+ - Fail-safe: помилки читання чи розбору YAML не кидаються назовні — натомість викликається переданий обробник, а результатом стає `null`. Це дозволяє перевіркам пропускати биті файли замість падіння.
28
+ - Розбір стійкий до BOM і до службового modeline-рядка `$schema` на першому рядку — вони не ламають парсинг і не потрапляють у результат.
29
+ - Предикат розпізнавання `Deployment` безпечний для будь-якого вводу: повертає `false` для `null`, масивів і не-об'єктів, ніколи не кидає винятків.
@@ -0,0 +1,148 @@
1
+ # `npm/rules/adr/fix.mjs`
2
+
3
+ ## Огляд
4
+
5
+ Файл `fix.mjs` — це **entry-point правила `adr`** у складі пакета `@nitra/cursor`. Він виконує дві ролі одночасно й тримає мінімум власної логіки, делегуючи всю роботу до загальних бібліотечних функцій оркестрації правил:
6
+
7
+ 1. **Library mode (бібліотечний режим).** Експортує функцію `run(ctx)`, яку викликає зовнішній оркестратор `@nitra/cursor` (наприклад, команда `npx @nitra/cursor fix adr` або агрегований прогін усіх правил). У цьому режимі правило виконує стандартну послідовність кроків `applies → JS-concerns → policy → mdc-refs` через `runStandardRule`, а контекст (наприклад, спільний `walkCache` для обходу файлів) передається ззовні.
8
+ 2. **Standalone mode (самостійний запуск).** Якщо файл запущено напряму як CLI (наприклад, `bun npm/rules/adr/fix.mjs`), він повністю емулює виклик `npx @nitra/cursor fix adr`: завантажує конфіг, застосовує whitelist, виводить summary і повертає процесу exit-code 0/1 для CI/IDE.
9
+
10
+ Файл сам по собі **не містить** ні логіки перевірки правила ADR, ні визначень policy/mdc-refs — він лише підключає механіку, спільну для всіх правил у директорії `npm/rules/*/fix.mjs`. Власне поведінка правила `adr` визначається сусідніми файлами в каталозі `npm/rules/adr/` (наприклад, `check-adr.mjs`, `.mdc`-файл, конфіг правила), які `runStandardRule` підхоплює за конвенцією на основі `import.meta.dirname`.
11
+
12
+ ## Експорти / API
13
+
14
+ Файл публікує один іменований експорт:
15
+
16
+ | Експорт | Тип / сигнатура | Призначення |
17
+ | --- | --- | --- |
18
+ | `run` | `(ctx?: RuleContext) => Promise<number>` | Запуск правила `adr` у library-режимі через `runStandardRule`. Повертає 0 (OK) або 1 (порушення). |
19
+
20
+ Окрім експорту, файл має **top-level side-effect**: блок `if (isRunAsCli(import.meta.url)) { … }` виконується одразу при імпорті/запуску модуля та, у разі прямого CLI-запуску, завершує процес викликом `process.exit(...)`. У бібліотечному режимі (`import { run } from '...'`) цей блок не спрацьовує, бо `isRunAsCli` повертає `false`.
21
+
22
+ Default-експортів, констант чи класів файл **не** надає.
23
+
24
+ ## Функції
25
+
26
+ ### `run(ctx)`
27
+
28
+ ```js
29
+ export function run(ctx) {
30
+ return runStandardRule(import.meta.dirname, ctx)
31
+ }
32
+ ```
33
+
34
+ - **Призначення.** Виконати стандартний конвеєр правила `adr`: `applies → JS-concerns → policy → mdc-refs`. Уся механіка делегується бібліотечній функції `runStandardRule`; локальної логіки немає, окрім прокидання директорії правила й контексту.
35
+ - **Параметри.**
36
+ - `ctx` (необов'язковий) — `RuleContext` із `../../scripts/lib/run-standard-rule.mjs`. Контекст переноситься між викликами різних правил у межах одного запуску оркестратора й може містити, наприклад, кешований обхід файлової системи (`walkCache`), що дозволяє не повторювати дорогі операції для кожного правила. Якщо `ctx` не передано, `runStandardRule` створює власний контекст за замовчуванням.
37
+ - **Повертає.** `Promise<number>` — `0`, якщо порушень правила немає; `1`, якщо знайдено хоча б одне порушення. Це **exit-code-сумісний** код, який далі використовується CLI-обгорткою для `process.exit`.
38
+ - **Side effects.** У межах самого `run` побічних ефектів **не вводить**; усі ефекти (читання файлів, друк звіту, кешування) виконуються всередині `runStandardRule`. Identифікатор правила визначається неявно через `import.meta.dirname` — тобто директорія, у якій лежить цей `fix.mjs` (`npm/rules/adr`), стає каноном для пошуку всіх supplementary-файлів правила (checks, mdc, конфіг).
39
+ - **Помилки.** Власних `try/catch` немає. Якщо `runStandardRule` кидає виняток, він проростає до викликача незмінно. У standalone-режимі винятки обробляються вже не `run`, а `runRuleCli`.
40
+
41
+ ### Top-level CLI-блок (не функція, але виконуваний код модуля)
42
+
43
+ ```js
44
+ if (isRunAsCli(import.meta.url)) {
45
+ process.exit(await runRuleCli(import.meta.dirname))
46
+ }
47
+ ```
48
+
49
+ - **Призначення.** Якщо файл запущено як головний модуль (тобто `import.meta.url` відповідає `argv[1]`), активується standalone-режим — еквівалент `npx @nitra/cursor fix adr`.
50
+ - **Логіка.**
51
+ 1. `isRunAsCli(import.meta.url)` визначає, чи модуль є entry-point процесу (а не імпортовано бібліотечно).
52
+ 2. `runRuleCli(import.meta.dirname)` виконує повний CLI-pipeline для правила в цій директорії: завантаження конфігу, застосування whitelist, виклик внутрішнього `run`, друк summary, повернення numeric exit-code.
53
+ 3. `process.exit(...)` завершує процес із цим exit-кодом — це потрібно, аби CI/IDE могли інтерпретувати успіх/невдачу.
54
+ - **Top-level `await`.** Виклик `await runRuleCli(...)` працює завдяки ESM top-level await (`.mjs`).
55
+ - **Pragma-коментар.** Над `process.exit` стоїть `eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit` із поясненням: standalone entry-point **повинен** повертати exit-code, тому загальна заборона `process.exit` тут свідомо відключена.
56
+ - **Чому два режими в одному файлі.** В коментарі прямо зазначено: "Дві ролі fix.mjs: library (run) + standalone (main)". Це конвенція пакета `@nitra/cursor` — кожне правило має один `fix.mjs`, який можна і `import`-ити, і запускати безпосередньо.
57
+
58
+ ## Залежності
59
+
60
+ ### Внутрішні (workspace `@nitra/cursor`)
61
+
62
+ | Шлях | Імпортовані символи | Роль |
63
+ | --- | --- | --- |
64
+ | `../../scripts/lib/run-rule-cli.mjs` | `isRunAsCli`, `runRuleCli` | `isRunAsCli` — перевірка, чи модуль є CLI entry-point. `runRuleCli` — повний CLI-pipeline (config + whitelist + summary + exit-code). |
65
+ | `../../scripts/lib/run-standard-rule.mjs` | `runStandardRule` | Реалізація стандартного конвеєра правила: `applies → JS-concerns → policy → mdc-refs`. Також звідси походить JSDoc-тип `RuleContext`. |
66
+
67
+ Шляхи відносні: з `npm/rules/adr/` два рівні вгору ведуть у `npm/`, далі — `scripts/lib/`.
68
+
69
+ ### Зовнішні (npm-пакети)
70
+
71
+ Прямих імпортів зовнішніх пакетів файл **не** має. Опосередковано, через бібліотечні модулі, можуть бути задіяні стандартні утиліти Node (`node:fs`, `node:path` тощо) — але це деталь реалізації `runStandardRule` / `runRuleCli`, а не цього файла.
72
+
73
+ ### Платформенні вимоги
74
+
75
+ - **ESM**. Розширення `.mjs` + використання `import.meta.dirname` і `import.meta.url`.
76
+ - **`import.meta.dirname`** — доступне в Node.js ≥ 20.11 та Bun. Без цієї властивості модуль не запрацює.
77
+ - **Top-level `await`** — для standalone-блоку.
78
+
79
+ ## Потік виконання / Використання
80
+
81
+ ### Сценарій 1. Library-режим (виклик із оркестратора)
82
+
83
+ ```js
84
+ import { run } from '@nitra/cursor/rules/adr/fix.mjs'
85
+
86
+ const code = await run({ walkCache /*, … */ })
87
+ if (code !== 0) {
88
+ // знайдені порушення правила adr
89
+ }
90
+ ```
91
+
92
+ Послідовність кроків усередині `run`:
93
+
94
+ 1. `runStandardRule` отримує абсолютний шлях директорії правила (`import.meta.dirname` → `…/npm/rules/adr`).
95
+ 2. За конвенціями цієї директорії бібліотека сама знаходить:
96
+ - `applies`-фільтр (які файли підпадають під правило),
97
+ - JS-concerns-перевірки,
98
+ - policy-частину (rego/правила політики, якщо є),
99
+ - `mdc-refs` (перевірка посилань на `.mdc`-файли).
100
+ 3. Кожен крок виконується послідовно; якщо хоч один знаходить порушення — фінальний exit-code = `1`.
101
+ 4. Promise резолвиться числом `0` або `1`.
102
+
103
+ Сам файл `fix.mjs` у цьому потоці — **тонка обгортка**: він не приймає рішень і не друкує нічого власноруч.
104
+
105
+ ### Сценарій 2. Standalone-режим (запуск напряму)
106
+
107
+ ```bash
108
+ bun npm/rules/adr/fix.mjs
109
+ # або
110
+ node npm/rules/adr/fix.mjs
111
+ ```
112
+
113
+ Послідовність:
114
+
115
+ 1. Модуль завантажується, `run` стає експортованим.
116
+ 2. Виконується top-level умова `isRunAsCli(import.meta.url)` → `true`.
117
+ 3. `runRuleCli(import.meta.dirname)` бере на себе:
118
+ - читання конфігу (наприклад, `.cursor`-конфіг або CLI-параметри),
119
+ - застосування whitelist (обмеження файлів, які проходять перевірку),
120
+ - виклик внутрішньої функції `run` цього ж правила,
121
+ - друк підсумкового summary (скільки файлів, скільки порушень),
122
+ - повернення exit-code (`0` або `1`).
123
+ 4. `process.exit(...)` зупиняє процес із цим кодом — CI/IDE отримують стандартний сигнал успіху/невдачі.
124
+
125
+ Цей режим — еквівалент `npx @nitra/cursor fix adr`, але без потреби у глобально встановленому CLI: достатньо мати checkout репозиторію.
126
+
127
+ ### Сценарій 3. Імпорт без виконання (рідкісний)
128
+
129
+ Якщо файл імпортується умовами, де `import.meta.url !== argv[1]`, спрацьовує лише експорт `run`; CLI-блок мовчазно пропускається. Це і є основою «двох ролей»: ESM-модуль безпечно імпортувати з будь-якого місця без сайд-ефекту запуску процесу.
130
+
131
+ ### Контекст у системі правил
132
+
133
+ Файл вписується у плаский набір правил `npm/rules/<id>/fix.mjs`. Кожне правило має такий самий каркас, відрізняючись лише іменем директорії (а отже — `import.meta.dirname`) та допоміжними файлами поруч (`check-*.mjs`, `*.mdc` тощо). Логіка спільного pipeline винесена у `scripts/lib/run-standard-rule.mjs` і `scripts/lib/run-rule-cli.mjs`, що робить `fix.mjs` максимально декларативним: він — «адаптер» між директорією правила та оркестратором.
134
+
135
+ ## Rebuild Test
136
+
137
+ Якщо знищити цей файл і реконструювати з документації вище, відновлювана версія повинна:
138
+
139
+ 1. Бути ESM-модулем (`.mjs`).
140
+ 2. Імпортувати з `../../scripts/lib/run-rule-cli.mjs` дві іменовані функції: `isRunAsCli` та `runRuleCli`.
141
+ 3. Імпортувати з `../../scripts/lib/run-standard-rule.mjs` іменовану функцію `runStandardRule`.
142
+ 4. Експортувати функцію `run(ctx)`, яка повертає результат виклику `runStandardRule(import.meta.dirname, ctx)` (без `await`, бо promise повертається як є).
143
+ 5. Мати JSDoc-блок до `run` з посиланням на тип `RuleContext` з `run-standard-rule.mjs` та описом `@returns {Promise<number>}` із семантикою `0 — OK, 1 — порушення`.
144
+ 6. Містити top-level умову `if (isRunAsCli(import.meta.url))`, всередині якої виконується `process.exit(await runRuleCli(import.meta.dirname))`.
145
+ 7. Над `process.exit` мати ESLint-disable-коментар для `n/no-process-exit` та `unicorn/no-process-exit` із поясненням, що standalone entry-point повинен повертати exit-code для CI/IDE.
146
+ 8. **Не** містити жодної додаткової логіки правила `adr` всередині — уся механіка делегована бібліотечним функціям.
147
+
148
+ Реконструйована версія за цими інваріантами буде функціонально еквівалентною оригіналу.