@nitra/cursor 1.13.87 → 1.14.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 (79) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/bin/n-cursor.js +5 -6
  3. package/package.json +1 -1
  4. package/rules/abie/abie.mdc +8 -8
  5. package/rules/abie/js/{applies/check.mjs → applies.mjs} +2 -2
  6. package/rules/abie/js/{env_dns/check.mjs → env_dns.mjs} +3 -3
  7. package/rules/abie/js/{firebase_hosting/check.mjs → firebase_hosting.mjs} +1 -1
  8. package/rules/abie/js/{hc_pairing/check.mjs → hc_pairing.mjs} +4 -4
  9. package/rules/abie/js/{ua_http_route/check.mjs → ua_http_route.mjs} +6 -6
  10. package/rules/abie/js/{ua_node_selector/check.mjs → ua_node_selector.mjs} +5 -5
  11. package/rules/abie/policy/base_deployment_preem/base_deployment_preem.rego +2 -2
  12. package/rules/abie/policy/health_check_policy/health_check_policy.rego +2 -2
  13. package/rules/abie/policy/http_route_base/http_route_base.rego +1 -1
  14. package/rules/abie/utils/enabled.mjs +1 -1
  15. package/rules/abie/utils/k8s-tree.mjs +1 -1
  16. package/rules/adr/js/{hooks/check.mjs → hooks.mjs} +1 -1
  17. package/rules/bun/js/{layout/check.mjs → layout.mjs} +1 -1
  18. package/rules/capacitor/js/{platforms/check.mjs → platforms.mjs} +1 -1
  19. package/rules/changelog/changelog.mdc +1 -1
  20. package/rules/changelog/js/{consistency/check.mjs → consistency.mjs} +2 -2
  21. package/rules/changelog/{js/consistency → utils}/package-manifest.mjs +1 -1
  22. package/rules/docker/js/{lint/check.mjs → lint.mjs} +5 -5
  23. package/rules/docker/lint/lint.mjs +1 -1
  24. package/rules/docker/{js/lint → utils}/docker-hadolint.mjs +1 -1
  25. package/rules/feedback/feedback.mdc +1 -1
  26. package/rules/ga/js/{workflows/check.mjs → workflows.mjs} +5 -5
  27. package/rules/ga/lint/lint.mjs +1 -1
  28. package/rules/graphql/js/{tooling/check.mjs → tooling.mjs} +5 -5
  29. package/rules/hasura/js/{internal_urls/check.mjs → internal_urls.mjs} +4 -4
  30. package/rules/hasura/policy/svc_hl/svc_hl.rego +1 -1
  31. package/rules/image-avif/js/{avif_generation/check.mjs → avif_generation.mjs} +5 -5
  32. package/rules/image-compress/js/{package_setup/check.mjs → package_setup.mjs} +3 -3
  33. package/rules/js-bun-db/js/{safety/check.mjs → safety.mjs} +5 -5
  34. package/rules/js-bun-db/{js/safety → utils}/bun-sql-scan.mjs +1 -1
  35. package/rules/js-bun-redis/js/{imports/check.mjs → imports.mjs} +4 -4
  36. package/rules/js-bun-redis/policy/package_json/package_json.rego +1 -1
  37. package/rules/js-lint/js/{tooling/check.mjs → tooling.mjs} +8 -4
  38. package/rules/js-lint/js-lint.mdc +11 -1
  39. package/rules/js-lint/{js/tooling → utils}/rebuild-oxlint-canonical.mjs +2 -2
  40. package/rules/js-mssql/js/{deps/check.mjs → deps.mjs} +5 -5
  41. package/rules/js-mssql/{js/deps → utils}/mssql-pool-scan.mjs +1 -1
  42. package/rules/js-run/js/{runtime/check.mjs → runtime.mjs} +10 -10
  43. package/rules/js-run/{js/runtime → utils}/bunyan-imports.mjs +1 -1
  44. package/rules/js-run/{js/runtime → utils}/check-env-scan.mjs +1 -1
  45. package/rules/js-run/{js/runtime → utils}/conn-file-rules.mjs +1 -1
  46. package/rules/js-run/{js/runtime → utils}/conn-imports-scan.mjs +1 -1
  47. package/rules/js-run/{js/runtime → utils}/promise-settimeout-scan.mjs +1 -1
  48. package/rules/k8s/js/{manifests/check.mjs → manifests.mjs} +4 -4
  49. package/rules/k8s/k8s.mdc +1 -1
  50. package/rules/nginx-default-tpl/js/{template/check.mjs → template.mjs} +5 -5
  51. package/rules/npm-module/js/{package_structure/check.mjs → package_structure.mjs} +4 -4
  52. package/rules/php/js/{tooling/check.mjs → tooling.mjs} +1 -1
  53. package/rules/rego/js/{applies/check.mjs → applies.mjs} +3 -3
  54. package/rules/security/js/{sample_secret/check.mjs → sample_secret.mjs} +2 -2
  55. package/rules/security/js/{trufflehog/check.mjs → trufflehog.mjs} +3 -3
  56. package/rules/security/security.mdc +2 -2
  57. package/rules/style-lint/js/{tooling/check.mjs → tooling.mjs} +1 -1
  58. package/rules/tauri/js/{tooling/check.mjs → tooling.mjs} +2 -2
  59. package/rules/test/js/{location/check.mjs → location.mjs} +3 -3
  60. package/rules/text/js/{formatting/check.mjs → formatting.mjs} +2 -2
  61. package/rules/vue/js/{packages/check.mjs → packages.mjs} +5 -5
  62. package/scripts/auto-rules.mjs +3 -3
  63. package/scripts/claude-stop-hook.mjs +2 -2
  64. package/scripts/sync-claude-config.mjs +5 -4
  65. package/scripts/utils/discover-checkable-rules.mjs +20 -27
  66. package/scripts/utils/inline-template-links.mjs +1 -1
  67. package/scripts/utils/run-rule.mjs +18 -23
  68. package/scripts/utils/with-lock.mjs +24 -12
  69. package/.claude-template/commands/n-check.md +0 -11
  70. /package/rules/adr/js/{hooks/template → templates/hooks}/.gitignore.snippet +0 -0
  71. /package/rules/docker/{js/lint → utils}/docker-mirror.mjs +0 -0
  72. /package/rules/graphql/{js/tooling → utils}/graphql-gql-scan.mjs +0 -0
  73. /package/rules/js-lint/js/{tooling → data/tooling}/knip-canonical.json +0 -0
  74. /package/rules/js-lint/js/{tooling → data/tooling}/oxlint-canonical-skeleton.json +0 -0
  75. /package/rules/js-lint/js/{tooling → data/tooling}/oxlint-canonical.json +0 -0
  76. /package/rules/js-lint/js/{tooling → data/tooling}/oxlint-rules.tsv +0 -0
  77. /package/rules/k8s/js/{kubescape_exceptions/template → templates/kubescape_exceptions}/.kubescape-exceptions.json.snippet.json +0 -0
  78. /package/rules/security/js/{trufflehog/template → templates/trufflehog}/.trufflehog-exclude.snippet.txt +0 -0
  79. /package/rules/vue/{js/packages → utils}/vue-forbidden-imports.mjs +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,54 @@
