@nitra/cursor 5.1.0 → 5.2.1

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 (214) hide show
  1. package/.claude-template/settings.template.json +22 -0
  2. package/.pi-template/extensions/n-cursor-adr/docs/index.md +15 -9
  3. package/CHANGELOG.md +18 -1
  4. package/bin/n-cursor.js +73 -16
  5. package/docs/stryker.config.md +6 -0
  6. package/docs/vitest.config.md +6 -0
  7. package/lib/docs/llm.md +29 -0
  8. package/lib/docs/models.md +24 -17
  9. package/lib/docs/omlx.md +32 -0
  10. package/lib/llm.mjs +137 -0
  11. package/lib/omlx.mjs +49 -4
  12. package/package.json +1 -1
  13. package/rules/abie/docs/fix.md +6 -0
  14. package/rules/abie/js/docs/applies.md +6 -0
  15. package/rules/abie/js/docs/env_dns.md +25 -22
  16. package/rules/abie/js/docs/firebase_hosting.md +6 -0
  17. package/rules/abie/js/docs/hc_pairing.md +21 -25
  18. package/rules/abie/js/docs/ua_http_route.md +27 -19
  19. package/rules/abie/js/docs/ua_node_selector.md +24 -19
  20. package/rules/abie/lib/docs/enabled.md +13 -7
  21. package/rules/abie/lib/docs/env-dns.md +9 -3
  22. package/rules/abie/lib/docs/hc-yaml.md +6 -0
  23. package/rules/abie/lib/docs/http-route.md +6 -0
  24. package/rules/abie/lib/docs/k8s-tree.md +6 -0
  25. package/rules/abie/lib/docs/kustomization-patches.md +6 -0
  26. package/rules/abie/lib/docs/overlay-paths.md +6 -0
  27. package/rules/abie/lib/docs/yaml.md +6 -0
  28. package/rules/adr/docs/fix.md +6 -0
  29. package/rules/adr/js/docs/hooks.md +29 -244
  30. package/rules/bun/docs/fix.md +6 -0
  31. package/rules/bun/js/docs/layout.md +37 -375
  32. package/rules/capacitor/docs/fix.md +22 -108
  33. package/rules/capacitor/js/docs/platforms.md +62 -268
  34. package/rules/changelog/docs/fix.md +6 -0
  35. package/rules/changelog/js/docs/consistency.md +36 -383
  36. package/rules/changelog/lib/docs/package-manifest.md +6 -0
  37. package/rules/ci4/docs/fix.md +23 -165
  38. package/rules/ci4/js/docs/marksman_config.md +9 -1
  39. package/rules/docker/docs/fix.md +6 -0
  40. package/rules/docker/js/docs/lint.md +55 -239
  41. package/rules/docker/lib/docs/docker-hadolint.md +6 -0
  42. package/rules/docker/lib/docs/docker-mirror.md +6 -0
  43. package/rules/docker/lib/docs/docker-native-addon.md +6 -0
  44. package/rules/docker/lib/docs/docker-nginx-user.md +6 -0
  45. package/rules/docker/lint/docs/lint.md +9 -1
  46. package/rules/efes/docs/fix.md +6 -0
  47. package/rules/feedback/docs/fix.md +21 -131
  48. package/rules/ga/docs/fix.md +14 -12
  49. package/rules/ga/js/docs/lint.md +12 -9
  50. package/rules/ga/js/docs/workflows.md +20 -19
  51. package/rules/ga/lint/docs/lint.md +6 -0
  52. package/rules/graphql/docs/fix.md +6 -0
  53. package/rules/graphql/js/docs/tooling.md +18 -253
  54. package/rules/graphql/lib/docs/graphql-gql-scan.md +6 -0
  55. package/rules/hasura/docs/fix.md +18 -111
  56. package/rules/image-avif/docs/fix.md +6 -0
  57. package/rules/image-avif/js/docs/avif_generation.md +6 -0
  58. package/rules/js-bun-db/lib/docs/bun-sql-scan.md +9 -3
  59. package/rules/js-bun-redis/lib/docs/redis-imports.md +6 -0
  60. package/rules/js-lint/js/docs/utils_imports.md +6 -0
  61. package/rules/js-lint-ci/docs/fix.md +7 -1
  62. package/rules/js-mssql/docs/fix.md +6 -0
  63. package/rules/js-mssql/lib/docs/mssql-pool-scan.md +6 -0
  64. package/rules/js-run/docs/fix.md +6 -0
  65. package/rules/js-run/lib/docs/bunyan-imports.md +6 -0
  66. package/rules/js-run/lib/docs/check-env-scan.md +6 -0
  67. package/rules/js-run/lib/docs/conn-file-rules.md +6 -0
  68. package/rules/js-run/lib/docs/conn-imports-scan.md +6 -0
  69. package/rules/js-run/lib/docs/promise-settimeout-scan.md +6 -0
  70. package/rules/js-run/lib/docs/temporal-scan.md +6 -0
  71. package/rules/k8s/docs/fix.md +6 -0
  72. package/rules/k8s/lint/docs/lint.md +6 -0
  73. package/rules/nginx-default-tpl/docs/fix.md +6 -0
  74. package/rules/npm-module/js/docs/header_doc_pointer.md +7 -0
  75. package/rules/npm-module/js/header_doc_pointer.mjs +2 -8
  76. package/rules/php/docs/fix.md +6 -0
  77. package/rules/php/lint/docs/lint.md +6 -0
  78. package/rules/python/docs/fix.md +6 -0
  79. package/rules/python/lint/docs/lint.md +6 -0
  80. package/rules/rego/lint/docs/lint.md +6 -0
  81. package/rules/release/docs/change.md +6 -0
  82. package/rules/release/docs/fix.md +6 -0
  83. package/rules/release/docs/release.md +6 -0
  84. package/rules/release/lib/docs/aggregate.md +6 -0
  85. package/rules/release/lib/docs/change-file.md +6 -0
  86. package/rules/release/lib/docs/fallback.md +6 -0
  87. package/rules/rust/lib/docs/has-cargo-toml.md +6 -0
  88. package/rules/security/docs/fix.md +7 -1
  89. package/rules/security/js/docs/lint.md +6 -0
  90. package/rules/style-lint/docs/fix.md +6 -0
  91. package/rules/tauri/docs/fix.md +6 -0
  92. package/rules/test/docs/fix.md +6 -0
  93. package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +6 -0
  94. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +6 -0
  95. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +6 -0
  96. package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +6 -0
  97. package/rules/text/docs/fix.md +6 -0
  98. package/rules/text/lint/docs/lint.md +6 -0
  99. package/rules/text/lint/docs/run-dotenv-linter.md +6 -0
  100. package/rules/text/lint/docs/run-shellcheck.md +6 -0
  101. package/rules/text/lint/docs/run-v8r.md +6 -0
  102. package/rules/vue/lib/docs/vue-forbidden-imports.md +6 -0
  103. package/scripts/coverage-classify/cache.mjs +1 -1
  104. package/scripts/coverage-classify/docs/apply.md +6 -0
  105. package/scripts/coverage-classify/docs/cache.md +6 -0
  106. package/scripts/coverage-classify/docs/prompt.md +6 -0
  107. package/scripts/coverage-classify/docs/verdict-schema.md +6 -0
  108. package/scripts/coverage-classify/prompt.mjs +1 -1
  109. package/scripts/coverage-fix-extract.mjs +1 -1
  110. package/scripts/coverage-fix.mjs +2 -1
  111. package/scripts/docs/auto-skills.md +6 -0
  112. package/scripts/docs/build-agents-commands.md +7 -1
  113. package/scripts/docs/cli-entry.md +6 -0
  114. package/scripts/docs/coverage-fix-extract.md +6 -0
  115. package/scripts/docs/coverage-fix.md +6 -0
  116. package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +6 -0
  117. package/scripts/docs/lint-cli.md +6 -0
  118. package/scripts/docs/post-tool-use-fix.md +6 -0
  119. package/scripts/docs/rename-yaml-extensions.md +6 -0
  120. package/scripts/docs/skills-cli.md +6 -0
  121. package/scripts/docs/sync-setup-bun-deps-action.md +6 -0
  122. package/scripts/docs/upgrade-nitra-cursor-and-install.md +6 -0
  123. package/scripts/docs/worktree-cli.md +6 -0
  124. package/scripts/lib/docs/assert-project-root.md +6 -0
  125. package/scripts/lib/docs/check-mdc-template-refs.md +6 -0
  126. package/scripts/lib/docs/check-reporter.md +6 -0
  127. package/scripts/lib/docs/diff-added-lines.md +6 -0
  128. package/scripts/lib/docs/discover-check-rules-from-cursor.md +6 -0
  129. package/scripts/lib/docs/discover-checkable-rules.md +6 -0
  130. package/scripts/lib/docs/ensure-tool.md +6 -0
  131. package/scripts/lib/docs/generated-markdown.md +6 -0
  132. package/scripts/lib/docs/gha-workflow.md +6 -0
  133. package/scripts/lib/docs/inline-template-links.md +6 -0
  134. package/scripts/lib/docs/list-rule-ids.md +6 -0
  135. package/scripts/lib/docs/load-cursor-config.md +6 -0
  136. package/scripts/lib/docs/mirror-parity.md +6 -0
  137. package/scripts/lib/docs/read-n-cursor-config-lite.md +6 -0
  138. package/scripts/lib/docs/resolve-target-files.md +6 -0
  139. package/scripts/lib/docs/root-notice.md +6 -0
  140. package/scripts/lib/docs/rule-meta-helpers.md +6 -0
  141. package/scripts/lib/docs/rule-meta.md +6 -0
  142. package/scripts/lib/docs/run-conftest-batch.md +6 -0
  143. package/scripts/lib/docs/run-lint-step.md +6 -0
  144. package/scripts/lib/docs/run-rule-cli.md +6 -0
  145. package/scripts/lib/docs/run-rule.md +6 -0
  146. package/scripts/lib/docs/run-standard-lint.md +6 -0
  147. package/scripts/lib/docs/run-standard-rule.md +6 -0
  148. package/scripts/lib/docs/skill-meta.md +6 -0
  149. package/scripts/lib/docs/template.md +6 -0
  150. package/scripts/lib/docs/timing-summary.md +6 -0
  151. package/scripts/lib/docs/workspaces.md +6 -0
  152. package/scripts/lib/docs/worktree-notice.md +6 -0
  153. package/scripts/lib/docs/worktree.md +6 -0
  154. package/scripts/lib/mirror-parity.mjs +1 -1
  155. package/scripts/lib/root-notice.mjs +1 -1
  156. package/scripts/lib/worktree-notice.mjs +5 -5
  157. package/scripts/lib/worktree.mjs +1 -1
  158. package/scripts/sync-claude-config.mjs +3 -0
  159. package/scripts/utils/docs/ast-scan-utils.md +6 -0
  160. package/scripts/utils/docs/ensure-gitignore-entries.md +6 -0
  161. package/scripts/utils/docs/find-package-json-paths.md +6 -0
  162. package/scripts/utils/docs/lock-cache-dir.md +6 -0
  163. package/scripts/utils/docs/pass.md +6 -0
  164. package/scripts/utils/docs/resolve-cargo-manifest.md +6 -0
  165. package/scripts/utils/docs/resolve-cmd.md +6 -0
  166. package/scripts/utils/docs/resolve-js-root.md +6 -0
  167. package/scripts/utils/docs/test-helpers.md +6 -0
  168. package/scripts/utils/docs/walk-cache.md +6 -0
  169. package/scripts/utils/docs/walkDir.md +6 -0
  170. package/scripts/utils/docs/worktree-fingerprint.md +6 -0
  171. package/scripts/utils/resolve-js-root.mjs +1 -1
  172. package/skills/doc-aggregate/SKILL.md +129 -0
  173. package/skills/doc-aggregate/js/docgen-ignore.mjs +9 -0
  174. package/skills/{docgen → doc-aggregate}/js/docgen-scan.mjs +22 -67
  175. package/skills/doc-aggregate/js/docs/docgen-ignore.md +21 -0
  176. package/skills/doc-files/SKILL.md +100 -0
  177. package/skills/doc-files/js/docgen-crc.mjs +164 -0
  178. package/skills/{docgen → doc-files}/js/docgen-extract-anchors.mjs +48 -13
  179. package/skills/{docgen → doc-files}/js/docgen-extract.mjs +39 -10
  180. package/skills/doc-files/js/docgen-files-batch.mjs +181 -0
  181. package/skills/doc-files/js/docgen-gen.mjs +336 -0
  182. package/skills/{docgen → doc-files}/js/docgen-prompts.mjs +65 -50
  183. package/skills/doc-files/js/docgen-scan.mjs +298 -0
  184. package/skills/doc-files/js/docs/docgen-crc.md +32 -0
  185. package/skills/doc-files/js/docs/docgen-extract-anchors.md +27 -0
  186. package/skills/doc-files/js/docs/docgen-extract.md +29 -0
  187. package/skills/doc-files/js/docs/docgen-files-batch.md +25 -0
  188. package/skills/doc-files/js/docs/docgen-gen.md +30 -0
  189. package/skills/doc-files/js/docs/docgen-prompts.md +32 -0
  190. package/skills/doc-files/js/docs/docgen-scan.md +25 -0
  191. package/skills/doc-files/js/units-js.mjs +139 -0
  192. package/skills/doc-files/js/units.mjs +19 -0
  193. package/skills/doc-files/meta.json +1 -0
  194. package/skills/fix/js/docs/llm-worker.md +6 -0
  195. package/skills/fix/js/docs/orchestrator.md +6 -0
  196. package/skills/fix/js/llm-worker.mjs +3 -3
  197. package/skills/fix/js/orchestrator.mjs +1 -1
  198. package/skills/start-check/js/check.mjs +5 -3
  199. package/skills/start-check/js/docs/check.md +6 -0
  200. package/skills/docgen/SKILL.md +0 -224
  201. package/skills/docgen/bench/etalon/firebase_hosting.md +0 -19
  202. package/skills/docgen/bench/etalon/k8s-tree.md +0 -24
  203. package/skills/docgen/bench/etalon/overlay-paths.md +0 -24
  204. package/skills/docgen/js/docgen-batch-omlx.mjs +0 -82
  205. package/skills/docgen/js/docgen-batch.mjs +0 -95
  206. package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +0 -95
  207. package/skills/docgen/js/docgen-gen.mjs +0 -306
  208. package/skills/docgen/js/docs/docgen-extract.md +0 -28
  209. package/skills/docgen/js/docs/docgen-gen.md +0 -41
  210. package/skills/docgen/js/docs/docgen-ignore.md +0 -24
  211. package/skills/docgen/js/docs/docgen-prompts.md +0 -24
  212. package/skills/docgen/js/docs/docgen-scan.md +0 -48
  213. /package/skills/{docgen → doc-aggregate}/meta.json +0 -0
  214. /package/skills/{docgen → doc-files}/js/docgen-ignore.mjs +0 -0
