@nitra/cursor 5.1.0 → 5.2.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 (204) 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 +12 -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/omlx.md +32 -0
  9. package/lib/llm.mjs +137 -0
  10. package/lib/omlx.mjs +49 -4
  11. package/package.json +1 -1
  12. package/rules/abie/docs/fix.md +6 -0
  13. package/rules/abie/js/docs/applies.md +6 -0
  14. package/rules/abie/js/docs/env_dns.md +25 -22
  15. package/rules/abie/js/docs/firebase_hosting.md +6 -0
  16. package/rules/abie/js/docs/hc_pairing.md +21 -25
  17. package/rules/abie/js/docs/ua_http_route.md +27 -19
  18. package/rules/abie/js/docs/ua_node_selector.md +24 -19
  19. package/rules/abie/lib/docs/enabled.md +13 -7
  20. package/rules/abie/lib/docs/env-dns.md +9 -3
  21. package/rules/abie/lib/docs/hc-yaml.md +6 -0
  22. package/rules/abie/lib/docs/http-route.md +6 -0
  23. package/rules/abie/lib/docs/k8s-tree.md +6 -0
  24. package/rules/abie/lib/docs/kustomization-patches.md +6 -0
  25. package/rules/abie/lib/docs/overlay-paths.md +6 -0
  26. package/rules/abie/lib/docs/yaml.md +6 -0
  27. package/rules/adr/docs/fix.md +6 -0
  28. package/rules/adr/js/docs/hooks.md +29 -244
  29. package/rules/bun/docs/fix.md +6 -0
  30. package/rules/bun/js/docs/layout.md +37 -375
  31. package/rules/capacitor/docs/fix.md +22 -108
  32. package/rules/capacitor/js/docs/platforms.md +62 -268
  33. package/rules/changelog/docs/fix.md +6 -0
  34. package/rules/changelog/lib/docs/package-manifest.md +6 -0
  35. package/rules/ci4/docs/fix.md +23 -165
  36. package/rules/ci4/js/docs/marksman_config.md +9 -1
  37. package/rules/docker/docs/fix.md +6 -0
  38. package/rules/docker/js/docs/lint.md +55 -239
  39. package/rules/docker/lib/docs/docker-hadolint.md +6 -0
  40. package/rules/docker/lib/docs/docker-mirror.md +6 -0
  41. package/rules/docker/lib/docs/docker-native-addon.md +6 -0
  42. package/rules/docker/lib/docs/docker-nginx-user.md +6 -0
  43. package/rules/docker/lint/docs/lint.md +9 -1
  44. package/rules/efes/docs/fix.md +6 -0
  45. package/rules/ga/lint/docs/lint.md +6 -0
  46. package/rules/graphql/docs/fix.md +6 -0
  47. package/rules/graphql/lib/docs/graphql-gql-scan.md +6 -0
  48. package/rules/image-avif/docs/fix.md +6 -0
  49. package/rules/image-avif/js/docs/avif_generation.md +6 -0
  50. package/rules/js-bun-db/lib/docs/bun-sql-scan.md +9 -3
  51. package/rules/js-bun-redis/lib/docs/redis-imports.md +6 -0
  52. package/rules/js-lint/js/docs/utils_imports.md +6 -0
  53. package/rules/js-lint-ci/docs/fix.md +7 -1
  54. package/rules/js-mssql/docs/fix.md +6 -0
  55. package/rules/js-mssql/lib/docs/mssql-pool-scan.md +6 -0
  56. package/rules/js-run/docs/fix.md +6 -0
  57. package/rules/js-run/lib/docs/bunyan-imports.md +6 -0
  58. package/rules/js-run/lib/docs/check-env-scan.md +6 -0
  59. package/rules/js-run/lib/docs/conn-file-rules.md +6 -0
  60. package/rules/js-run/lib/docs/conn-imports-scan.md +6 -0
  61. package/rules/js-run/lib/docs/promise-settimeout-scan.md +6 -0
  62. package/rules/js-run/lib/docs/temporal-scan.md +6 -0
  63. package/rules/k8s/docs/fix.md +6 -0
  64. package/rules/k8s/lint/docs/lint.md +6 -0
  65. package/rules/nginx-default-tpl/docs/fix.md +6 -0
  66. package/rules/npm-module/js/docs/header_doc_pointer.md +7 -0
  67. package/rules/npm-module/js/header_doc_pointer.mjs +2 -8
  68. package/rules/php/docs/fix.md +6 -0
  69. package/rules/php/lint/docs/lint.md +6 -0
  70. package/rules/python/docs/fix.md +6 -0
  71. package/rules/python/lint/docs/lint.md +6 -0
  72. package/rules/rego/lint/docs/lint.md +6 -0
  73. package/rules/release/docs/change.md +6 -0
  74. package/rules/release/docs/fix.md +6 -0
  75. package/rules/release/docs/release.md +6 -0
  76. package/rules/release/lib/docs/aggregate.md +6 -0
  77. package/rules/release/lib/docs/change-file.md +6 -0
  78. package/rules/release/lib/docs/fallback.md +6 -0
  79. package/rules/rust/lib/docs/has-cargo-toml.md +6 -0
  80. package/rules/security/docs/fix.md +7 -1
  81. package/rules/security/js/docs/lint.md +6 -0
  82. package/rules/style-lint/docs/fix.md +6 -0
  83. package/rules/tauri/docs/fix.md +6 -0
  84. package/rules/test/docs/fix.md +6 -0
  85. package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +6 -0
  86. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +6 -0
  87. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +6 -0
  88. package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +6 -0
  89. package/rules/text/docs/fix.md +6 -0
  90. package/rules/text/lint/docs/lint.md +6 -0
  91. package/rules/text/lint/docs/run-dotenv-linter.md +6 -0
  92. package/rules/text/lint/docs/run-shellcheck.md +6 -0
  93. package/rules/text/lint/docs/run-v8r.md +6 -0
  94. package/rules/vue/lib/docs/vue-forbidden-imports.md +6 -0
  95. package/scripts/coverage-classify/cache.mjs +1 -1
  96. package/scripts/coverage-classify/docs/apply.md +6 -0
  97. package/scripts/coverage-classify/docs/cache.md +6 -0
  98. package/scripts/coverage-classify/docs/prompt.md +6 -0
  99. package/scripts/coverage-classify/docs/verdict-schema.md +6 -0
  100. package/scripts/coverage-classify/prompt.mjs +1 -1
  101. package/scripts/coverage-fix-extract.mjs +1 -1
  102. package/scripts/coverage-fix.mjs +2 -1
  103. package/scripts/docs/auto-skills.md +6 -0
  104. package/scripts/docs/build-agents-commands.md +7 -1
  105. package/scripts/docs/cli-entry.md +6 -0
  106. package/scripts/docs/coverage-fix-extract.md +6 -0
  107. package/scripts/docs/coverage-fix.md +6 -0
  108. package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +6 -0
  109. package/scripts/docs/lint-cli.md +6 -0
  110. package/scripts/docs/post-tool-use-fix.md +6 -0
  111. package/scripts/docs/rename-yaml-extensions.md +6 -0
  112. package/scripts/docs/skills-cli.md +6 -0
  113. package/scripts/docs/sync-setup-bun-deps-action.md +6 -0
  114. package/scripts/docs/upgrade-nitra-cursor-and-install.md +6 -0
  115. package/scripts/docs/worktree-cli.md +6 -0
  116. package/scripts/lib/docs/assert-project-root.md +6 -0
  117. package/scripts/lib/docs/check-mdc-template-refs.md +6 -0
  118. package/scripts/lib/docs/check-reporter.md +6 -0
  119. package/scripts/lib/docs/diff-added-lines.md +6 -0
  120. package/scripts/lib/docs/discover-check-rules-from-cursor.md +6 -0
  121. package/scripts/lib/docs/discover-checkable-rules.md +6 -0
  122. package/scripts/lib/docs/ensure-tool.md +6 -0
  123. package/scripts/lib/docs/generated-markdown.md +6 -0
  124. package/scripts/lib/docs/gha-workflow.md +6 -0
  125. package/scripts/lib/docs/inline-template-links.md +6 -0
  126. package/scripts/lib/docs/list-rule-ids.md +6 -0
  127. package/scripts/lib/docs/load-cursor-config.md +6 -0
  128. package/scripts/lib/docs/mirror-parity.md +6 -0
  129. package/scripts/lib/docs/read-n-cursor-config-lite.md +6 -0
  130. package/scripts/lib/docs/resolve-target-files.md +6 -0
  131. package/scripts/lib/docs/root-notice.md +6 -0
  132. package/scripts/lib/docs/rule-meta-helpers.md +6 -0
  133. package/scripts/lib/docs/rule-meta.md +6 -0
  134. package/scripts/lib/docs/run-conftest-batch.md +6 -0
  135. package/scripts/lib/docs/run-lint-step.md +6 -0
  136. package/scripts/lib/docs/run-rule-cli.md +6 -0
  137. package/scripts/lib/docs/run-rule.md +6 -0
  138. package/scripts/lib/docs/run-standard-lint.md +6 -0
  139. package/scripts/lib/docs/run-standard-rule.md +6 -0
  140. package/scripts/lib/docs/skill-meta.md +6 -0
  141. package/scripts/lib/docs/template.md +6 -0
  142. package/scripts/lib/docs/timing-summary.md +6 -0
  143. package/scripts/lib/docs/workspaces.md +6 -0
  144. package/scripts/lib/docs/worktree-notice.md +6 -0
  145. package/scripts/lib/docs/worktree.md +6 -0
  146. package/scripts/lib/mirror-parity.mjs +1 -1
  147. package/scripts/lib/root-notice.mjs +1 -1
  148. package/scripts/lib/worktree-notice.mjs +5 -5
  149. package/scripts/lib/worktree.mjs +1 -1
  150. package/scripts/sync-claude-config.mjs +3 -0
  151. package/scripts/utils/docs/ast-scan-utils.md +6 -0
  152. package/scripts/utils/docs/ensure-gitignore-entries.md +6 -0
  153. package/scripts/utils/docs/find-package-json-paths.md +6 -0
  154. package/scripts/utils/docs/lock-cache-dir.md +6 -0
  155. package/scripts/utils/docs/pass.md +6 -0
  156. package/scripts/utils/docs/resolve-cargo-manifest.md +6 -0
  157. package/scripts/utils/docs/resolve-cmd.md +6 -0
  158. package/scripts/utils/docs/resolve-js-root.md +6 -0
  159. package/scripts/utils/docs/test-helpers.md +6 -0
  160. package/scripts/utils/docs/walk-cache.md +6 -0
  161. package/scripts/utils/docs/walkDir.md +6 -0
  162. package/scripts/utils/docs/worktree-fingerprint.md +6 -0
  163. package/scripts/utils/resolve-js-root.mjs +1 -1
  164. package/skills/doc-aggregate/SKILL.md +129 -0
  165. package/skills/doc-aggregate/js/docgen-ignore.mjs +9 -0
  166. package/skills/{docgen → doc-aggregate}/js/docgen-scan.mjs +22 -67
  167. package/skills/doc-aggregate/js/docs/docgen-ignore.md +21 -0
  168. package/skills/doc-files/SKILL.md +100 -0
  169. package/skills/doc-files/js/docgen-crc.mjs +164 -0
  170. package/skills/{docgen → doc-files}/js/docgen-extract-anchors.mjs +20 -11
  171. package/skills/{docgen → doc-files}/js/docgen-extract.mjs +15 -9
  172. package/skills/doc-files/js/docgen-files-batch.mjs +181 -0
  173. package/skills/doc-files/js/docgen-gen.mjs +291 -0
  174. package/skills/{docgen → doc-files}/js/docgen-prompts.mjs +43 -40
  175. package/skills/doc-files/js/docgen-scan.mjs +298 -0
  176. package/skills/doc-files/js/docs/docgen-crc.md +32 -0
  177. package/skills/doc-files/js/docs/docgen-extract-anchors.md +27 -0
  178. package/skills/doc-files/js/docs/docgen-extract.md +29 -0
  179. package/skills/doc-files/js/docs/docgen-files-batch.md +25 -0
  180. package/skills/doc-files/js/docs/docgen-gen.md +30 -0
  181. package/skills/doc-files/js/docs/docgen-prompts.md +32 -0
  182. package/skills/doc-files/js/docs/docgen-scan.md +25 -0
  183. package/skills/doc-files/meta.json +1 -0
  184. package/skills/fix/js/docs/llm-worker.md +6 -0
  185. package/skills/fix/js/docs/orchestrator.md +6 -0
  186. package/skills/fix/js/llm-worker.mjs +3 -3
  187. package/skills/fix/js/orchestrator.mjs +1 -1
  188. package/skills/start-check/js/check.mjs +5 -3
  189. package/skills/start-check/js/docs/check.md +6 -0
  190. package/skills/docgen/SKILL.md +0 -224
  191. package/skills/docgen/bench/etalon/firebase_hosting.md +0 -19
  192. package/skills/docgen/bench/etalon/k8s-tree.md +0 -24
  193. package/skills/docgen/bench/etalon/overlay-paths.md +0 -24
  194. package/skills/docgen/js/docgen-batch-omlx.mjs +0 -82
  195. package/skills/docgen/js/docgen-batch.mjs +0 -95
  196. package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +0 -95
  197. package/skills/docgen/js/docgen-gen.mjs +0 -306
  198. package/skills/docgen/js/docs/docgen-extract.md +0 -28
  199. package/skills/docgen/js/docs/docgen-gen.md +0 -41
  200. package/skills/docgen/js/docs/docgen-ignore.md +0 -24
  201. package/skills/docgen/js/docs/docgen-prompts.md +0 -24
  202. package/skills/docgen/js/docs/docgen-scan.md +0 -48
  203. /package/skills/{docgen → doc-aggregate}/meta.json +0 -0
  204. /package/skills/{docgen → doc-files}/js/docgen-ignore.mjs +0 -0