4
4
 
5
5
  Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
6
6
 
7
+ ## [1.14.0] - 2026-05-24
8
+
9
+ ### Changed (BREAKING)
10
+
11
+ - **Flat концерн-лейаут:** кожен JS-концерн правила тепер один файл `npm/rules/<rule>/js/<concern>.mjs` замість вкладеного `js/<concern>/check.mjs`. Tests — у `js/tests/<concern>.test.mjs` (single) або `js/tests/<concern>/<name>.test.mjs` (multi+fixtures). Templates — у `js/templates/<concern>/`. Data (json/tsv) — у `js/data/<concern>/`. Helpers (cross-concern і concern-private) — у `<rule>/utils/<helper>.mjs` peer до `js/` (existing convention з `abie/utils/`).
12
+ - **`JsConcern.files` removed:** один файл на concern, поле більше не потрібне. `runRule` обчислює шлях як `<rule>/js/<concern.name>.mjs`; `resolveJsCheckPath` тепер `(bundledRulesDir, ruleId, concern)` без `fileName`.
13
+ - **`CHECK_FILENAME_RE` і `TEST_SUFFIX` removed:** discovery більше не використовує regex `check-*.mjs` — `listJsConcerns` фільтрує `*.mjs` без `.test.mjs` (підкаталоги скіпаються через `!isFile()`).
14
+ - **`scripts/sync-claude-config.mjs::ADR_GITIGNORE_SNIPPET_REL`** змінено: `rules/adr/js/hooks/template/.gitignore.snippet` → `rules/adr/js/templates/hooks/.gitignore.snippet`.
15
+ - **`scripts/utils/inline-template-links.mjs::TEMPLATE_SEGMENT_RE`** розширено з `/\/template\//` до `/\/templates?\//` — підтримує і `js/templates/` (нова конвенція), і `policy/<concern>/template/` (існуюча).
16
+
17
+ ### Breaking (для зовнішніх інтеграторів)
18
+
19
+ - Каталог `npm/rules/<rule>/js/<concern>/check.mjs` тепер `npm/rules/<rule>/js/<concern>.mjs`. Tests → `js/tests/`, templates → `js/templates/`, data → `js/data/` (усе всередині `js/`); helpers → `<rule>/utils/<helper>.mjs` (peer до `js/`, як `abie/utils/`). Імпорти helpers з concern-файлів: `from '../utils/<helper>.mjs'`. Міграційний скрипт у git-історії — комміт `refactor(rules): flat layout js/<concern>.mjs (міграційний move)`.
20
+
21
+ ### Notes
22
+
23
+ - Convention для helper-імен: namespace-префікс (`<rule>-` або `<concern>-`) робить колізії у плоскому `utils/` неможливими (як уже робить abie: `k8s-tree`, `kustomization-patches`; docker: `docker-mirror`; vue: `vue-forbidden-imports`).
24
+ - Шпаргалка імпорт-шляхів у `.cursor/rules/scripts.mdc` (1.10 → 1.11).
25
+ - `.cursor/rules/conftest.mdc` — алгоритм Rego-first переписаний під flat-layout.
26
+ - Канонічні `security.mdc` і `k8s.mdc` markdown-лінки на template-файли оновлені (`./js/templates/<concern>/`).
27
+
28
+ ## [1.13.90] - 2026-05-24
29
+
30
+ ### Added
31
+
32
+ - **`js-lint` 1.23 → 1.24 — конвенція `utils/` vs `lib/`:** додано секцію «Структура спільних модулів». `utils/` — низькорівневі generic helpers без домену (могли б жити окремим npm-пакетом); `lib/` — внутрішні модулі з доменним state/конфігом/side effects. Канонічні назви лише ці дві — не `shared/`, не `common/`. Дзеркало `.cursor/rules/n-js-lint.mdc` оновлено.
33
+
34
+ ## [1.13.89] - 2026-05-23
35
+
36
+ ### Changed
37
+
38
+ - **Stop-hook кличе `fix` замість deprecated `check`:** `scripts/claude-stop-hook.mjs` тепер спавнить `npx --no @nitra/cursor fix` — без deprecation-warning'а на кожен Stop event Claude Code.
39
+ - **`.claude-template/commands/n-check.md` видалено** (разом з локальним `.claude/commands/n-check.md`). Після CLI-перейменування `check` → `fix` slash-команда `/n-check` вказувала на застарілу команду. У `syncClaudeConfig` логіка sync `commands/*.md` залишилась; зараз темплейт порожній. Тест `створює settings.json + slash-команди` переписано на «без slash-команд, коли темплейт порожній».
40
+ - **JSDoc/docstring чистка:** `bin/n-cursor.js` (CLI usage header), `scripts/claude-stop-hook.mjs`, `scripts/sync-claude-config.mjs`, `rules/image-compress/js/package_setup/check.mjs` — згадки `npx @nitra/cursor check`, `/n-check`, `npm/scripts/check-*.mjs` оновлено на актуальну CLI (`fix`) і шляхи (`rules/<id>/fix.mjs`, `rules/<id>/js/<concern>/check.mjs`).
41
+ - **`.cursor/rules/conftest.mdc`** — алгоритм рішення / патерн Rego-authoritative / Workflow / Red-flags переписано під фактичну структуру `rules/<rule>/js/<concern>/check.mjs` + `rules/<rule>/policy/<name>/`. Прибрано згадки `npm/scripts/check-<rule>.mjs` та `npm/policy/<rule>/` (legacy шляхи); приклади `check abie`, `check ga` → `fix abie`, `fix ga`.
42
+ - **`docs/fix-cursor-skill.md`** — ASCII-діаграми, workflow-кроки та таблиця "Анатомія Skill-файлу" → `npx @nitra/cursor fix`; згадка `check-*.mjs скрипти` → `rules/<id>/fix.mjs правил`.
43
+
44
+ ### Notes
45
+
46
+ - Споживачі: після оновлення вручну видалити `.claude/commands/n-check.md` (sync не вичищає orphan slash-команди з темплейту). Активна команда — `/n-fix` (зі скілу `n-fix`).
47
+ - В `.claude/settings.json` permission `Bash(npx @nitra/cursor check)` видалено як redundant — вайлдкард `Bash(npx @nitra/cursor *)` нижче вже покриває обидві команди.
48
+
49
+ ## [1.13.88] - 2026-05-23
50
+
51
+ ### Changed
52
+
53
+ - **`scripts/utils/with-lock.mjs` + тести:** локальна `sleep(ms)` через `new Promise(r => setTimeout(r, ms))` замінена на іменований імпорт `setTimeout as sleep` із `node:timers/promises`. Відповідає правилу `js-run` (без ручних `setTimeout`-промісів) — перевірка `npx @nitra/cursor fix js-run` стала зеленою.
54
+
7
55
  ## [1.13.87] - 2026-05-23
