@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.
- package/.claude-template/settings.template.json +22 -0
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +15 -9
- package/CHANGELOG.md +18 -1
- package/bin/n-cursor.js +73 -16
- package/docs/stryker.config.md +6 -0
- package/docs/vitest.config.md +6 -0
- package/lib/docs/llm.md +29 -0
- package/lib/docs/models.md +24 -17
- package/lib/docs/omlx.md +32 -0
- package/lib/llm.mjs +137 -0
- package/lib/omlx.mjs +49 -4
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +6 -0
- package/rules/abie/js/docs/applies.md +6 -0
- package/rules/abie/js/docs/env_dns.md +25 -22
- package/rules/abie/js/docs/firebase_hosting.md +6 -0
- package/rules/abie/js/docs/hc_pairing.md +21 -25
- package/rules/abie/js/docs/ua_http_route.md +27 -19
- package/rules/abie/js/docs/ua_node_selector.md +24 -19
- package/rules/abie/lib/docs/enabled.md +13 -7
- package/rules/abie/lib/docs/env-dns.md +9 -3
- package/rules/abie/lib/docs/hc-yaml.md +6 -0
- package/rules/abie/lib/docs/http-route.md +6 -0
- package/rules/abie/lib/docs/k8s-tree.md +6 -0
- package/rules/abie/lib/docs/kustomization-patches.md +6 -0
- package/rules/abie/lib/docs/overlay-paths.md +6 -0
- package/rules/abie/lib/docs/yaml.md +6 -0
- package/rules/adr/docs/fix.md +6 -0
- package/rules/adr/js/docs/hooks.md +29 -244
- package/rules/bun/docs/fix.md +6 -0
- package/rules/bun/js/docs/layout.md +37 -375
- package/rules/capacitor/docs/fix.md +22 -108
- package/rules/capacitor/js/docs/platforms.md +62 -268
- package/rules/changelog/docs/fix.md +6 -0
- package/rules/changelog/js/docs/consistency.md +36 -383
- package/rules/changelog/lib/docs/package-manifest.md +6 -0
- package/rules/ci4/docs/fix.md +23 -165
- package/rules/ci4/js/docs/marksman_config.md +9 -1
- package/rules/docker/docs/fix.md +6 -0
- package/rules/docker/js/docs/lint.md +55 -239
- package/rules/docker/lib/docs/docker-hadolint.md +6 -0
- package/rules/docker/lib/docs/docker-mirror.md +6 -0
- package/rules/docker/lib/docs/docker-native-addon.md +6 -0
- package/rules/docker/lib/docs/docker-nginx-user.md +6 -0
- package/rules/docker/lint/docs/lint.md +9 -1
- package/rules/efes/docs/fix.md +6 -0
- package/rules/feedback/docs/fix.md +21 -131
- package/rules/ga/docs/fix.md +14 -12
- package/rules/ga/js/docs/lint.md +12 -9
- package/rules/ga/js/docs/workflows.md +20 -19
- package/rules/ga/lint/docs/lint.md +6 -0
- package/rules/graphql/docs/fix.md +6 -0
- package/rules/graphql/js/docs/tooling.md +18 -253
- package/rules/graphql/lib/docs/graphql-gql-scan.md +6 -0
- package/rules/hasura/docs/fix.md +18 -111
- package/rules/image-avif/docs/fix.md +6 -0
- package/rules/image-avif/js/docs/avif_generation.md +6 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +9 -3
- package/rules/js-bun-redis/lib/docs/redis-imports.md +6 -0
- package/rules/js-lint/js/docs/utils_imports.md +6 -0
- package/rules/js-lint-ci/docs/fix.md +7 -1
- package/rules/js-mssql/docs/fix.md +6 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +6 -0
- package/rules/js-run/docs/fix.md +6 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +6 -0
- package/rules/js-run/lib/docs/check-env-scan.md +6 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +6 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +6 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +6 -0
- package/rules/js-run/lib/docs/temporal-scan.md +6 -0
- package/rules/k8s/docs/fix.md +6 -0
- package/rules/k8s/lint/docs/lint.md +6 -0
- package/rules/nginx-default-tpl/docs/fix.md +6 -0
- package/rules/npm-module/js/docs/header_doc_pointer.md +7 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +2 -8
- package/rules/php/docs/fix.md +6 -0
- package/rules/php/lint/docs/lint.md +6 -0
- package/rules/python/docs/fix.md +6 -0
- package/rules/python/lint/docs/lint.md +6 -0
- package/rules/rego/lint/docs/lint.md +6 -0
- package/rules/release/docs/change.md +6 -0
- package/rules/release/docs/fix.md +6 -0
- package/rules/release/docs/release.md +6 -0
- package/rules/release/lib/docs/aggregate.md +6 -0
- package/rules/release/lib/docs/change-file.md +6 -0
- package/rules/release/lib/docs/fallback.md +6 -0
- package/rules/rust/lib/docs/has-cargo-toml.md +6 -0
- package/rules/security/docs/fix.md +7 -1
- package/rules/security/js/docs/lint.md +6 -0
- package/rules/style-lint/docs/fix.md +6 -0
- package/rules/tauri/docs/fix.md +6 -0
- package/rules/test/docs/fix.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +6 -0
- package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +6 -0
- package/rules/text/docs/fix.md +6 -0
- package/rules/text/lint/docs/lint.md +6 -0
- package/rules/text/lint/docs/run-dotenv-linter.md +6 -0
- package/rules/text/lint/docs/run-shellcheck.md +6 -0
- package/rules/text/lint/docs/run-v8r.md +6 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +6 -0
- package/scripts/coverage-classify/cache.mjs +1 -1
- package/scripts/coverage-classify/docs/apply.md +6 -0
- package/scripts/coverage-classify/docs/cache.md +6 -0
- package/scripts/coverage-classify/docs/prompt.md +6 -0
- package/scripts/coverage-classify/docs/verdict-schema.md +6 -0
- package/scripts/coverage-classify/prompt.mjs +1 -1
- package/scripts/coverage-fix-extract.mjs +1 -1
- package/scripts/coverage-fix.mjs +2 -1
- package/scripts/docs/auto-skills.md +6 -0
- package/scripts/docs/build-agents-commands.md +7 -1
- package/scripts/docs/cli-entry.md +6 -0
- package/scripts/docs/coverage-fix-extract.md +6 -0
- package/scripts/docs/coverage-fix.md +6 -0
- package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +6 -0
- package/scripts/docs/lint-cli.md +6 -0
- package/scripts/docs/post-tool-use-fix.md +6 -0
- package/scripts/docs/rename-yaml-extensions.md +6 -0
- package/scripts/docs/skills-cli.md +6 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +6 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +6 -0
- package/scripts/docs/worktree-cli.md +6 -0
- package/scripts/lib/docs/assert-project-root.md +6 -0
- package/scripts/lib/docs/check-mdc-template-refs.md +6 -0
- package/scripts/lib/docs/check-reporter.md +6 -0
- package/scripts/lib/docs/diff-added-lines.md +6 -0
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +6 -0
- package/scripts/lib/docs/discover-checkable-rules.md +6 -0
- package/scripts/lib/docs/ensure-tool.md +6 -0
- package/scripts/lib/docs/generated-markdown.md +6 -0
- package/scripts/lib/docs/gha-workflow.md +6 -0
- package/scripts/lib/docs/inline-template-links.md +6 -0
- package/scripts/lib/docs/list-rule-ids.md +6 -0
- package/scripts/lib/docs/load-cursor-config.md +6 -0
- package/scripts/lib/docs/mirror-parity.md +6 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +6 -0
- package/scripts/lib/docs/resolve-target-files.md +6 -0
- package/scripts/lib/docs/root-notice.md +6 -0
- package/scripts/lib/docs/rule-meta-helpers.md +6 -0
- package/scripts/lib/docs/rule-meta.md +6 -0
- package/scripts/lib/docs/run-conftest-batch.md +6 -0
- package/scripts/lib/docs/run-lint-step.md +6 -0
- package/scripts/lib/docs/run-rule-cli.md +6 -0
- package/scripts/lib/docs/run-rule.md +6 -0
- package/scripts/lib/docs/run-standard-lint.md +6 -0
- package/scripts/lib/docs/run-standard-rule.md +6 -0
- package/scripts/lib/docs/skill-meta.md +6 -0
- package/scripts/lib/docs/template.md +6 -0
- package/scripts/lib/docs/timing-summary.md +6 -0
- package/scripts/lib/docs/workspaces.md +6 -0
- package/scripts/lib/docs/worktree-notice.md +6 -0
- package/scripts/lib/docs/worktree.md +6 -0
- package/scripts/lib/mirror-parity.mjs +1 -1
- package/scripts/lib/root-notice.mjs +1 -1
- package/scripts/lib/worktree-notice.mjs +5 -5
- package/scripts/lib/worktree.mjs +1 -1
- package/scripts/sync-claude-config.mjs +3 -0
- package/scripts/utils/docs/ast-scan-utils.md +6 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +6 -0
- package/scripts/utils/docs/find-package-json-paths.md +6 -0
- package/scripts/utils/docs/lock-cache-dir.md +6 -0
- package/scripts/utils/docs/pass.md +6 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +6 -0
- package/scripts/utils/docs/resolve-cmd.md +6 -0
- package/scripts/utils/docs/resolve-js-root.md +6 -0
- package/scripts/utils/docs/test-helpers.md +6 -0
- package/scripts/utils/docs/walk-cache.md +6 -0
- package/scripts/utils/docs/walkDir.md +6 -0
- package/scripts/utils/docs/worktree-fingerprint.md +6 -0
- package/scripts/utils/resolve-js-root.mjs +1 -1
- package/skills/doc-aggregate/SKILL.md +129 -0
- package/skills/doc-aggregate/js/docgen-ignore.mjs +9 -0
- package/skills/{docgen → doc-aggregate}/js/docgen-scan.mjs +22 -67
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +21 -0
- package/skills/doc-files/SKILL.md +100 -0
- package/skills/doc-files/js/docgen-crc.mjs +164 -0
- package/skills/{docgen → doc-files}/js/docgen-extract-anchors.mjs +48 -13
- package/skills/{docgen → doc-files}/js/docgen-extract.mjs +39 -10
- package/skills/doc-files/js/docgen-files-batch.mjs +181 -0
- package/skills/doc-files/js/docgen-gen.mjs +336 -0
- package/skills/{docgen → doc-files}/js/docgen-prompts.mjs +65 -50
- package/skills/doc-files/js/docgen-scan.mjs +298 -0
- package/skills/doc-files/js/docs/docgen-crc.md +32 -0
- package/skills/doc-files/js/docs/docgen-extract-anchors.md +27 -0
- package/skills/doc-files/js/docs/docgen-extract.md +29 -0
- package/skills/doc-files/js/docs/docgen-files-batch.md +25 -0
- package/skills/doc-files/js/docs/docgen-gen.md +30 -0
- package/skills/doc-files/js/docs/docgen-prompts.md +32 -0
- package/skills/doc-files/js/docs/docgen-scan.md +25 -0
- package/skills/doc-files/js/units-js.mjs +139 -0
- package/skills/doc-files/js/units.mjs +19 -0
- package/skills/doc-files/meta.json +1 -0
- package/skills/fix/js/docs/llm-worker.md +6 -0
- package/skills/fix/js/docs/orchestrator.md +6 -0
- package/skills/fix/js/llm-worker.mjs +3 -3
- package/skills/fix/js/orchestrator.mjs +1 -1
- package/skills/start-check/js/check.mjs +5 -3
- package/skills/start-check/js/docs/check.md +6 -0
- package/skills/docgen/SKILL.md +0 -224
- package/skills/docgen/bench/etalon/firebase_hosting.md +0 -19
- package/skills/docgen/bench/etalon/k8s-tree.md +0 -24
- package/skills/docgen/bench/etalon/overlay-paths.md +0 -24
- package/skills/docgen/js/docgen-batch-omlx.mjs +0 -82
- package/skills/docgen/js/docgen-batch.mjs +0 -95
- package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +0 -95
- package/skills/docgen/js/docgen-gen.mjs +0 -306
- package/skills/docgen/js/docs/docgen-extract.md +0 -28
- package/skills/docgen/js/docs/docgen-gen.md +0 -41
- package/skills/docgen/js/docs/docgen-ignore.md +0 -24
- package/skills/docgen/js/docs/docgen-prompts.md +0 -24
- package/skills/docgen/js/docs/docgen-scan.md +0 -48
- /package/skills/{docgen → doc-aggregate}/meta.json +0 -0
- /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
|
-
|
|
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
|
-
|
|
14
|
+
## Поведінка
|
|
219
15
|
|
|
220
|
-
1.
|
|
221
|
-
|
|
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
|
-
|
|
232
|
-
|
|
22
|
+
3. Перевірка конфігурації хуків Cursor
|
|
23
|
+
Перевіряється, чи містить конфігурацію Cursor необхідні стоп-хуки для кожного визначеного скрипта.
|
|
233
24
|
|
|
234
|
-
|
|
25
|
+
4. Перевірка ігнорування логів
|
|
26
|
+
Перевіряється вміст файлу `.gitignore` на відповідність ігнорування кожного лог-файлу хука.
|
|
235
27
|
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
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
|
-
|
|
36
|
+
check — перевіряє, чи відповідає проєкт вимогам adr.mdc (adr.mdc).
|
|
250
37
|
|
|
251
|
-
|
|
38
|
+
## Гарантії поведінки
|
|
252
39
|
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
256
|
-
-
|
|
257
|
-
-
|
|
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
|
+
- Не звертається до мережі.
|