@@ -1,259 +1,44 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/adr/js/hooks.mjs
4
+ crc: 3f239faf
5
+ score: 100
6
+ ---
7
+
1
8
  # hooks.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль `npm/rules/adr/js/hooks.mjs` це скрипт-перевірник (check) правила `adr.mdc` пакета `@nitra/cursor`. Його завдання переконатися, що в репозиторії-споживачі правильно встановлені та підтримуються ADR (Architecture Decision Records) Stop-hook'и для двох LLM-середовищ: Claude Code та Cursor Agent.
6
-
7
- Skрипт перевіряє, що:
8
-
9
- - Канонічні bash-скрипти `capture-decisions.sh` і `normalize-decisions.sh` присутні у `.claude/hooks/` цільового репо й байт-у-байт збігаються з версіями, які поставляє npm-пакет у `.claude-template/hooks/` (sync керує файлами повністю — будь-яке локальне редагування фіксується як `fail`).
10
- - Файл `.claude/settings.json` (project-shared конфіг Claude Code) існує — глибша валідація `hooks.Stop[]` робиться окремими policy-правилами (`npm/policy/adr/settings_json/`, `npm/policy/adr/settings_local_json/`).
11
- - Файл `.cursor/hooks.json` валідний JSON і містить у `hooks.stop[]` entries з `command`, що посилаються на обидва managed-скрипти (це дозволяє Cursor Agent також запускати ADR capture/normalize по `stop`-події).
12
- - `.gitignore` у корені покриває лог-файли `.claude/hooks/capture-decisions.log` і `.claude/hooks/normalize-decisions.log`, інакше runtime-логи потраплятимуть у git.
13
- - Наявність LLM CLI (`claude` або `cursor-agent`) у `PATH` — це **інформативна** перевірка (warning через `pass`-меседж), бо хук без CLI просто мовчки no-op'ає, а не фейлиться.
14
-
15
- Модуль експортує єдину асинхронну функцію `check(cwd)`, яка повертає numeric exit-code (0 = OK, 1 = є проблеми). Усе зведення результатів і форматування проходить через `createCheckReporter()` з `npm/scripts/lib/check-reporter.mjs`.
16
-
17
- ## Експорти / API
18
-
19
- | Назва | Тип | Призначення |
20
- | ----- | --- | ----------- |
21
- | `check` | `async (cwd?: string) => Promise<number>` | Єдиний публічний експорт. Запускає весь набір перевірок правила `adr.mdc` для дерева репозиторію за шляхом `cwd` (default — `process.cwd()`). Повертає 0 при повному success або 1, якщо принаймні одна перевірка зафейлилась. |
22
-
23
- Усі інші ідентифікатори файлу (`HOOK_ARTIFACTS`, `PROJECT_SETTINGS_REL`, `CURSOR_HOOKS_REL`, `EOL_RE`, `BUNDLED_HOOKS_DIR`, `projectHookPath`, `projectLogPath`, `gitignoreLineCoversHookLog`, `checkHookScript`, `checkProjectSettings`, `readJsonSafe`, `cursorConfigHasStopHook`, `checkCursorHooks`, `checkGitignoreForLog`, `checkGitignore`, `isBinaryInPath`, `checkLlmCliAvailable`) — внутрішні (module-private).
24
-
25
- ## Функції
26
-
27
- ### `projectHookPath(scriptName)`
28
-
29
- - **Сигнатура:** `(scriptName: string) => string`
30
- - **Параметри:**
31
- - `scriptName` — базове ім'я hook-скрипта (наприклад `capture-decisions.sh`).
32
- - **Повертає:** відносний шлях вигляду `.claude/hooks/<scriptName>`.
33
- - **Side effects:** немає (чиста функція конкатенації шляху).
34
-
35
- ### `projectLogPath(logName)`
36
-
37
- - **Сигнатура:** `(logName: string) => string`
38
- - **Параметри:**
39
- - `logName` — базове ім'я лог-файлу (наприклад `capture-decisions.log`).
40
- - **Повертає:** відносний шлях вигляду `.claude/hooks/<logName>`.
41
- - **Side effects:** немає.
42
-
43
- ### `gitignoreLineCoversHookLog(line, logPath)`
44
-
45
- - **Сигнатура:** `(line: string, logPath: string) => boolean`
46
- - **Параметри:**
47
- - `line` — одна нормалізована (trim) лінія з `.gitignore`.
48
- - `logPath` — шлях до конкретного лог-файлу, який треба покрити.
49
- - **Повертає:** `true`, якщо рядок покриває цей лог. Підтримує матчі:
50
- - точний шлях (`logPath`);
51
- - glob `.claude/hooks/*.log` або `.claude/hooks/**/*.log`;
52
- - широкий glob `*.log` або `**/*.log`.
53
- - Порожні рядки та коментарі (`#…`) ігноруються.
54
- - **Side effects:** немає.
55
-
56
- ### `checkHookScript(reporter, cwd, scriptName)`
57
-
58
- - **Сигнатура:** `async (reporter: CheckReporter, cwd: string, scriptName: string) => Promise<void>`
59
- - **Параметри:**
60
- - `reporter` — інстанс, створений `createCheckReporter()`; з нього використовуються `pass` і `fail`.
61
- - `cwd` — корінь репозиторію-споживача.
62
- - `scriptName` — базове ім'я hook-скрипта.
63
- - **Повертає:** нічого (звітує результат через reporter).
64
- - **Поведінка:**
65
- 1. Якщо `<cwd>/.claude/hooks/<scriptName>` не існує → `fail` з підказкою запустити `npx @nitra/cursor`.
66
- 2. Якщо канонічний скрипт у пакеті (`<пакет>/.claude-template/hooks/<scriptName>`, обчислюється від `import.meta.url`) не існує → `fail` про перевстановлення `@nitra/cursor`.
67
- 3. Інакше читає обидва файли паралельно через `Promise.all`+`readFile` і порівнює як рядки UTF-8. При повному збігу — `pass`, інакше — `fail` із підказкою про повторний sync.
68
- - **Side effects:** файлова система — `existsSync`, `readFile`. Мутує внутрішній стан репортера.
69
-
70
- ### `checkProjectSettings(reporter, cwd)`
71
-
72
- - **Сигнатура:** `(reporter: CheckReporter, cwd: string) => void`
73
- - **Параметри:**
74
- - `reporter` — репортер для збору результату.
75
- - `cwd` — корінь репозиторію.
76
- - **Повертає:** нічого.
77
- - **Поведінка:** перевіряє лише факт наявності `.claude/settings.json` (`existsSync`). `pass`, якщо файл є, інакше — `fail` з підказкою про `npx @nitra/cursor`. Глибша валідація структури `hooks.Stop[]` навмисно винесена в policy-правила `adr.settings_json` і `adr.settings_local_json`.
78
- - **Side effects:** одне `existsSync`.
79
-
80
- ### `readJsonSafe(path)`
81
-
82
- - **Сигнатура:** `async (path: string) => Promise<unknown | null>`
83
- - **Параметри:**
84
- - `path` — шлях до JSON-файлу.
85
- - **Повертає:** результат `JSON.parse(await readFile(path, 'utf8'))` або `null`, якщо читання чи парсинг кинули виняток.
86
- - **Side effects:** читання файлу; виняток придушується try/catch і конвертується у `null`.
87
-
88
- ### `cursorConfigHasStopHook(config, marker)`
89
-
90
- - **Сигнатура:** `(config: unknown, marker: string) => boolean`
91
- - **Параметри:**
92
- - `config` — попередньо розпарсений вміст `.cursor/hooks.json`.
93
- - `marker` — підрядок, який має зустрічатися в `command` шуканого entry (зазвичай — шлях до managed hook-скрипта, наприклад `.claude/hooks/capture-decisions.sh`).
94
- - **Повертає:** `true`, якщо у `config.hooks.stop` є щонайменше один елемент-об'єкт з рядковим `command`, який містить `marker`. Кожен крок обходу (`config` — об'єкт-не-масив, `hooks` — об'єкт-не-масив, `stop` — масив) явно валідовано, тож не-канонічна структура повертає `false` без винятків.
95
- - **Side effects:** немає.
96
-
97
- ### `checkCursorHooks(reporter, cwd)`
98
-
99
- - **Сигнатура:** `async (reporter: CheckReporter, cwd: string) => Promise<void>`
100
- - **Параметри:**
101
- - `reporter` — репортер.
102
- - `cwd` — корінь репо.
103
- - **Повертає:** нічого.
104
- - **Поведінка:**
105
- 1. Якщо `.cursor/hooks.json` не існує — `fail` (запропонувати `npx @nitra/cursor`).
106
- 2. Інакше парсить через `readJsonSafe`. Якщо повернуло `null` — `fail` ("не парситься як JSON").
107
- 3. Для кожного елемента `HOOK_ARTIFACTS` обчислює marker через `projectHookPath(scriptName)` і шукає stop-entry за допомогою `cursorConfigHasStopHook`. На кожен скрипт — окремий `pass` або `fail`.
108
- - **Side effects:** читання файлу, мутація стану репортера.
109
-
110
- ### `checkGitignoreForLog(reporter, logName, gitignoreContent)`
111
-
112
- - **Сигнатура:** `(reporter: CheckReporter, logName: string, gitignoreContent: string) => void`
113
- - **Параметри:**
114
- - `reporter` — репортер.
115
- - `logName` — базове ім'я лог-файлу.
116
- - `gitignoreContent` — наперед прочитаний вміст `.gitignore` (передається ззовні, щоб не читати файл двічі).
117
- - **Повертає:** нічого.
118
- - **Поведінка:** розбиває контент по `EOL_RE` (`\r?\n`), тримує кожну лінію та перевіряє через `gitignoreLineCoversHookLog`. Якщо хоч одна лінія покриває шлях — `pass`, інакше — `fail` з підказкою додати рядок.
119
- - **Side effects:** мутація стану репортера.
120
-
121
- ### `checkGitignore(reporter, cwd)`
122
-
123
- - **Сигнатура:** `async (reporter: CheckReporter, cwd: string) => Promise<void>`
124
- - **Параметри:**
125
- - `reporter` — репортер.
126
- - `cwd` — корінь репо.
127
- - **Повертає:** нічого.
128
- - **Поведінка:**
129
- 1. Якщо `.gitignore` у корені відсутній — викидає по `fail` на кожен `HOOK_ARTIFACTS.logName` (один fail для кожного логу окремо, а не один загальний).
130
- 2. Інакше один раз читає файл і прокручує `HOOK_ARTIFACTS`, делегуючи кожен лог у `checkGitignoreForLog`.
131
- - **Side effects:** одне `readFile`, кілька викликів `fail`/`pass` через репортер.
132
-
133
- ### `isBinaryInPath(name)`
134
-
135
- - **Сигнатура:** `(name: string) => boolean`
136
- - **Параметри:**
137
- - `name` — ім'я бінарника без розширення.
138
- - **Повертає:** `true`, якщо у каталогах `process.env.PATH` (розділених `path.delimiter`) знайдено файл з таким іменем. Чек робиться через `existsSync(join(dir, name))` — без виклику `spawn`/`child_process`, тому не залежить від executable-біта і працює як легкий `which`.
139
- - **Side effects:** читання env через `node:process` + `existsSync` на кожен каталог `PATH`.
140
-
141
- ### `checkLlmCliAvailable(reporter)`
142
-
143
- - **Сигнатура:** `(reporter: CheckReporter) => void`
144
- - **Параметри:**
145
- - `reporter` — репортер.
146
- - **Повертає:** нічого.
147
- - **Поведінка:** перевіряє `isBinaryInPath('claude')` та `isBinaryInPath('cursor-agent')`. Виводить **завжди `pass`** з одним із чотирьох повідомлень (обидва знайдено / лише `claude` / лише `cursor-agent` / жодного). Це навмисний дизайн — відсутність CLI означає, що hook просто no-op'ає й не валить білд.
148
- - **Side effects:** мутація стану репортера (тільки `pass`-меседжі).
149
-
150
- ### `check(cwd?)` *(експорт)*
151
-
152
- - **Сигнатура:** `async (cwd?: string) => Promise<number>`
153
- - **Параметри:**
154
- - `cwd` — корінь репо. За замовчуванням — `process.cwd()`.
155
- - **Повертає:** exit-code зі `reporter.getExitCode()` (0 або 1).
156
- - **Поведінка (порядок виконання):**
157
- 1. Створює свіжий репортер через `createCheckReporter()`.
158
- 2. Послідовно (через `for…of` + `await`) для кожного `HOOK_ARTIFACTS` запускає `checkHookScript`.
159
- 3. Викликає `checkProjectSettings` (синхронно).
160
- 4. Викликає `await checkCursorHooks`.
161
- 5. Викликає `await checkGitignore`.
162
- 6. Викликає `checkLlmCliAvailable` (синхронно).
163
- 7. Повертає `reporter.getExitCode()`.
164
- - **Side effects:** усі ті, що зведено у внутрішніх перевірках (FS read, env read).
165
-
166
- ## Константи модуля
167
-
168
- | Ім'я | Тип/значення | Призначення |
169
- | ---- | ------------ | ----------- |
170
- | `HOOK_ARTIFACTS` | `readonly [{ scriptName, logName }, …]` | Перелік hook-артефактів (`capture-decisions.sh`+`.log`, `normalize-decisions.sh`+`.log`), які перевіряються однотипно. `as const` через JSDoc-каст `/** @type {const} */`. |
171
- | `PROJECT_SETTINGS_REL` | `'.claude/settings.json'` | Project-shared конфіг Claude Code. |
172
- | `CURSOR_HOOKS_REL` | `'.cursor/hooks.json'` | Конфіг Cursor Agent. |
173
- | `EOL_RE` | `/\r?\n/u` | Регекс для split рядків `.gitignore` (підтримує LF і CRLF). |
174
- | `here` | `string` | Каталог цього модуля, обчислений через `fileURLToPath(import.meta.url)` + `dirname`. |
175
- | `BUNDLED_HOOKS_DIR` | `string` | Абсолютний шлях до `.claude-template/hooks/` усередині пакета `@nitra/cursor`: `<here>/../../../.claude-template/hooks`. Використовується як джерело канонічних скриптів. |
176
-
177
- ## Залежності
178
-
179
- ### Node.js builtins
180
-
181
- - `node:fs` → `existsSync` — синхронна перевірка наявності файлу.
182
- - `node:fs/promises` → `readFile` — асинхронне читання UTF-8 контенту.
183
- - `node:path` → `delimiter`, `dirname`, `join` — крос-платформне склеювання шляхів і split `PATH`.
184
- - `node:process` → `env` — доступ до `PATH` для пошуку LLM CLI.
185
- - `node:url` → `fileURLToPath` — конверсія `import.meta.url` у локальний шлях для обчислення `BUNDLED_HOOKS_DIR`.
186
-
187
- ### Внутрішні модулі пакета
188
-
189
- - `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера з API `{ pass(msg), fail(msg), getExitCode() }`. Усі результати модуля проходять через нього.
190
-
191
- ### Зовнішні файли репо-споживача (читаються, не модифікуються)
192
-
193
- - `<cwd>/.claude/hooks/capture-decisions.sh`, `<cwd>/.claude/hooks/normalize-decisions.sh` — managed bash-скрипти.
194
- - `<cwd>/.claude/settings.json` — project-shared Claude config.
195
- - `<cwd>/.cursor/hooks.json` — Cursor Agent hooks config.
196
- - `<cwd>/.gitignore` — для перевірки покриття лог-файлів.
197
-
198
- ### Файли пакета (джерело істини для diff)
199
-
200
- - `<package-root>/.claude-template/hooks/capture-decisions.sh`
201
- - `<package-root>/.claude-template/hooks/normalize-decisions.sh`
202
-
203
- Шлях обчислюється статично від `import.meta.url` — модуль не залежить від `process.cwd()` для пошуку bundled-файлів.
204
-
205
- ## Потік виконання / Використання
206
-
207
- ### Як модуль викликається
208
-
209
- Скрипт — частина уніфікованої check-системи `@nitra/cursor`. Зовнішній рантайм (`npx @nitra/cursor check` або еквівалент у тестах) імпортує функцію `check` і викликає її:
210
-
211
- ```js
212
- import { check } from '@nitra/cursor/rules/adr/js/hooks.mjs'
213
-
214
- const exitCode = await check(process.cwd())
215
- process.exit(exitCode)
216
- ```
12
+ Файл надає публічну функцію `check` для валідації даних. Код використовує конфігурацію з файлу `.local.json` для визначення логіки. Функція працює у режимі, де невдачі повертають `false` або `null` замість генерації винятків. Повідомлення про події передаються за допомогою маркера (adr.mdc).
217
13
 
218
- ### Порядок перевірок усередині `check`
14
+ ## Поведінка
219
15
 
220
- 1. **Канонічність bash-скриптів** — для кожного з `HOOK_ARTIFACTS`:
221
- - FS-existence cцільового файлу;
222
- - FS-existence канонічного файлу в пакеті;
223
- - byte-exact diff обох контентів.
224
- 2. **`.claude/settings.json` existence** — sanity-check, що project-shared конфіг є.
225
- 3. **`.cursor/hooks.json`** — JSON parsing + наявність `hooks.stop[].command` markers для обох scriptName.
226
- 4. **`.gitignore` log-coverage** — для кожного логу шукається покривна лінія (точна, scoped-glob або wide-glob).
227
- 5. **LLM CLI availability** — інформативна перевірка `claude`/`cursor-agent` у `PATH`; **не валить exit code**.
16
+ 1. Перевірка канонічності скриптів
17
+ Проводиться перевірка наявності та відповідності логіки між скриптами, визначеними в артефактах, і їхніми канонічними версіями. У разі невідповідності повертається сигнал про необхідність повторного синхронізації.
228
18
 
229
- ### Як інтерпретувати результат
19
+ 2. Валідація налаштувань проєкту
20
+ Перевіряється наявність файлу `.claude/settings.json` для підтвердження коректності конфігурації відповідно до вимог (adr.mdc).
230
21
 
231
- - **Return `0`** усі обов'язкові перевірки пройшли; LLM-CLI-секція могла видати warning, але це нормально.
232
- - **Return `1`** хоч одна `fail`-перевірка. Усі повідомлення `fail` містять actionable-підказку (зазвичай `npx @nitra/cursor` або конкретний рядок для `.gitignore`).
22
+ 3. Перевірка конфігурації хуків Cursor
23
+ Перевіряється, чи містить конфігурацію Cursor необхідні стоп-хуки для кожного визначеного скрипта.
233
24
 
234
- ### Типові сценарії регресії
25
+ 4. Перевірка ігнорування логів
26
+ Перевіряється вміст файлу `.gitignore` на відповідність ігнорування кожного лог-файлу хука.
235
27
 
236
- - Локальний редактор bash-скрипта → `checkHookScript` зафейлить byte-diff.
237
- - Видалення `.cursor/hooks.json` чи поламана структура `checkCursorHooks` повідомить через JSON-error або відсутність marker.
238
- - Перенесення hook entry в `settings.local.json` → деталі ловить policy-правило, але `checkProjectSettings` гарантує, що project-shared файл хоча б присутній.
239
- - Відсутність `.gitignore`-покриття для логів → багато `fail`-меседжів з конкретним рядком, що треба додати.
240
- - Відсутність LLM CLI → `pass` із warning-меседжем, але `exit 0` (hook буде no-op'ати).
28
+ 5. Перевірка покриття логів
29
+ Перевіряється, чи покриває конфігурація `.gitignore` всі необхідні лог-файли.
241
30
 
242
- ### Контекстні нюанси
31
+ 6. Перевірка доступності CLI
32
+ Перевіряється наявність бінарних файлів `claude` або `cursor-agent` у системному PATH. Якщо жодного не знайдено, це інформується як попередження, оскільки хук працюватиме у режимі мовчки.
243
33
 
244
- - Усі шляхи в `fail`/`pass`-меседжах — відносні до `cwd` (не абсолютні), щоб output був стабільний у CI та однаковий між машинами.
245
- - `readJsonSafe` свідомо приглушує помилки парсингу — рішення про "JSON broken" приймається в `checkCursorHooks` через `config === null`.
246
- - `cursorConfigHasStopHook` робить точкову, але повну валідацію типів, бо `.cursor/hooks.json` керується одночасно автоматичним sync і людьми — не можна вважати, що структура завжди канонічна.
247
- - `BUNDLED_HOOKS_DIR` обчислений `dirname(fileURLToPath(import.meta.url))` + три `..` — цей розрахунок чутливий до **переміщень файлу всередині пакета**: якщо змінити structure `npm/rules/adr/js/`, треба синхронно правити кількість `..` сегментів.
34
+ ## Публічний API
248
35
 
249
- ## Rebuild Test
36
+ check перевіряє, чи відповідає проєкт вимогам adr.mdc (adr.mdc).
250
37
 
251
- Якщо файл `hooks.mjs` загубити, його можна відновити з цієї документації, дотримуючись таких інваріантів:
38
+ ## Гарантії поведінки
252
39
 
253
- - Один експорт `async function check(cwd = process.cwd()): Promise<number>`.
254
- - Внутрішні константи `HOOK_ARTIFACTS`, `PROJECT_SETTINGS_REL`, `CURSOR_HOOKS_REL`, `EOL_RE`, `BUNDLED_HOOKS_DIR` мають описані значення.
255
- - Усі перевірки звітують через `createCheckReporter()` з `npm/scripts/lib/check-reporter.mjs`.
256
- - Канонічні bash-скрипти беруться з `<тут>/../../../.claude-template/hooks/` (три `..` від каталогу модуля).
257
- - `.gitignore`-матч підтримує точний шлях + `.claude/hooks/*.log` + `.claude/hooks/**/*.log` + `*.log` + `**/*.log`, ігнорує порожні й коментарі.
258
- - LLM-CLI-перевірка завжди завершується `pass` — exit-code від неї не залежить.
259
- - Порядок викликів усередині `check` має значення для читабельного output: hook-скрипти → settings → cursor hooks → gitignore → llm cli.
40
+ - Read-only: файл не виконує операцій запису у файлову систему.
41
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
42
+ - За невдалої перевірки повертає `false`/`null` замість винятку.
43
+ - Свідомо пропускає шляхи: `.git`.
44
+ - Не звертається до мережі.
@@ -1,3 +1,9 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/bun/fix.mjs
4
+ crc: 12fc1644
5
+ ---
6
+
1
7
  # `npm/rules/bun/fix.mjs`
2
8
 
3
9
  ## Огляд