8
56
 
9
57
  ### Added
package/bin/n-cursor.js CHANGED
@@ -5,12 +5,12 @@
5
5
  *
6
6
  * Використання:
7
7
  * `npx \@nitra/cursor` — завантажити cursor-правила
8
- * `npx \@nitra/cursor check` — перевірити правила з `.cursor/rules/*.mdc`, для яких у пакеті є check/policy;
8
+ * `npx \@nitra/cursor fix` — перевірити правила з `.cursor/rules/*.mdc`, для яких у пакеті є `fix.mjs`/policy;
9
9
  * якщо в корені вже є `.n-cursor.json`, спочатку зчитується конфіг і за потреби дописується `$schema`
10
- * `npx \@nitra/cursor check bun` — перевірити лише вказані правила (ігнорує `.cursor/rules/`)
10
+ * `npx \@nitra/cursor fix bun` — перевірити лише вказані правила (ігнорує `.cursor/rules/`)
11
11
  * `npx \@nitra/cursor rename-yaml-extensions` — k8s `*.yml` → `*.yaml`, `.github` `*.yaml` → `*.yml` (опції: `--dry-run`, `--root=…`; див. bin/rename-yaml-extensions.mjs)
12
12
  * `npx \@nitra/cursor stop-hook` — точка входу Stop hook Claude Code (читає stdin, виходить 0 при `stop_hook_active`,
13
- * інакше викликає `check`); прописується автоматично в `.claude/settings.json`
13
+ * інакше викликає `fix`); прописується автоматично в `.claude/settings.json`
14
14
  * `npx \@nitra/cursor lint-ga` — канонічний lint-ga (ga.mdc): preflight на `shellcheck` →
15
15
  * `bunx github-actionlint` → `uvx zizmor --offline --collect=workflows .`
16
16
  * `npx \@nitra/cursor lint-rego` — канонічний lint-rego (conftest.mdc + rego.mdc):
@@ -25,9 +25,8 @@
25
25
  * `npx \@nitra/cursor skill claude taze ["task"]` — Claude Code CLI (`claude -p`)
26
26
  *
27
27
  * Agent інтеграція: під час синку, окрім `.cursor/rules` і `.claude/commands` (з skills), CLI ще раз
28
- * синхронізує `.claude/settings.json` (hooks + permissions; merge — користувацькі поля зберігаються),
29
- * `.cursor/hooks.json` (Cursor Agent hooks; merge — користувацькі hooks зберігаються),
30
- * і slash-команди checks (`/n-check`).
28
+ * синхронізує `.claude/settings.json` (hooks + permissions; merge — користувацькі поля зберігаються)
29
+ * і `.cursor/hooks.json` (Cursor Agent hooks; merge — користувацькі hooks зберігаються).
31
30
  * Опт-аут — поле `claude-config: false` у `.n-cursor.json`.