@@ -1,295 +1,89 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/capacitor/js/platforms.mjs
4
+ crc: eb8d6293
5
+ score: 100
6
+ ---
7
+
1
8
  # platforms.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль `platforms.mjs` реалізує **check** для правила `capacitor.mdc`: перевіряє, що проєкт-застосунок на базі **Capacitor** відповідає політикам монорепо Nitra. Файл експортує асинхронну функцію `check(cwd)`, яка повертає **exit-код** (0 ok, 1 fail), а також низку допоміжних чистих функцій для розбору **npm**-діапазонів версій, обходу `package.json` та пошуку `Podfile` у каталозі `ios/`.
6
-
7
- Перевірка послідовно виконує три блоки логіки:
8
-
9
- 1. **Виявлення Capacitor у репозиторії.** Capacitor вважається задіяним, якщо в корені присутній один із файлів `capacitor.config.json` / `capacitor.config.ts` / `capacitor.config.mjs`, **або** хоч у одному `package.json` (рекурсивний обхід дерева з пропуском типових каталогів) задекларовано пакет із префіксом `@capacitor/` у будь-якому блоці залежностей (`dependencies`, `devDependencies`, `optionalDependencies`, `peerDependencies`). Якщо ознак немає — check одразу повертає **pass** і код **0**, не вимагаючи жодних дій.
10
- 2. **Перевірка мінімальної версії `@capacitor/core` ≥ 8.** Для кожного `package.json`, який оголошує `@capacitor/core`, обчислюється **нижня межа major** з рядка npm-діапазону. Якщо вона менша за `MIN_CAPACITOR_MAJOR = 8`, або діапазон не вдалося визначити (`*`, `latest`, `x`, незрозумілий синтаксис) — це fail; повідомлення підказує задати, наприклад, `^8.0.0`. Якщо `capacitor.config.*` знайдено, а `@capacitor/core` у дереві відсутній — теж fail.
11
- 3. **iOS / Podfile.** За політикою `capacitor.mdc` iOS-частина Capacitor-застосунку повинна збиратися лише через **SPM**, без CocoaPods. Рекурсивний обхід `ios/` (пропускаючи `Pods`, `build`, `DerivedData`) шукає перший `Podfile`. Якщо `Podfile` є, він вважається порушенням, **окрім** випадку коли в кореневому `package.json` або в `capacitor.config.{json,ts,mjs}` присутній об’єкт `nitra` із прапором `iosCocoaPodsBecausePluginsLackSpm: true` або `iosCocoaPodsAllowed: true`. Якщо каталогу `ios/` немає — умова не застосовується.
12
-
13
- Усі повідомлення про результат виводяться через `createCheckReporter()` зі спільного хелпера `scripts/lib/check-reporter.mjs`.
14
-
15
- ## Експорти / API
16
-
17
- Файл експортує іменовані символи (без default export):
18
-
19
- - `capacitorSegmentMinMajor(segment)` — мінімальний **major** для одного OR-сегмента npm-діапазону.
20
- - `capacitorVersionRangeMinMajor(versionRange)` — мінімальний **major** для повного діапазону, з підтримкою `||`.
21
- - `isCapacitorCoreVersionAtLeast8(versionRange, min?)` — булеан-предикат: чи нижня межа діапазону `≥ min` (за замовчуванням `MIN_CAPACITOR_MAJOR`).
22
- - `recordCapacitorFromOnePackageJson(absPath, root, out)` — асинхронно прочитати один `package.json` і поповнити акумулятор.
23
- - `collectCapacitorDataFromAllPackageJson(root, out)` — рекурсивно обійти всі `package.json` у репозиторії, агрегуючи `byPath` і `anyCapacitor`.
24
- - `hasCapacitorConfigInRoot(root)` — синхронно перевірити наявність `capacitor.config.{json,ts,mjs}` у корені.
25
- - `isCapacitorRelevantForCheck(root, anyCapacitor)` — чи варто застосовувати правила Capacitor взагалі.
26
- - `walkIosForPodfileSkipPods(root, dir, onPodfileRelative)` — рекурсивний пошук `Podfile` під `ios/` із пропуском службових тек.
27
- - `findFirstPodfileUnderIosExcludingPods(root)` — повертає **найкоротший** posix-relative шлях до першого знайденого `Podfile` (або `null`).
28
- - `nitrAObjectAllowsIosCocoaPods(o)` — предикат для об’єкта `nitra`: чи дозволено CocoaPods.
29
- - `check(cwd?)` — головна функція **check**; повертає **exit-код**.
30
-
31
- Внутрішні (неекспортовані) функції: `firstVersionMajorFromNpmValue`, `reportOneCapacitorCoreRange`, `recordCapacitorFromDependencyObject`, `extractNitraObjectBodySource`, `nitraObjectBodyStringAllowsCocoaPodsExempt`, `pathJsonShowsNitraCocoapodsExempt`, `capacitorConfigTsMjsNitraCocoapodsExempt`, `isIosCocoaPodsExemptByNitraConfig`.
32
-
33
- Константи модульного рівня:
34
-
35
- - `MIN_CAPACITOR_MAJOR = 8` — мінімальний допустимий **major** Capacitor.
36
- - `IGNORED_DIRS_FOR_PACKAGE_JSON` — `Set` каталогів, які пропускаються при обході (`node_modules`, `.git`, `dist`, `coverage`, `Pods`, `.turbo`, `.next`, `build`).
37
- - Регулярки: `NPM_OR_PARTS_RE` (`\s*\|\|\s*`), `NPM_HYPHEN_RANGE_RE` (`^(.+?)\s+-\s+(.+)$`), `FIRST_VERSION_NUM_RE` (`^(?:v)?(\d+)`), `PREFIX_GEQ_RE` (`^>=\s*`), `PREFIX_GT_RE` (`^>\s*`), `STRIP_CARET_TILDE_EQ_RE` (`^[=^~]+\s*`), `RE_NITRA_CONFIG_OBJECT_LEAD_IN` (початок блоку `nitra: {` у TS/MJS), `RE_COCOAPODS_EXEMPT_SPM` (`iosCocoaPodsBecausePluginsLackSpm: true`), `RE_COCOAPODS_EXEMPT_ALLOW` (`iosCocoaPodsAllowed: true`).
38
-
39
- ## Функції
40
-
41
- ### `capacitorSegmentMinMajor(segment)`
42
-
43
- - **Сигнатура:** `(segment: string) => number | null`
44
- - **Параметри:** `segment` — одна частина npm-діапазону (без `||` всередині).
45
- - **Повертає:** мінімальний **major**, який задовольняється сегментом; `null`, якщо сегмент — `*`, `x` (case-insensitive) або `latest`, або якщо вхід не рядок чи порожній.
46
- - **Логіка:**
47
- - Не-рядок або порожній рядок після `trim()` → `null`.
48
- - `*`, `x` (нижній регістр), `latest` → `null` (невизначена нижня межа).
49
- - Префікс `<` або `<=` → `0` (теоретично може допускати дуже старі major-и).
50
- - Префікс `>` (але не `>=`) → витягає число з решти рядка через `firstVersionMajorFromNpmValue`.
51
- - Дефіс-діапазон `a - b` (`NPM_HYPHEN_RANGE_RE`) → бере major лівої межі.
52
- - Префікси `^`, `~`, `=` → знімає їх і повертає major першого числа.
53
- - Префікс `>=` → знімає його і повертає major.
54
- - Інакше — повертає major першого числа в рядку.
55
- - **Side effects:** немає (чиста функція).
56
-
57
- ### `firstVersionMajorFromNpmValue(t)` _(внутрішня)_
58
-
59
- - **Сигнатура:** `(t: string) => number | null`
60
- - **Параметри:** `t` — фрагмент рядка версії без префікса операторів.
61
- - **Повертає:** перше ціле число (major), знайдене регуляркою `FIRST_VERSION_NUM_RE` (опційний префікс `v`); `null`, якщо число не знайдено або рядок порожній.
62
- - **Side effects:** немає.
63
-
64
- ### `capacitorVersionRangeMinMajor(versionRange)`
65
-
66
- - **Сигнатура:** `(versionRange: string) => number | null`
67
- - **Параметри:** `versionRange` — повне значення поля для `@capacitor/core` з `package.json`.
68
- - **Повертає:** найменший (нижній) **major** серед усіх OR-частин; `null`, якщо хоча б одна частина — `*` / `latest` / `x` / нерозпізнана (тобто діапазон вважається небезпечним).
69
- - **Логіка:** розбиває за `||`, кожну частину пропускає через `capacitorSegmentMinMajor`, ранній вихід із `null` при першій невизначеній; інакше — мінімум серед усіх отриманих чисел.
70
- - **Side effects:** немає.
71
-
72
- ### `isCapacitorCoreVersionAtLeast8(versionRange, min = MIN_CAPACITOR_MAJOR)`
73
-
74
- - **Сигнатура:** `(versionRange: string, min?: number) => boolean`
75
- - **Параметри:** `versionRange` — рядок версії; `min` — нижній поріг major (за замовчуванням **8**).
76
- - **Повертає:** `true`, якщо нижня межа діапазону визначена і `>= min`; інакше — `false` (зокрема для `*`, `latest`).
77
- - **Side effects:** немає.
78
-
79
- ### `reportOneCapacitorCoreRange(fail, pass, rel, range)` _(внутрішня)_
80
-
81
- - **Сигнатура:** `(fail: (m: string) => void, pass: (m: string) => void, rel: string, range: string) => void`
82
- - **Параметри:** `fail`, `pass` — друк-колбеки reporter; `rel` — posix-relative шлях `package.json`; `range` — значення `@capacitor/core`.
83
- - **Повертає:** `void`.
84
- - **Side effects:** викликає `pass(...)` або `fail(...)` зі сформованим повідомленням, у якому згадано `MIN_CAPACITOR_MAJOR` та рекомендацію `^8.0.0`.
85
-
86
- ### `recordCapacitorFromDependencyObject(rel, obj, out)` _(внутрішня)_
87
-
88
- - **Сигнатура:** `(rel: string, obj: Record<string, unknown>, out: { byPath: Map<string, string>, anyCapacitor: boolean }) => void`
89
- - **Параметри:** `rel` — relative-шлях `package.json`; `obj` — один із блоків залежностей; `out` — акумулятор.
90
- - **Повертає:** `void`.
91
- - **Side effects:**
92
- - Виставляє `out.anyCapacitor = true`, якщо знайдено будь-який ключ, що починається з `@capacitor/`.
93
- - Якщо ключ — рівно `@capacitor/core` і значення — непорожній рядок, кладе пару `rel → range` в `out.byPath`. Повторні записи з різних блоків залежностей перезаписують одне одного (останній блок перемагає в порядку `dependencies → devDependencies → optionalDependencies → peerDependencies`).
94
-
95
- ### `recordCapacitorFromOnePackageJson(absPath, root, out)`
96
-
97
- - **Сигнатура:** `(absPath: string, root: string, out: { byPath: Map<string, string>, anyCapacitor: boolean }) => Promise<void>`
98
- - **Параметри:** `absPath` — абсолютний шлях до `package.json`; `root` — корінь репозиторію; `out` — акумулятор.
99
- - **Повертає:** `Promise<void>`.
100
- - **Side effects:**
101
- - Читає файл через `readFile(absPath, 'utf8')`; будь-яка помилка вводу/виводу мовчазно повертає керування (файл пропускається).
102
- - Парсить JSON; помилка парсингу — теж мовчазне пропускання.
103
- - Обчислює posix-relative шлях відносно `root` (з заміною `\` на `/`); якщо `relative()` повертає порожній рядок — підставляє `absPath`.
104
- - Для кожного блоку залежностей, що є об’єктом (не масив, не `null`/`undefined`), викликає `recordCapacitorFromDependencyObject`.
105
-
106
- ### `collectCapacitorDataFromAllPackageJson(root, out)`
107
-
108
- - **Сигнатура:** `(root: string, out: { byPath: Map<string, string>, anyCapacitor: boolean }) => Promise<void>`
109
- - **Параметри:** `root` — корінь обходу; `out` — акумулятор (буде ініціалізовано).
110
- - **Повертає:** `Promise<void>`.
111
- - **Side effects:**
112
- - На початку **скидає** `out.anyCapacitor = false`; якщо `out.byPath` уже існує — викликає `.clear()`, інакше створює нову `Map`.
113
- - Внутрішня функція `walk(dir)` робить `readdir(dir, { withFileTypes: true })`; помилку каталогу мовчки ігнорує.
114
- - Для кожного запису: якщо це каталог і його імені немає в `IGNORED_DIRS_FOR_PACKAGE_JSON` — рекурсивно входить; якщо це файл `package.json` — викликає `recordCapacitorFromOnePackageJson`.
115
- - Інші типи файлів (`isFile` зі значенням false, симлінки тощо) пропускаються — записи з `entry.isDirectory() === false && entry.isFile() === false` не оброблюються.
116
-
117
- ### `hasCapacitorConfigInRoot(root)`
118
-
119
- - **Сигнатура:** `(root: string) => boolean`
120
- - **Параметри:** `root` — корінь репозиторію.
121
- - **Повертає:** `true`, якщо хоча б один із файлів `capacitor.config.json`, `capacitor.config.ts`, `capacitor.config.mjs` існує в корені.
122
- - **Side effects:** виконує `existsSync` (синхронний доступ до файлової системи).
123
-
124
- ### `isCapacitorRelevantForCheck(root, anyCapacitor)`
125
-
126
- - **Сигнатура:** `(root: string, anyCapacitor: boolean) => boolean`
127
- - **Параметри:** `root` — корінь; `anyCapacitor` — чи зустрічався `@capacitor/` у `package.json`.
128
- - **Повертає:** `true`, якщо є capacitor-конфіг у корені **або** `anyCapacitor === true`.
129
- - **Side effects:** виклик `hasCapacitorConfigInRoot` (`existsSync`).
130
-
131
- ### `walkIosForPodfileSkipPods(root, dir, onPodfileRelative)`
132
-
133
- - **Сигнатура:** `(root: string, dir: string, onPodfileRelative: (rel: string) => void) => Promise<boolean>`
134
- - **Параметри:** `root` — корінь репозиторію; `dir` — поточний каталог обходу; `onPodfileRelative` — колбек із posix-relative шляхом знайденого `Podfile`.
135
- - **Повертає:** `Promise<boolean>` — `true`, якщо в дереві знайдено принаймні один `Podfile` (повернення відбувається при **першому** знайденому всередині поточного `dir` або в його підкаталогах).
136
- - **Логіка:**
137
- - `readdir(dir, { withFileTypes: true })`; помилка → `false`.
138
- - Пропускає підкаталоги/файли з іменами `Pods`, `build`, `DerivedData` (порівняння за іменем).
139
- - Якщо запис — файл із іменем `Podfile`: викликає колбек із posix-relative шляхом і повертає `true` (ранній вихід — інші записи поточного каталогу не оглядаються).
140
- - Якщо запис — каталог: рекурсивно входить; якщо нащадок повернув `true`, передається ланцюжком назовні.
141
- - **Side effects:** дисковий I/O (`readdir`), виклики `onPodfileRelative`.
142
-
143
- ### `findFirstPodfileUnderIosExcludingPods(root)`
144
-
145
- - **Сигнатура:** `(root: string) => Promise<string | null>`
146
- - **Параметри:** `root` — корінь репозиторію.
147
- - **Повертає:** posix-relative шлях до першого виявленого `Podfile` під `ios/` (а саме — **найкоротший** із тих, що були передані в колбек у межах того самого виклику обходу) або `null`, якщо `ios/` немає чи в ньому не знайдено `Podfile` поза `Pods/`.
148
- - **Логіка:** перевіряє існування `ios/` через `existsSync`. Викликає `walkIosForPodfileSkipPods` з колбеком, який утримує лише шлях із мінімальною довжиною рядка (`rel.length < first.length`). Через ранній вихід `walkIosForPodfileSkipPods` зазвичай колбек спрацьовує один раз; вибір «найкоротшого» — захист на випадок зміни поведінки обходу.
149
- - **Side effects:** дисковий I/O.
150
-
151
- ### `nitrAObjectAllowsIosCocoaPods(o)`
152
-
153
- - **Сигнатура:** `(o: unknown) => boolean`
154
- - **Параметри:** `o` — кандидат у об’єкт `nitra`.
155
- - **Повертає:** `true`, якщо `o` — звичайний об’єкт (не `null`, не масив) і містить `iosCocoaPodsBecausePluginsLackSpm === true` або `iosCocoaPodsAllowed === true`; інакше — `false`.
156
- - **Side effects:** немає.
157
- - **Зауваження:** назва функції написана з нестандартною капіталізацією `nitrA` — використовується саме так на місці виклику.
158
-
159
- ### `extractNitraObjectBodySource(source)` _(внутрішня)_
160
-
161
- - **Сигнатура:** `(source: string) => string | null`
162
- - **Параметри:** `source` — текст файлу `capacitor.config.ts` або `capacitor.config.mjs`.
163
- - **Повертає:** підрядок `{ ... }`, що відповідає тілу об’єкта після `nitra:` / `"nitra":` / `'nitra':` (перше входження), збалансованому за фігурними дужками; `null`, якщо вхід не знайдено або не вдалося збалансувати дужки.
164
- - **Логіка:** `RE_NITRA_CONFIG_OBJECT_LEAD_IN.exec(source)` знаходить початок; далі вручну лічильник `d` балансу `{`/`}` від першої `{` до зустрічної `}` на нульовому рівні.
165
- - **Side effects:** немає.
166
- - **Обмеження:** не парсить TS/MJS повноцінно; ігнорує можливі `{` / `}` усередині рядків чи коментарів, що теоретично може дати хибний баланс на нетипових вхідних даних. Для штатних `capacitor.config.*` цього достатньо.
167
-
168
- ### `nitraObjectBodyStringAllowsCocoaPodsExempt(objectBody)` _(внутрішня)_
169
-
170
- - **Сигнатура:** `(objectBody: string) => boolean`
171
- - **Параметри:** `objectBody` — текст тіла об’єкта `nitra`.
172
- - **Повертає:** `true`, якщо в підрядку є `iosCocoaPodsBecausePluginsLackSpm: true` або `iosCocoaPodsAllowed: true` (регулярки `RE_COCOAPODS_EXEMPT_SPM`, `RE_COCOAPODS_EXEMPT_ALLOW`).
173
- - **Side effects:** немає.
174
-
175
- ### `pathJsonShowsNitraCocoapodsExempt(absPath)` _(внутрішня)_
176
-
177
- - **Сигнатура:** `(absPath: string) => Promise<boolean>`
178
- - **Параметри:** `absPath` — повний шлях до JSON-файла (`package.json` або `capacitor.config.json`).
179
- - **Повертає:** `true`, якщо файл існує, валідно парситься як JSON, і його ключ `nitra` задовольняє `nitrAObjectAllowsIosCocoaPods`.
180
- - **Логіка:** `existsSync` → `readFile` → `JSON.parse`. Будь-яка помилка читання/парсингу повертає `false`.
181
- - **Side effects:** дисковий I/O.
182
-
183
- ### `capacitorConfigTsMjsNitraCocoapodsExempt(root)` _(внутрішня)_
184
-
185
- - **Сигнатура:** `(root: string) => Promise<boolean>`
186
- - **Параметри:** `root` — корінь репозиторію.
187
- - **Повертає:** `true`, якщо `capacitor.config.ts` або `capacitor.config.mjs` (у такій послідовності) існує та містить блок `nitra: { ... }` з прапором винятку.
188
- - **Логіка:** для кожного імені викликає `existsSync`, читає вміст, через `extractNitraObjectBodySource` дістає тіло і перевіряє `nitraObjectBodyStringAllowsCocoaPodsExempt`. Знайдено → `true`; інакше після обох — `false`.
189
- - **Side effects:** дисковий I/O. Винятки `readFile` не перехоплюються, тому пошкоджений файл може кинути помилку наверх (єдина функція в файлі, що не загортає `readFile` у `try/catch`).
190
-
191
- ### `isIosCocoaPodsExemptByNitraConfig(root)` _(внутрішня)_
192
-
193
- - **Сигнатура:** `(root: string) => Promise<boolean>`
194
- - **Параметри:** `root` — корінь репозиторію.
195
- - **Повертає:** `true`, якщо знайдено валідний виняток `nitra` у `package.json`, або в `capacitor.config.json`, або в `capacitor.config.{ts,mjs}` (перевіряється в такому порядку, з раннім виходом).
196
- - **Side effects:** дисковий I/O.
12
+ Модуль інспектує та збирає дані конфігурацій Capacitor для оцінки сумісності версій. Він використовується для перевірки наявності та відповідності версій Capacitor, необхідних для коректної роботи з iOS-проєктами. Функції, такі як `collectCapacitorDataFromAllPackageJson`, забезпечують збір необхідної інформації. Модуль спирається на конфігурації, визначені у файлі `.config.json`. Функція `check` та `isCapacitorRelevantForCheck` застосовуються для визначення релевантності конфігурації. (capacitor.mdc)
197
13
 
198
- ### `check(cwd = process.cwd())`
14
+ ## Поведінка
199
15
 
200
- - **Сигнатура:** `(cwd?: string) => Promise<number>`
201
- - **Параметри:** `cwd` корінь репозиторію для перевірки; за замовчуванням `process.cwd()`.
202
- - **Повертає:** exit-код від `reporter.getExitCode()`: **0** — усі повідомлення лише `pass`; **1** — було щонайменше одне `fail`.
203
- - **Side effects:**
204
- - Створює reporter через `createCheckReporter()` і викликає `pass(...)` / `fail(...)` для друку повідомлень користувачу.
205
- - Викликає `collectCapacitorDataFromAllPackageJson(root, acc)` — рекурсивний дисковий обхід усіх `package.json`.
206
- - Викликає `findFirstPodfileUnderIosExcludingPods(root)` — обхід `ios/`.
207
- - Викликає `isIosCocoaPodsExemptByNitraConfig(root)` лише якщо `podfileRel !== null` (мінімізує читання конфігів).
208
- - **Шлях виконання:**
209
- 1. `acc = { byPath: new Map(), anyCapacitor: false }`; зібрати дані з усіх `package.json`.
210
- 2. Якщо `isCapacitorRelevantForCheck(root, anyCapacitor) === false` — `pass('Capacitor не виявлено …')` і вихід **0**.
211
- 3. Інакше `pass('Проєкт з ознаками Capacitor — застосовую capacitor.mdc')`.
212
- 4. Якщо `byPath.size === 0` (є конфіг, але немає `@capacitor/core` у дереві) — `fail` з підказкою додати `^8.0.0`. Інакше — для кожної пари `[rel, range]` викликати `reportOneCapacitorCoreRange`.
213
- 5. Подія iOS:
214
- - Якщо `findFirstPodfileUnderIosExcludingPods(root)` повернув `null` і `ios/` існує — `pass('ios/ без Podfile поза Pods/ …')`.
215
- - Якщо `ios/` не існує — `pass('каталог ios/ не знайдено …')`.
216
- - Якщо `Podfile` знайдено і `isIosCocoaPodsExemptByNitraConfig(root) === true` — `pass(... — дозволено виняток ...)`.
217
- - Інакше — `fail(... використовуй лише SPM ...)`.
218
- 6. Повернути `getExitCode()`.
16
+ capacitorSegmentMinMajor
17
+ Витягує мінімальний мажорний номер з частини діапазону npm версій
219
18
 
220
- ## Залежності
19
+ capacitorVersionRangeMinMajor
20
+ Обчислює мінімальний мажорний номер для повного діапазону npm версій з урахуванням `||`
221
21
 
222
- **Стандартна бібліотека Node.js:**
22
+ isCapacitorCoreVersionAtLeast8
23
+ Перевіряє, чи нижня межа версії Capacitor є більшою або дорівнює заданому мінімуму
223
24
 
224
- - `node:fs` — `existsSync` (синхронна перевірка існування файлу/каталогу).
225
- - `node:fs/promises` `readdir` `withFileTypes: true`), `readFile` (utf-8).
226
- - `node:path` — `join`, `relative`.
25
+ recordCapacitorFromOnePackageJson
26
+ Записує інформацію про залежності Capacitor у накопичувач
227
27
 
228
- **Локальні модулі:**
28
+ collectCapacitorDataFromAllPackageJson
29
+ Рекурсивно шукає та збирає інформацію про залежності Capacitor з усіх `package.json` у репозиторії
229
30
 
230
- - `../../../scripts/lib/check-reporter.mjs` — `createCheckReporter` (фабрика об’єкта з `pass`, `fail`, `getExitCode`; формує консольний звіт і веде стан коду виходу).
31
+ hasCapacitorConfigInRoot
32
+ Перевіряє наявність конфігураційних файлів Capacitor у корені репозиторію
231
33
 
232
- **Зовнішні npm-пакети:** немає.
34
+ isCapacitorRelevantForCheck
35
+ Визначає, чи потрібно застосовувати перевірку Capacitor на основі наявності конфігурації або залежностей
233
36
 
234
- **Системні припущення:**
37
+ walkIosForPodfileSkipPods
38
+ Рекурсивно шукає файли `Podfile` у каталозі `ios`, ігноруючи папки `Pods`, `build` та `DerivedData`
235
39
 
236
- - Виклик відбувається з кореня репозиторію (або `cwd` передано явно).
237
- - Файлова система POSIX-сумісна або Windows (всі шляхи нормалізуються через `replaceAll('\\', '/')` до posix-форми у звітах).
40
+ findFirstPodfileUnderIosExcludingPods
41
+ Шукає перший знайдений `Podfile` у каталозі `ios`, ухиляючись від кешу CocoaPods
238
42
 
239
- ## Потік виконання / Використання
43
+ nitrAObjectAllowsIosCocoaPods
44
+ Перевіряє, чи дозволяє об'єкт `nitra` використання `Podfile` на iOS через спеціальні прапори
240
45
 
241
- Файл призначений для виклику як check-функція в межах CLI чи runner правил `npm/rules/capacitor`. Типовий сценарій:
46
+ extractNitraObjectBodySource
47
+ Витягує текст тіла об'єкта `{...}` після маркера `nitra:` у конфігураційному файлі
242
48
 
243
- 1. Зовнішній runner імпортує `check` із `platforms.mjs`.
244
- 2. Викликає `await check()` або `await check(repoRoot)`.
245
- 3. Під час виконання у консоль друкуються рядки звіту через `createCheckReporter()` (pass/fail).
246
- 4. Повернений Promise розв’язується числом `0` або `1`, яке runner передає в `process.exit(...)`.
49
+ nitraObjectBodyStringAllowsCocoaPodsExempt
50
+ Перевіряє, чи містить витягнутий текст виняток, який дозволяє пропуск аналізу SPM
247
51
 
248
- Приклад фактичного виклику (наприклад, у CLI-обгортці):
52
+ pathJsonShowsNitraCocoapodsExempt
53
+ Перевіряє, чи містить об'єкт `nitra` у JSON-файлі виняток, який дозволяє пропуск аналізу SPM
249
54
 
250
- ```js
251
- import { check } from './platforms.mjs'
55
+ capacitorConfigTsMjsNitraCocoapodsExempt
56
+ Перевіряє, чи містить конфігураційні файли `.ts` або `.mjs` виняток, який дозволяє пропуск аналізу SPM
252
57
 
253
- const exitCode = await check(process.cwd())
254
- process.exit(exitCode)
255
- ```
58
+ isIosCocoaPodsExemptByNitraConfig
59
+ Перевіряє, чи дозволяє конфігурація `nitra` використання `Podfile` на iOS
256
60
 
257
- Окремі експортовані функції зручні для модульних тестів і для повторного використання в інших правилах:
61
+ check
62
+ Виконує повну перевірку конфігурації Capacitor, включаючи перевірку залежностей та налаштувань iOS
258
63
 
259
- - `capacitorVersionRangeMinMajor`, `isCapacitorCoreVersionAtLeast8`, `capacitorSegmentMinMajor` суто строкові утиліти без I/O; тести подають синтетичні діапазони.
260
- - `recordCapacitorFromOnePackageJson` і `collectCapacitorDataFromAllPackageJson` — інтеграційні утиліти над `package.json`; вимагають реальної або змодельованої файлової системи (через тимчасові теки тощо).
261
- - `walkIosForPodfileSkipPods`, `findFirstPodfileUnderIosExcludingPods` — обхід `ios/`.
262
- - `nitrAObjectAllowsIosCocoaPods` — чистий предикат для об’єкта `nitra`.
263
- - `hasCapacitorConfigInRoot`, `isCapacitorRelevantForCheck` — швидкі синхронні перевірки наявності конфігів.
64
+ Повертає помилку, якщо не знайдено необхідної залежності `@capacitor/core` з версією, сумісною з `MIN_CAPACITOR_MAJOR`
264
65
 
265
- **Поведінкові інваріанти:**
66
+ Повертає помилку, якщо знайдено `Podfile` на iOS, який не дозволяє використання CocoaPods без винятку `nitra`
266
67
 
267
- - Жоден `package.json`, який не валідується як JSON, не призводить до помилки `check`; такі файли мовчки пропускаються.
268
- - Каталоги з `IGNORED_DIRS_FOR_PACKAGE_JSON` ніколи не оглядаються, у тому числі `node_modules` — тобто аналізуються лише власні `package.json` репозиторію та воркспейсів, але не вкладені пакети залежностей.
269
- - Обхід `ios/` ніколи не входить у `Pods`, `build`, `DerivedData` — це принципово для коректної політики (SPM-only): артефакти CocoaPods, що могли залишитися від попередніх збірок, не повинні впливати на result.
270
- - Рішення «диапазон допустимий» приймається консервативно: будь-яка невизначеність (`*`, `latest`, неможливість витягти число) трактується як **не** допустимо.
271
- - Виняток для CocoaPods читається з трьох джерел у строгому порядку: `package.json` → `capacitor.config.json` → `capacitor.config.{ts,mjs}` (з раннім `true`).
68
+ ## Публічний API
272
69
 
273
- ## Rebuild Test
70
+ capacitorSegmentMinMajor визначає нижню межу для однієї частини діапазону npm.
71
+ capacitorVersionRangeMinMajor — визначає мінімальну можливу (нижню) major-версію для повного діапазону npm, включаючи `||`.
72
+ isCapacitorCoreVersionAtLeast8 — перевіряє, чи відповідає версія ядру Capacitor мінімальному рівню 8.
73
+ recordCapacitorFromOnePackageJson — записує дані Capacitor з одного файлу `package.json`.
74
+ collectCapacitorDataFromAllPackageJson — збирає дані Capacitor з усіх `package.json` у дереві, накопичуючи `byPath` та `anyCapacitor`.
75
+ hasCapacitorConfigInRoot — перевіряє наявність конфігурації Capacitor у кореневому файлі.
76
+ isCapacitorRelevantForCheck — визначає, чи слід застосовувати правила, залежно від наявності конфігу або `@capacitor/` у залежностях.
77
+ walkIosForPodfileSkipPods — рекурсивно шукає `Podfile` у директорії `ios/`, ігноруючи директорії `Pods` (кеш CocoaPods) та типові build-каталоги.
78
+ findFirstPodfileUnderIosExcludingPods — знаходить перший `Podfile` у директорії `ios/`, пропуская директорії `Pods`.
79
+ nitrAObjectAllowsIosCocoaPods — перевіряє, чи дозволяє об’єкт `nitra` використовувати `Podfile` (CocoaPods) на iOS (див. (capacitor.mdc); `@nitra/SPM` не аналізується).
80
+ check — виконує загальну перевірку.
274
81
 
275
- Зібрані з цього документа ключові факти, достатні для відтворення поведінки:
82
+ ## Гарантії поведінки
276
83
 
277
- - Експортується `check(cwd?)` із поверненням `Promise<number>` (0/1) на основі `createCheckReporter`.
278
- - Capacitor вважається релевантним, якщо в корені є `capacitor.config.{json,ts,mjs}` **АБО** у будь-якому `package.json` (рекурсивно, ігноруючи `node_modules`, `.git`, `dist`, `coverage`, `Pods`, `.turbo`, `.next`, `build`) є залежність з префіксом `@capacitor/` у `dependencies` / `devDependencies` / `optionalDependencies` / `peerDependencies`.
279
- - Мінімальний допустимий major Capacitor **8** (`MIN_CAPACITOR_MAJOR`).
280
- - Алгоритм обчислення мінімального major npm-діапазону:
281
- - Розбити за `\s*\|\|\s*` на сегменти.
282
- - У сегменті: `*` / `x` (low) / `latest` → невизначено (`null`), що означає fail для всього діапазону.
283
- - `<` / `<=` → 0.
284
- - `>` (не `>=`) → major першого числа після оператора.
285
- - `a - b` (з `\s+-\s+`) → major лівої межі.
286
- - `^`, `~`, `=` → major першого числа після префікса.
287
- - `>=` → major першого числа після префікса.
288
- - Інакше — major першого числа в сегменті.
289
- - Регулярка для першого числа: `^(?:v)?(\d+)` (опційний `v`).
290
- - Результат для діапазону — мінімум серед сегментів; якщо будь-який сегмент дав `null`, повертається `null`.
291
- - `isCapacitorCoreVersionAtLeast8(range)` ⇔ `capacitorVersionRangeMinMajor(range) >= 8`.
292
- - iOS-перевірка: знайти перший `Podfile` під `ios/`, пропускаючи `Pods`, `build`, `DerivedData`. Якщо знайдено — fail, **окрім** випадку, коли `package.json.nitra` або `capacitor.config.json.nitra` (як JSON-об’єкт) має `iosCocoaPodsBecausePluginsLackSpm === true` або `iosCocoaPodsAllowed === true`, **або** в `capacitor.config.ts` / `capacitor.config.mjs` фрагмент тіла об’єкта `nitra: { ... }` містить `iosCocoaPodsBecausePluginsLackSpm: true` чи `iosCocoaPodsAllowed: true`.
293
- - Якщо `ios/` немає — iOS-блок повністю пропускається (`pass` із поясненням).
294
- - Якщо capacitor-конфіг є, а `@capacitor/core` не знайдено в жодному `package.json` — fail (треба додати залежність з версією `^8.0.0`).
295
- - Помилки I/O і JSON у `package.json` / JSON-конфігах не падають check, а трактуються як «нічого не знайдено» в цій точці.
84
+ - Read-only: файл не виконує операцій запису у файлову систему.
85
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
86
+ - За невдалої перевірки повертає `false`/`null` замість винятку.
87
+ - Кешує результати в межах одного прогону.
88
+ - Свідомо пропускає шляхи: `.git`, `node_modules`.
89
+ - Не звертається до мережі.
@@ -1,3 +1,9 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/changelog/fix.mjs
4
+ crc: 12fc1644
5
+ ---
6
+
1
7
  # fix.mjs — точка входу правила `changelog`
2
8
 
3
9
  ## Огляд