32
31
  *
33
32
  * Якщо у корені репозиторію немає .n-cursor.json, спочатку перейменовується за наявності nitra-cursor.json;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "1.13.87",
3
+ "version": "1.14.0",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -133,7 +133,7 @@ KVCMS_URL=http://kvcms-hl.ua-apruv.svc.abie-ua.internal:8080
133
133
 
134
134
  `<namespace>` (наприклад `dev-apruv` / `ua-apruv`) — `metadata.name` цільового namespace після kustomize-overlay для відповідного середовища; `<service>` — `metadata.name` headless Service (`-hl`) того сервісу, до якого йде URL.
135
135
 
136
- **Перевірка `js/env_dns/check.mjs`** сканує всі `*.env` файли, basename яких збігається з `dev.env` / `ua.env` (з провідною крапкою чи без), знаходить **усі** internal URL (`http://<svc>.<ns>.svc.<dns>` — як для Hasura-ендпоінта, так і для KVCMS чи будь-якого іншого) і вимагає, щоб для кожного:
136
+ **Перевірка `js/env_dns.mjs`** сканує всі `*.env` файли, basename яких збігається з `dev.env` / `ua.env` (з провідною крапкою чи без), знаходить **усі** internal URL (`http://<svc>.<ns>.svc.<dns>` — як для Hasura-ендпоінта, так і для KVCMS чи будь-якого іншого) і вимагає, щоб для кожного:
137
137
 
138
138
  - DNS-суфікс відповідав env: `abie-dev.internal` / `abie-ua.internal`;
139
139
  - namespace починався з `dev-` / `ua-` відповідно.
@@ -160,7 +160,7 @@ bun add -d @nitra/abie-docs
160
160
 
161
161
  ## Швидкий gate через conftest (Rego)
162
162
 
163
- Підмножину пер-документних правил продубльовано як rego-полісі у **`npm/rules/abie/policy/`** (запускається через **`bun run lint-rego`** для `*_test.rego` юніт-тестів і через **`npx @nitra/cursor fix abie`** для прогону по реальних YAML — деталі в **conftest.mdc** / **n-rego.mdc**). JS у **`js/<concern>/check.mjs`** authoritative — rego тільки швидкий gate для одиничного маніфеста (зокрема через IDE-розширення `tsandall.opa`).
163
+ Підмножину пер-документних правил продубльовано як rego-полісі у **`npm/rules/abie/policy/`** (запускається через **`bun run lint-rego`** для `*_test.rego` юніт-тестів і через **`npx @nitra/cursor fix abie`** для прогону по реальних YAML — деталі в **conftest.mdc** / **n-rego.mdc**). JS у **`js/<concern>.mjs`** authoritative — rego тільки швидкий gate для одиничного маніфеста (зокрема через IDE-розширення `tsandall.opa`).
164
164
 
165
165
  Пакети (директорія в **`npm/policy/abie/`** → namespace → що перевіряє):
166
166
 
@@ -170,12 +170,12 @@ bun add -d @nitra/abie-docs
170
170
  - **`clean_merged_ignore_branches/`** → `abie.clean_merged_ignore_branches` — у workflow `.github/workflows/clean-merged-branch.yml` крок з `uses: phpdocker-io/github-actions-delete-abandoned-branches` має `with.ignore_branches`, що містить токени `dev,ua` (case-insensitive). **Цільові файли:** `.github/workflows/clean-merged-branch.yml`.
171
171
  - **`package_json_docs/`** → `abie.package_json_docs` — у кореневому `package.json` `devDependencies` має містити `@nitra/abie-docs` (presence-only, версію не фіксуємо). **Цільові файли:** `package.json`.
172
172
 
173
- Cross-file / FS-логіка лишається у JS-частинах (`js/<concern>/check.mjs`) — Rego не читає файлову систему й не робить cross-document резолюцію:
173
+ Cross-file / FS-логіка лишається у JS-частинах (`js/<concern>.mjs`) — Rego не читає файлову систему й не робить cross-document резолюцію:
174
174
 
175
- - парність HCP↔Deployment у каталозі та modeline `hc.yaml` — `js/hc_pairing/check.mjs`;
176
- - валідація ua-overlay JSON6902 patches на HTTPRoute + аналіз cross-namespace `backendRefs` у пакетах — `js/ua_http_route/check.mjs`;
177
- - ua-overlay JSON6902 patch на `Deployment.nodeSelector` (`preem: false`) — `js/ua_node_selector/check.mjs`;
178
- - env→cluster DNS (`*.dev.env` / `*.ua.env`) — `js/env_dns/check.mjs`;
179
- - скан артефактів Firebase Hosting у підкаталогах першого рівня — `js/firebase_hosting/check.mjs`.
175
+ - парність HCP↔Deployment у каталозі та modeline `hc.yaml` — `js/hc_pairing.mjs`;
176
+ - валідація ua-overlay JSON6902 patches на HTTPRoute + аналіз cross-namespace `backendRefs` у пакетах — `js/ua_http_route.mjs`;
177
+ - ua-overlay JSON6902 patch на `Deployment.nodeSelector` (`preem: false`) — `js/ua_node_selector.mjs`;
178
+ - env→cluster DNS (`*.dev.env` / `*.ua.env`) — `js/env_dns.mjs`;
179
+ - скан артефактів Firebase Hosting у підкаталогах першого рівня — `js/firebase_hosting.mjs`.
180
180
 
181
181
  Точна звірка `targetRef.name` HealthCheckPolicy з суфіксом `-hl` обчислюється з `hcp.metadata.name` і живе у Rego (`abie.health_check_policy`); за конвенцією `hcp.metadata.name` дорівнює `<deployment.name>`, тому окремий cross-file lookup до маніфесту Deployment не потрібен.
@@ -3,9 +3,9 @@
3
3
  * Якщо повертає `false` — CLI пропускає всі концерни (JS і policy) цього правила.
4
4
  * `check()` друкує тільки context-pass; решта концернів роблять справжню роботу.
5
5
  */
6
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
6
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
7
7
 
8
- import { isAbieRuleEnabled } from '../../utils/enabled.mjs'
8
+ import { isAbieRuleEnabled } from '../utils/enabled.mjs'
9
9
 
10
10
  /**
11
11
  * @returns {Promise<boolean>} `true` — правило застосовне; `false` — пропустити
@@ -9,10 +9,10 @@
9
9
  import { readFile } from 'node:fs/promises'
10
10
  import { basename, relative } from 'node:path'
11
11
 
12
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
13
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
12
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
13
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
14
14
 
15
- import { abieEnvNameFromBasename, collectAbieEnvFiles, validateAbieEnvInternalUrls } from '../../utils/env-dns.mjs'
15
+ import { abieEnvNameFromBasename, collectAbieEnvFiles, validateAbieEnvInternalUrls } from '../utils/env-dns.mjs'
16
16
 
17
17
  /**
18
18
  * @returns {Promise<number>} результат
@@ -7,7 +7,7 @@ import { existsSync } from 'node:fs'
7
7
  import { readdir } from 'node:fs/promises'
8
8
  import { join } from 'node:path'
9
9
 
10
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
10
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
11
11
 
12
12
  const SKIP_TOP_DIR_NAMES = new Set(['.git', 'node_modules'])
13
13
 
@@ -10,11 +10,11 @@ import { existsSync } from 'node:fs'
10
10
  import { readFile } from 'node:fs/promises'
11
11
  import { relative } from 'node:path'
12
12
 
13
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
14
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
13
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
14
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
15
15
 
16
- import { validateAbieHcModeline } from '../../utils/hc-yaml.mjs'
17
- import { collectDeploymentDirs, findK8sYamlFiles } from '../../utils/k8s-tree.mjs'
16
+ import { validateAbieHcModeline } from '../utils/hc-yaml.mjs'
17
+ import { collectDeploymentDirs, findK8sYamlFiles } from '../utils/k8s-tree.mjs'
18
18
 
19
19
  /**
20
20
  * @returns {Promise<number>} результат
@@ -10,20 +10,20 @@
10
10
  import { readFile } from 'node:fs/promises'
11
11
  import { relative } from 'node:path'
12
12
 
13
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
14
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
13
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
14
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
15
15
 
16
- import { analyzeAbieSharedBackendRefsInPackageK8s } from '../../utils/http-route.mjs'
17
- import { findK8sYamlFiles } from '../../utils/k8s-tree.mjs'
16
+ import { analyzeAbieSharedBackendRefsInPackageK8s } from '../utils/http-route.mjs'
17
+ import { findK8sYamlFiles } from '../utils/k8s-tree.mjs'
18
18
  import {
19
19
  getCombinedNginxRunPatchTextFromKustomization,
20
20
  validateAbieNginxRunHttpRoutePatches
21
- } from '../../utils/kustomization-patches.mjs'
21
+ } from '../utils/kustomization-patches.mjs'
22
22
  import {
23
23
  abiePackageDirFromK8sOverlay,
24
24
  abieOverlayRequiresHttpRouteByVite,
25
25
  isUaKustomizationPath
26
- } from '../../utils/overlay-paths.mjs'
26
+ } from '../utils/overlay-paths.mjs'
27
27
 
28
28
  /**
29
29
  * @returns {Promise<number>} результат
@@ -8,12 +8,12 @@
8
8
  import { readFile } from 'node:fs/promises'
9
9
  import { relative } from 'node:path'
10
10
 
11
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
12
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
11
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
12
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
13
13
 
14
- import { collectDeploymentDirs, findK8sYamlFiles } from '../../utils/k8s-tree.mjs'
15
- import { kustomizationHasAbieDeploymentNodeSelectorPatch } from '../../utils/kustomization-patches.mjs'
16
- import { abieOverlayK8sTreeHasDeployment, isUaKustomizationPath } from '../../utils/overlay-paths.mjs'
14
+ import { collectDeploymentDirs, findK8sYamlFiles } from '../utils/k8s-tree.mjs'
15
+ import { kustomizationHasAbieDeploymentNodeSelectorPatch } from '../utils/kustomization-patches.mjs'
16
+ import { abieOverlayK8sTreeHasDeployment, isUaKustomizationPath } from '../utils/overlay-paths.mjs'
17
17
 
18
18
  /**
19
19
  * @returns {Promise<number>} результат
@@ -2,7 +2,7 @@
2
2
  # `spec.template.spec.nodeSelector.preem` зі значенням, що вважається істинним
3
3
  # (boolean `true` або рядок `"true"` без урахування регістру). Overlay ua далі
4
4
  # підміняє селектор JSON6902-патчем на `preem: false`
5
- # (див. `js/ua_node_selector/check.mjs`).
5
+ # (див. `js/ua_node_selector.mjs`).
6
6
  #
7
7
  # Запуск (локально, лише для одного base-YAML з Deployment):
8
8
  # conftest test path/to/k8s/base/deployment.yaml \
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # Cross-file gating: шлях `…/k8s/.../base/…` фільтрується через
13
13
  # `policy/base_deployment_preem/target.json` (glob). Rule-level applies-гейт —
14
- # `js/applies/check.mjs` (поле `rules` у `.n-cursor.json`).
14
+ # `js/applies.mjs` (поле `rules` у `.n-cursor.json`).
15
15
  #
16
16
  # Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
17
17
  # Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
@@ -18,8 +18,8 @@
18
18
  #
19
19
  # Cross-file gating: glob по `hc.yaml` у k8s-дереві — у
20
20
  # `policy/health_check_policy/target.json`. FS-парність HCP↔Deployment та
21
- # modeline `hc.yaml` — `js/hc_pairing/check.mjs`. Rule-level applies-гейт —
22
- # `js/applies/check.mjs`.
21
+ # modeline `hc.yaml` — `js/hc_pairing.mjs`. Rule-level applies-гейт —
22
+ # `js/applies.mjs`.
23
23
  #
24
24
  # Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
25
25
  # Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
@@ -8,7 +8,7 @@
8
8
  #
9
9
  # Cross-file gating (саме шлях `…/k8s/.../base/...` визначає, чи застосовувати
10
10
  # правило) задає glob у `policy/http_route_base/target.json`. Тут — лише
11
- # валідація вмісту `spec.hostnames`. Rule-level applies-гейт — `js/applies/check.mjs`.
11
+ # валідація вмісту `spec.hostnames`. Rule-level applies-гейт — `js/applies.mjs`.
12
12
  #
13
13
  # Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
14
14
  # Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Rule-level applies-гейт abie: чи `.n-cursor.json:rules` містить `abie`.
3
- * Використовується `js/applies/check.mjs` як `applies()`-експорт — якщо false,
3
+ * Використовується `js/applies.mjs` як `applies()`-експорт — якщо false,
4
4
  * CLI пропускає всі концерни правила (включно з policy).
5
5
  */
6
6
  import { existsSync } from 'node:fs'
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { dirname, relative } from 'node:path'
10
10
 
11
- import { pathHasK8sSegment } from '../../k8s/js/manifests/check.mjs'
11
+ import { pathHasK8sSegment } from '../../k8s/js/manifests.mjs'
12
12
  import { walkDir } from '../../../scripts/utils/walkDir.mjs'
13
13
  import { isDeploymentDoc, readAndParseYamlDocs } from './yaml.mjs'
14
14
 
@@ -24,7 +24,7 @@ import { delimiter, dirname, join } from 'node:path'
24
24
  import { env } from 'node:process'
25
25
  import { fileURLToPath } from 'node:url'
26
26
 
27
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
27
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
28
28
 
29
29
  /** Один hook-артефакт: bash-скрипт + його лог-файл, які перевіряємо однотипно. */
30
30
  const HOOK_ARTIFACTS = /** @type {const} */ ([
@@ -20,7 +20,7 @@
20
20
  import { existsSync } from 'node:fs'
21
21
  import { readFile } from 'node:fs/promises'
22
22
 
23
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
23
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
24
24
 
25
25
  /** Розділювач токенів у `scripts.lint` (послідовність пробільних символів). */
26
26
  const WHITESPACE_RE = /\s+/u
@@ -25,7 +25,7 @@ import { existsSync } from 'node:fs'
25
25
  import { readdir, readFile } from 'node:fs/promises'
26
26
  import { join, relative } from 'node:path'
27
27
 
28
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
28
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
29
29
 
30
30
  /** Мінімальна допустима мажорна версія Capacitor (capacitor.mdc) */
31
31
  const MIN_CAPACITOR_MAJOR = 8
@@ -43,7 +43,7 @@ alwaysApply: true
43
43
 
44
44
  **Вимагають bump + нову секцію CHANGELOG** — усі інші зміни в каталозі workspace (код, rego, правила, скіли, конфіги, тести тощо). Виняток `.cursor/` / `.claude/` **не** поширюється на джерело правил у репо `@nitra/cursor` — воно лежить під `npm/`, тож зміни в ньому далі вимагають bump.
45
45
 
46
- Перевірка програмна (`changelog/js/consistency/check.mjs`).
46
+ Перевірка програмна (`changelog/js/consistency.mjs`).
47
47
 
48
48
  ## Дві моделі бази порівняння
49
49
 
@@ -22,13 +22,13 @@ import { readFile } from 'node:fs/promises'
22
22
  import { join } from 'node:path'
23
23
  import { promisify } from 'node:util'
24
24
 
25
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
25
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
26
26
  import {
27
27
  getMonorepoProjectRootDirs,
28
28
  manifestFilePath,
29
29
  parsePyprojectFields,
30
30
  readPackageManifest
31
- } from './package-manifest.mjs'
31
+ } from '../utils/package-manifest.mjs'
32
32
 
33
33
  const execFileAsync = promisify(execFile)
34
34
 
@@ -8,7 +8,7 @@ import { dirname, join, relative } from 'node:path'
8
8
 
9
9
  import { parse as parseToml } from 'smol-toml'
10
10
 
11
- import { getMonorepoPackageRootDirs, isIgnoredWorkspaceRoot } from '../../../../scripts/utils/workspaces.mjs'
11
+ import { getMonorepoPackageRootDirs, isIgnoredWorkspaceRoot } from '../../../scripts/utils/workspaces.mjs'
12
12
 
13
13
  /**
14
14
  * @typedef {'npm' | 'python'} PackageKind
@@ -30,11 +30,11 @@
30
30
  import { readFile } from 'node:fs/promises'
31
31
  import { basename } from 'node:path'
32
32
 
33
- import { getMirrorGcrHint, getFromImageToken } from './docker-mirror.mjs'
34
- import { lintDockerfileWithHadolint, posixRel } from './docker-hadolint.mjs'
35
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
36
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
37
- import { walkDir } from '../../../../scripts/utils/walkDir.mjs'
33
+ import { getMirrorGcrHint, getFromImageToken } from '../utils/docker-mirror.mjs'
34
+ import { lintDockerfileWithHadolint, posixRel } from '../utils/docker-hadolint.mjs'
35
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
36
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
37
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
38
38
 
39
39
  const NEWLINE_RE = /\r?\n/
40
40
  const BUN_INSTALL_RE = /\bbun\s+(?:install|i)\b/iu
@@ -13,7 +13,7 @@
13
13
  import { basename } from 'node:path'
14
14
 
15
15
  import { isRunAsCli } from '../../../scripts/cli-entry.mjs'
16
- import { lintDockerfileWithHadolint, posixRel } from '../js/lint/docker-hadolint.mjs'
16
+ import { lintDockerfileWithHadolint, posixRel } from '../utils/docker-hadolint.mjs'
17
17
  import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
18
18
  import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
19
19
  import { walkDir } from '../../../scripts/utils/walkDir.mjs'
@@ -8,7 +8,7 @@
8
8
  import { spawnSync } from 'node:child_process'
9
9
  import { relative, sep } from 'node:path'
10
10
 
11
- import { resolveCmd } from '../../../../scripts/utils/resolve-cmd.mjs'
11
+ import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
12
12
 
13
13
  /** Тег образу для резервного запуску (узгоджуй з docker.mdc). */
14
14
  export const HADOLINT_IMAGE = 'hadolint/hadolint:v2.12.0'
@@ -17,7 +17,7 @@ version: '1.0'
17
17
  **Тертя** — усе, що ускладнило роботу скілу й стосується самого пакета `@nitra/cursor`, а не коду користувацького проєкту:
18
18
 
19
19
  - неоднозначна чи неповна інструкція в `SKILL.md` або `.mdc`;
20
- - правило вимагає поведінку, яку можна перевірити програмно, але програмної перевірки (`rules/<id>/js/<concern>/check.mjs` або `rules/<id>/policy/<concern>/*.rego`) для неї немає;
20
+ - правило вимагає поведінку, яку можна перевірити програмно, але програмної перевірки (`rules/<id>/js/<concern>.mjs` або `rules/<id>/policy/<concern>/*.rego`) для неї немає;
21
21
  - хибне спрацювання перевірки (false positive);
22
22
  - порушення, яке правило вимагає виправляти вручну, хоча реальний автофікс можливий;
23
23
  - повторюваний патерн, який варто закодувати в правило чи скіл.
@@ -20,11 +20,11 @@ import { execFileSync } from 'node:child_process'
20
20
  import { basename, dirname, join } from 'node:path'
21
21
  import { fileURLToPath } from 'node:url'
22
22
 
23
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
24
- import { eventPathsIncludeExact, parseWorkflowYaml } from '../../../../scripts/utils/gha-workflow.mjs'
25
- import { resolveCmd } from '../../../../scripts/utils/resolve-cmd.mjs'
26
- import { runConftestBatch } from '../../../../scripts/utils/run-conftest-batch.mjs'
27
- import { loadTemplate } from '../../../../scripts/utils/template.mjs'
23
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
24
+ import { eventPathsIncludeExact, parseWorkflowYaml } from '../../../scripts/utils/gha-workflow.mjs'
25
+ import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
26
+ import { runConftestBatch } from '../../../scripts/utils/run-conftest-batch.mjs'
27
+ import { loadTemplate } from '../../../scripts/utils/template.mjs'
28
28
 
29
29
  const HERE = dirname(fileURLToPath(import.meta.url))
30
30
  const GA_POLICY_DIR = join(HERE, '..', '..', 'policy')
@@ -29,7 +29,7 @@
29
29
  */
30
30
  import { platform } from 'node:process'
31
31
 
32
- import { check as checkGa } from '../js/workflows/check.mjs'
32
+ import { check as checkGa } from '../js/workflows.mjs'
33
33
  import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
34
34
  import { runLintStep } from '../../../scripts/utils/run-lint-step.mjs'
35
35
  import { runStandardLint } from '../../../scripts/utils/run-standard-lint.mjs'
@@ -10,15 +10,15 @@ import { existsSync } from 'node:fs'
10
10
  import { readFile } from 'node:fs/promises'
11
11
  import { relative } from 'node:path'
12
12
 
13
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
13
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
14
14
  import {
15
15
  isGqlScanSourceFile,
16
16
  shouldSkipFileForGqlScan,
17
17
  sourceFileHasGqlTaggedTemplate
18
- } from './graphql-gql-scan.mjs'
19
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
20
- import { runConftestBatch } from '../../../../scripts/utils/run-conftest-batch.mjs'
21
- import { walkDir } from '../../../../scripts/utils/walkDir.mjs'
18
+ } from '../utils/graphql-gql-scan.mjs'
19
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
20
+ import { runConftestBatch } from '../../../scripts/utils/run-conftest-batch.mjs'
21
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
22
22
 
23
23
  /** Очікуваний файл GraphQL Config у корені (graphql.mdc). */
24
24
  export const GRAPHQL_RC_FILENAME = '.graphqlrc.yml'
@@ -28,10 +28,10 @@ import { basename, join, relative } from 'node:path'
28
28
 
29
29
  import { parseAllDocuments } from 'yaml'
30
30
 
31
- import { getRepositoryUrl } from '../../../../scripts/auto-rules.mjs'
32
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
33
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
34
- import { walkDir } from '../../../../scripts/utils/walkDir.mjs'
31
+ import { getRepositoryUrl } from '../../../scripts/auto-rules.mjs'
32
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
33
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
34
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
35
35
 
36
36
  const NITRA_REPOSITORY_URL_MARKER = 'https://github.com/nitra/'
37
37
  const ABIE_REPOSITORY_URL_MARKER = 'https://github.com/abinbevefes/'
@@ -8,7 +8,7 @@
8
8
  # conftest test hasura/k8s/base/svc-hl.yaml -p npm/rules/hasura/policy/svc_hl \
9
9
  # --namespace hasura.svc_hl
10
10
  #
11
- # Cross-file (`HASURA_GRAPHQL_ENDPOINT` ↔ YAML) — `js/internal_urls/check.mjs`.
11
+ # Cross-file (`HASURA_GRAPHQL_ENDPOINT` ↔ YAML) — `js/internal_urls.mjs`.
12
12
  package hasura.svc_hl
13
13
 
14
14
  import rego.v1
@@ -30,11 +30,11 @@ import { join, relative } from 'node:path'
30
30
  import { spawnSync } from 'node:child_process'
31
31
  import { env } from 'node:process'
32
32
 
33
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
34
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
35
- import { resolveCmd } from '../../../../scripts/utils/resolve-cmd.mjs'
36
- import { walkDir } from '../../../../scripts/utils/walkDir.mjs'
37
- import { getMonorepoPackageRootDirs } from '../../../../scripts/utils/workspaces.mjs'
33
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
34
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
35
+ import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
36
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
37
+ import { getMonorepoPackageRootDirs } from '../../../scripts/utils/workspaces.mjs'
38
38
 
39
39
  /** Імʼя CLI-пакета, який генерує AVIF. */
40
40
  const MINIFY_PACKAGE_NAME = '@nitra/minify-image'
@@ -9,8 +9,8 @@
9
9
  * - застарілий `.minify-image-cache.tsv` (з версій < 3.2) видалений з кореня та
10
10
  * з `.gitignore`.
11
11
  *
12
- * **Що покрила Rego** (`npx \@nitra/cursor check`,
13
- * `npm/policy/image_compress/package_json/`):
12
+ * **Що покрила Rego** (`npx \@nitra/cursor fix`,
13
+ * `npm/rules/image-compress/policy/package_json/`):
14
14
  * - `scripts.lint-image` викликає `npx \@nitra/minify-image --src=. --write`
15
15
  * без `--avif` (AVIF — окреме правило `image-avif`);
16
16
  * - агрегований `lint` (якщо є) містить `bun run lint-image`;
@@ -19,7 +19,7 @@
19
19
  import { existsSync } from 'node:fs'
20
20
  import { readFile } from 'node:fs/promises'
21
21
 
22
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
22
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
23
23
 
24
24
  /** Імʼя committed-кешу (sha1 + originalSize + size) у `@nitra/minify-image` ≥ 3.2.0. */
25
25
  const HASH_CACHE_FILENAME = '.n-minify-image.tsv'
@@ -33,7 +33,7 @@ import { existsSync } from 'node:fs'
33
33
  import { readFile } from 'node:fs/promises'
34
34
  import { join, relative } from 'node:path'
35
35
 
36
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
36
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
37
37
  import {
38
38
  findBunSqlPerRequestConnectionInText,
39
39
  findBunSqlPgLeftoverCallInText,
@@ -48,10 +48,10 @@ import {
48
48
  isBunSqlScanSourceFile,
49
49
  textHasBunSqlImport,
50
50
  textHasPgLibImport
51
- } from './bun-sql-scan.mjs'
52
- import { findAllPackageJsonPaths } from '../../../../scripts/utils/find-package-json-paths.mjs'
53
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
54
- import { walkDir } from '../../../../scripts/utils/walkDir.mjs'
51
+ } from '../utils/bun-sql-scan.mjs'
52
+ import { findAllPackageJsonPaths } from '../../../scripts/utils/find-package-json-paths.mjs'
53
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
54
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
55
55
 
56
56
  // Дешеві pre-filter regex'и для AST-сканера LISTEN/NOTIFY: уникаємо парсингу
57
57
  // файлів, у яких ніяких сигналів немає. Винесено в модульний скоуп, щоб не
@@ -27,7 +27,7 @@ import {
27
27
  parseProgramOrNull,
28
28
  templateQuasisText,
29
29
  walkAstWithAncestors
30
- } from '../../../../scripts/utils/ast-scan-utils.mjs'
30
+ } from '../../../scripts/utils/ast-scan-utils.mjs'
31
31
 
32
32
  const SOURCE_FILE_RE = /\.([cm]?[jt]sx?)$/u
33
33
  const BUN_SQL_IMPORT_RE = /\bimport\s*\{[\s\S]*?\b(sql|SQL)\b[\s\S]*?\}\s*from\s*["']bun["']/u
@@ -14,14 +14,14 @@ import { existsSync } from 'node:fs'
14
14
  import { readFile } from 'node:fs/promises'
15
15
  import { join, relative } from 'node:path'
16
16
 
17
- import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mjs'
18
- import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-config.mjs'
17
+ import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
18
+ import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
19
19
  import {
20
20
  findRedisImportsInText,
21
21
  isRedisScanSourceFile,
22
22
  shouldSkipFileForRedisScan
23
- } from '../../../../scripts/utils/redis-imports.mjs'
24
- import { walkDir } from '../../../../scripts/utils/walkDir.mjs'
23
+ } from '../../../scripts/utils/redis-imports.mjs'
24
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
25
25
 
26
26
  /**
27
27
  * Збирає абсолютні шляхи JS/TS джерел у репозиторії для скану заборонених redis-імпортів.