@nitra/cursor 12.8.4 → 12.8.6

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 (35) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/bin/n-cursor.js +8 -7
  3. package/package.json +1 -1
  4. package/rules/abie/js/env_dns.mdc +33 -0
  5. package/rules/abie/js/firebase_hosting.mdc +3 -0
  6. package/rules/abie/js/hc_pairing.mdc +23 -0
  7. package/rules/abie/js/http_route_base.mdc +25 -0
  8. package/rules/abie/js/ua_http_route.mdc +47 -0
  9. package/rules/abie/js/ua_node_selector.mdc +27 -0
  10. package/rules/abie/main.mdc +11 -127
  11. package/rules/doc-files/js/docs/index.md +15 -15
  12. package/rules/js/docs/main.md +6 -6
  13. package/rules/js/js/docs/check.md +11 -10
  14. package/rules/js/js/docs/tooling.md +7 -7
  15. package/rules/js/js/docs/utils_imports.md +13 -12
  16. package/rules/test/js/docs/stryker_config.md +12 -12
  17. package/rules/test/js/docs/vitest-config-pool-forks.md +13 -7
  18. package/scripts/auto-rules.mjs +6 -6
  19. package/scripts/auto-skills.mjs +3 -3
  20. package/scripts/docs/auto-rules.md +17 -31
  21. package/scripts/docs/auto-skills.md +18 -163
  22. package/scripts/docs/sync-setup-bun-deps-action.md +6 -5
  23. package/scripts/lib/docs/inline-template-links.md +13 -293
  24. package/scripts/lib/docs/mirror-parity.md +9 -9
  25. package/scripts/lib/docs/rule-meta.md +12 -12
  26. package/scripts/lib/docs/skill-meta.md +9 -9
  27. package/scripts/lib/docs/timing-summary.md +6 -6
  28. package/scripts/lib/docs/worktree-notice.md +10 -8
  29. package/scripts/lib/inline-template-links.mjs +31 -0
  30. package/scripts/lib/mirror-parity.mjs +5 -3
  31. package/scripts/lib/rule-meta.mjs +6 -6
  32. package/scripts/lib/skill-meta.mjs +6 -6
  33. package/scripts/lib/worktree-notice.mjs +2 -2
  34. package/scripts/utils/docs/resolve-js-root.md +4 -4
  35. package/types/bin/n-cursor.d.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [12.8.6] - 2026-06-22
4
+
5
+ ### Changed
6
+
7
+ - ✨ feat(rules/abie): http_route_base.mdc + активація + ua-домени у ua_http_route.mdc
8
+
9
+ ## [12.8.5] - 2026-06-22
10
+
11
+ ### Changed
12
+
13
+ - ♻️ refactor(npm): Перехід з `style-lint` на `style` у правил та конфігах
14
+
3
15
  ## [12.8.4] - 2026-06-22
4
16
 
5
17
  ### Changed
package/bin/n-cursor.js CHANGED
@@ -74,7 +74,7 @@ import { fileURLToPath } from 'node:url'
74
74
 
75
75
  import { buildAgentsCommandBulletItems } from '../scripts/build-agents-commands.mjs'
76
76
  import { formatGeneratedMarkdownLines, renderAgentsTemplate } from '../scripts/lib/generated-markdown.mjs'
77
- import { inlineTemplateLinks } from '../scripts/lib/inline-template-links.mjs'
77
+ import { inlineMarkdownIncludes, inlineTemplateLinks } from '../scripts/lib/inline-template-links.mjs'
78
78
  import {
79
79
  detectAutoRules,
80
80
  detectLegacyRuleIds,
@@ -422,7 +422,8 @@ async function readBundledRuleContent(rule, bundledRulesDir = BUNDLED_RULES_DIR)
422
422
  )
423
423
  }
424
424
  const text = await readFile(bundledPath, 'utf8')
425
- return inlineTemplateLinks(text, dirname(bundledPath))
425
+ const withTemplates = await inlineTemplateLinks(text, dirname(bundledPath))
426
+ return inlineMarkdownIncludes(withTemplates, dirname(bundledPath))
426
427
  }
427
428
 
428
429
  /**
@@ -629,16 +630,16 @@ function buildClaudeLintParallelismSectionLines() {
629
630
  }
630
631
 
631
632
  /**
632
- * Рендерить секцію для CLAUDE.md: скіли з `meta.json.worktree === true` запускаються
633
+ * Рендерить секцію для CLAUDE.md: скіли з `main.json.worktree === true` запускаються
633
634
  * лише в окремому git-worktree (дублює fail-fast банер `SKILL.md` як завжди-читане правило).
634
635
  * @returns {string[]} рядки для вставки (з порожнім рядком на початку)
635
636
  */
636
637
  function buildClaudeWorktreeEnforcementSectionLines() {
637
638
  return [
638
639
  '',
639
- '## Worktree-only skills (`meta.json` → `worktree: true`)',
640
+ '## Worktree-only skills (`main.json` → `worktree: true`)',
640
641
  '',
641
- 'Скіл із **`worktree: true`** у `meta.json` запускається **виключно** в окремому git-worktree (`.worktrees/<current-branch>-<suffix>/`) — **не** в основному дереві й **не** паралельно. Перший крок такого скіла (блок `n-cursor:worktree:start` у його `SKILL.md`) — **preflight**: якщо `git rev-parse --show-toplevel` не вказує під `.worktrees/`, **STOP** і не питай користувача про назву гілки; створи worktree від поточної гілки готовим snippet з `SKILL.md` за конвенцією `<current-branch>-<suffix>` і без shell expansion (без command substitution, variable expansion чи backticks). Чисте робоче дерево — **не** привід пропустити preflight.',
642
+ 'Скіл із **`worktree: true`** у `main.json` запускається **виключно** в окремому git-worktree (`.worktrees/<current-branch>-<suffix>/`) — **не** в основному дереві й **не** паралельно. Перший крок такого скіла (блок `n-cursor:worktree:start` у його `SKILL.md`) — **preflight**: якщо `git rev-parse --show-toplevel` не вказує під `.worktrees/`, **STOP** і не питай користувача про назву гілки; створи worktree від поточної гілки готовим snippet з `SKILL.md` за конвенцією `<current-branch>-<suffix>` і без shell expansion (без command substitution, variable expansion чи backticks). Чисте робоче дерево — **не** привід пропустити preflight.',
642
643
  ''
643
644
  ]
644
645
  }
@@ -794,10 +795,10 @@ async function syncSkills(configSkills, bundledSkillsDir = BUNDLED_SKILLS_DIR) {
794
795
  const rootOnly = !worktree && meta?.requireRoot === true
795
796
  const entries = await readdir(srcDir, { withFileTypes: true })
796
797
  for (const entry of entries) {
797
- // Лише top-level файли скіла. `meta.json` — метадані (не для споживача);
798
+ // Лише top-level файли скіла. `main.json` — метадані (не для споживача);
798
799
  // підкаталоги (`js/` — скіл-специфічний код) виконуються з пакета через
799
800
  // `npx`, у проєкт не копіюються (як `npm/rules/<id>/js/`). Див. scripts.mdc.
800
- if (!entry.isFile() || entry.name === 'meta.json') continue
801
+ if (!entry.isFile() || entry.name === 'main.json') continue
801
802
  let content = await readFile(join(srcDir, entry.name), 'utf8')
802
803
  if (entry.name === 'SKILL.md') {
803
804
  content = injectWorktreeNotice(content, worktree)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "12.8.4",
3
+ "version": "12.8.6",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -0,0 +1,33 @@
1
+ ## Внутрішньокластерні URL у env-файлах (dev / ua)
2
+
3
+ Правило стосується **будь-якого** внутрішньокластерного URL у env-файлах abie-проєкту, а не лише `HASURA_GRAPHQL_ENDPOINT`. Це може бути URL до Hasura, KVCMS, `auth-run-hl`, `file-link-hl` чи будь-якого іншого Service у кластері — у всіх випадках DNS-суфікс і namespace-префікс мають відповідати **середовищу** з імені env-файлу.
4
+
5
+ abie-проєкти живуть у **двох GKE-кластерах** (dev / ua), тож DNS-суфікс і namespace у URL відрізняються між `*.env`-файлами:
6
+
7
+ | env-файл (basename) | namespace-префікс у URL | DNS-суфікс кластера | примітка |
8
+ | --- | --- | --- | --- |
9
+ | `dev.env`, `.dev.env` | `dev-…` | `abie-dev.internal` | GKE-кластер dev |
10
+ | `ua.env`, `.ua.env` | `ua-…` | `abie-ua.internal` | GKE-кластер ua |
11
+
12
+ Канонічна форма URL — `http://<service>.<namespace>.svc.<cluster-dns-suffix>:<port>`. Суфікс — `<cluster>.internal`.
13
+
14
+ Приклади для одного env-файлу з двома сервісами (Hasura + KVCMS):
15
+
16
+ ```env title="hasura/.dev.env"
17
+ HASURA_GRAPHQL_ENDPOINT=http://apruv-h-hl.dev-apruv.svc.abie-dev.internal:8080
18
+ KVCMS_URL=http://kvcms-hl.dev-apruv.svc.abie-dev.internal:8080
19
+ ```
20
+
21
+ ```env title="hasura/.ua.env"
22
+ HASURA_GRAPHQL_ENDPOINT=http://apruv-h-hl.ua-apruv.svc.abie-ua.internal:8080
23
+ KVCMS_URL=http://kvcms-hl.ua-apruv.svc.abie-ua.internal:8080
24
+ ```
25
+
26
+ `<namespace>` (наприклад `dev-apruv` / `ua-apruv`) — `metadata.name` цільового namespace після kustomize-overlay для відповідного середовища; `<service>` — `metadata.name` headless Service (`-hl`) того сервісу, до якого йде URL.
27
+
28
+ **Перевірка `js/env_dns.mjs`** сканує всі `*.env` файли, basename яких збігається з `dev.env` / `ua.env` (з провідною крапкою чи без), знаходить **усі** internal URL (`http://<svc>.<ns>.svc.<dns>` — як для Hasura-ендпоінта, так і для KVCMS чи будь-якого іншого) і вимагає, щоб для кожного:
29
+
30
+ - DNS-суфікс відповідав env: `abie-dev.internal` / `abie-ua.internal`;
31
+ - namespace починався з `dev-` / `ua-` відповідно.
32
+
33
+ Загальне правило про **внутрішній** URL (не публічний домен) для `HASURA_GRAPHQL_ENDPOINT` лишається у **`hasura.mdc`** (для nitra і abie) — `rules/hasura/fix.mjs` приймає кластерний DNS-формат `<cluster>.internal`.
@@ -0,0 +1,3 @@
1
+ ## Firebase Hosting
2
+
3
+ У **кожному** підкаталозі, що лежить **безпосередньо** в корені репозиторію, не тримати конфіг і кеш **Firebase Hosting**: у таких каталогах не повинно бути **`.firebaserc`**, **`firebase.json`** та каталогу **`.firebase/`** (у **самому** корені репозиторію ці імена перевіркою abie **не** розглядаються; `node_modules` / `.git` зі скану вилучаються).
@@ -0,0 +1,23 @@
1
+ ## k8s: `hc.yaml` поруч із Deployment
2
+
3
+ Якщо під **`k8s`** є **Deployment**, у **тій самій директорії** має бути **`hc.yaml`** з **HealthCheckPolicy** (**`networking.gke.io/v1`**): коректний modeline **`$schema`**, **`httpHealthCheck.requestPath`** — непорожній шлях від кореня (рядок, що починається з **`/`**: канонічно **`/healthz`**, але також допустимі **`/IsAlive`**, **`/api/live`** тощо — узгоджується з реальним endpoint сервісу), порт **8080**, **`targetRef.name`** — **headless** **Service** з суфіксом **`-hl`** (узгоджено з парою **`svc.yaml`** / **`svc-hl.yaml`** у **k8s.mdc**): або **`${metadata.name}-hl`**, або те саме ім'я, якщо **`metadata.name`** уже з **`-hl`**.
4
+
5
+ ```yaml title="hc.yaml"
6
+ # yaml-language-server: $schema=https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json
7
+ apiVersion: networking.gke.io/v1
8
+ kind: HealthCheckPolicy
9
+ metadata:
10
+ name: СЕРВІС
11
+ namespace: dev # kustomize overlay
12
+ spec:
13
+ default:
14
+ config:
15
+ type: HTTP
16
+ httpHealthCheck:
17
+ requestPath: /healthz
18
+ port: 8080
19
+ targetRef:
20
+ group: ''
21
+ kind: Service
22
+ name: СЕРВІС-hl
23
+ ```
@@ -0,0 +1,25 @@
1
+ ## k8s: **HTTPRoute** у base-шарі — домени `aiml.live`
2
+
3
+ У **HTTPRoute** під шляхом **`…/k8s/.../base/...`** (сегмент `base` у path) усі значення **`spec.hostnames`** мають належати до домену **`aiml.live`**: точна відповідність **`aiml.live`**, wildcard **`*.aiml.live`** або будь-який піддомен (**`api.aiml.live`**, **`app.aiml.live`** тощо). Перевірка — case-insensitive.
4
+
5
+ Rego-пакет: **`abie.http_route_base`** (`policy/http_route_base/`). Цільові файли: `…/k8s/.../base/.../*.yaml` типу HTTPRoute.
6
+
7
+ ```yaml title="…/k8s/base/hr.yaml"
8
+ apiVersion: gateway.networking.k8s.io/v1
9
+ kind: HTTPRoute
10
+ metadata:
11
+ name: my-app
12
+ spec:
13
+ hostnames:
14
+ - "my-app.aiml.live" # ✓ піддомен aiml.live
15
+ parentRefs:
16
+ - name: gateway
17
+ ```
18
+
19
+ Недозволені в base-шарі (але коректні для ua-overlay — `abie.app`, `vybeerai.com.ua`):
20
+
21
+ ```yaml
22
+ hostnames:
23
+ - "abie.app" # ✗ ua-домен, не base
24
+ - "vybeerai.com.ua" # ✗ ua-домен, не base
25
+ ```
@@ -0,0 +1,47 @@
1
+ ## k8s: overlay **HTTPRoute** (**ua**)
2
+
3
+ За наявності **Deployment** під **k8s** і наявності **Vite** (**`vite.config.js`**, **`vite.config.mjs`** або **`vite.config.ts`** у каталозі пакета) у **`ua/kustomization.yaml`** цього пакета потрібні **inline JSON6902** у **`patches`**: **target** **`kind: HTTPRoute`**, **непорожній `name`** (як у маніфесті маршруту). Мають бути зміни **`/spec/hostnames`** (хоча б один з доменів: **`abie.app`**, **`vybeerai.com.ua`**, **`*.abie.app`**, **`*.vybeerai.com.ua`**) та **`/spec/parentRefs/0/namespace`** (**`ua`**, також дозволені префікси **`ua-*`**, наприклад **`ua-b2b`**). Як обирати **`op`** (**add** / **replace** тощо) у patch — **k8s.mdc** (розділ про JSON patch у kustomization).
4
+
5
+ ### HTTPRoute: спільні сервіси **`auth-run-hl`**, **`file-link-hl`**
6
+
7
+ У **HTTPRoute** у шляху з **`…/k8s/base/…`** у **`spec.hostnames`** дозволені лише **`aiml.live`**, **`*.aiml.live`** та інші піддомени **aiml.live** (перевірка — Rego-пакет **`abie.http_route_base`**, див. розділ нижче).
8
+
9
+ Ці **Service** (headless **`-hl`**) живуть у **базовому** неймспейсі **`dev`**. У маніфесті **HTTPRoute** під **`k8s`** (шар без **`ua/`** — наприклад **`…/k8s/base/hr.yaml`**) для кожного **`backendRefs`** до такого сервісу явно вкажи **`namespace: dev`** і порт **8080**:
10
+
11
+ ```yaml title="…/k8s/base/hr.yaml (фрагмент)"
12
+ spec:
13
+ rules:
14
+ - matches:
15
+ - path:
16
+ type: PathPrefix
17
+ value: /
18
+ backendRefs:
19
+ - name: auth-run-hl
20
+ namespace: dev
21
+ port: 8080
22
+ - name: file-link-hl
23
+ namespace: dev
24
+ port: 8080
25
+ ```
26
+
27
+ У **`ua/kustomization.yaml`** додай до того самого **inline** patch на **`HTTPRoute`** (той самий **`target.name`**) операції **JSON6902** з **`path`**: **`/spec/rules/<i>/backendRefs/<j>/namespace`**, де **`<i>`** / **`<j>`** — індекси відповідно до порядку **`spec.rules`** та **`backendRefs`** у base-файлі; **`value`**: **`ua`** (також дозволені **`ua-*`**). Якщо кілька таких **`backendRefs`**, потрібна окрема операція для кожного.
28
+
29
+ ```yaml title="…/ua/kustomization.yaml (фрагмент)"
30
+ - target:
31
+ kind: HTTPRoute
32
+ name: my-httproute
33
+ patch: |-
34
+ - op: replace
35
+ path: /spec/hostnames
36
+ value:
37
+ - "abie.app" # зокрема vybeerai.com.ua, *.vybeerai.com.ua, *.abie.app
38
+ - op: replace
39
+ path: /spec/parentRefs/0/namespace
40
+ value: ua
41
+ - op: replace
42
+ path: /spec/rules/0/backendRefs/0/namespace
43
+ value: ua
44
+ - op: replace
45
+ path: /spec/rules/0/backendRefs/1/namespace
46
+ value: ua
47
+ ```
@@ -0,0 +1,27 @@
1
+ ## k8s: overlay **ua** і nodeSelector
2
+
3
+ У **`…/ua/kustomization.yaml`** того пакета, у дереві **`k8s`** якого є **Deployment**, потрібен patch на **`kind: Deployment`**: **`spec.template.spec.nodeSelector`** з **`preem: false`**. Форму **JSON6902** (шлях **`/spec/template/spec/nodeSelector`**, **`op`**) див. **k8s.mdc**.
4
+
5
+ ```yaml title="…/ua/kustomization.yaml (фрагмент)"
6
+ patches:
7
+ - target:
8
+ kind: Deployment
9
+ name: my-app
10
+ patch: |-
11
+ - op: add
12
+ path: /spec/template/spec/nodeSelector
13
+ value:
14
+ preem: 'false'
15
+ ```
16
+
17
+ ### Базовий Deployment (`…/base/`)
18
+
19
+ Якщо **Deployment** у YAML під **`k8s`** лежить у шляху з сегментом **`base`**, у **`spec.template.spec.nodeSelector`** має бути **`preem`** зі значенням **істинно** (**`true`** або рядок **`'true'`**); overlay **ua** підміняє селектор.
20
+
21
+ ```yaml title="…/base/deploy.yaml (фрагмент)"
22
+ spec:
23
+ template:
24
+ spec:
25
+ nodeSelector:
26
+ preem: 'true' # буде замінено через kustomize
27
+ ```
@@ -6,139 +6,25 @@ version: '1.22'
6
6
 
7
7
  Правило **abie** для споживачів **@nitra/cursor**: **k8s** (Deployment + **HealthCheckPolicy** у **`hc.yaml`**, overlay **ua** — **nodeSelector**, **HTTPRoute** (будь-який непорожній **`target.name`**, для спільних сервісів **`auth-run-hl`** / **`file-link-hl`** — **`namespace: dev`** у base та patch **`…/backendRefs/…/namespace`** у **ua**)), гілки **dev**, **ua** у **clean-merged-branch**, а також заборона тримати артефакти **Firebase Hosting** у **підкаталогах першого рівня** (безпосередні діти кореня репозиторію; у самому корені ці імена не вимагаються до видалення).
8
8
 
9
- ## k8s: `hc.yaml` поруч із Deployment
10
-
11
- Якщо під **`k8s`** є **Deployment**, у **тій самій директорії** має бути **`hc.yaml`** з **HealthCheckPolicy** (**`networking.gke.io/v1`**): коректний modeline **`$schema`**, **`httpHealthCheck.requestPath`** — непорожній шлях від кореня (рядок, що починається з **`/`**: канонічно **`/healthz`**, але також допустимі **`/IsAlive`**, **`/api/live`** тощо — узгоджується з реальним endpoint сервісу), порт **8080**, **`targetRef.name`** — **headless** **Service** з суфіксом **`-hl`** (узгоджено з парою **`svc.yaml`** / **`svc-hl.yaml`** у **k8s.mdc**): або **`${metadata.name}-hl`**, або те саме ім’я, якщо **`metadata.name`** уже з **`-hl`**.
12
-
13
- ```yaml title="hc.yaml"
14
- # yaml-language-server: $schema=https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json
15
- apiVersion: networking.gke.io/v1
16
- kind: HealthCheckPolicy
17
- metadata:
18
- name: СЕРВІС
19
- namespace: dev # kustomize overlay
20
- spec:
21
- default:
22
- config:
23
- type: HTTP
24
- httpHealthCheck:
25
- requestPath: /healthz
26
- port: 8080
27
- targetRef:
28
- group: ''
29
- kind: Service
30
- name: СЕРВІС-hl
31
- ```
32
-
33
- ## k8s: overlay **HTTPRoute** (**ua**)
34
-
35
- За наявності **Deployment** під **k8s** і наявності **Vite** (**`vite.config.js`**, **`vite.config.mjs`** або **`vite.config.ts`** у каталозі пакета) у **`ua/kustomization.yaml`** цього пакета потрібні **inline JSON6902** у **`patches`**: **target** **`kind: HTTPRoute`**, **непорожній `name`** (як у маніфесті маршруту). Мають бути зміни **`/spec/hostnames`** (домени abie — у скрипті) та **`/spec/parentRefs/0/namespace`** (**`ua`**, також дозволені префікси **`ua-*`**, наприклад **`ua-b2b`**). Як обирати **`op`** (**add** / **replace** тощо) у patch — **k8s.mdc** (розділ про JSON patch у kustomization).
36
-
37
- ### HTTPRoute: спільні сервіси **`auth-run-hl`**, **`file-link-hl`**
38
-
39
- У **HTTPRoute** у шляху з **`…/k8s/base/…`** у **`spec.hostnames`** дозволені лише **`aiml.live`**, **`*.aiml.live`** та інші піддомени **aiml.live** (перевірка — Rego-пакет **`abie.http_route_base`**, див. розділ нижче).
40
-
41
- Ці **Service** (headless **`-hl`**) живуть у **базовому** неймспейсі **`dev`**. У маніфесті **HTTPRoute** під **`k8s`** (шар без **`ua/`** — наприклад **`…/k8s/base/hr.yaml`**) для кожного **`backendRefs`** до такого сервісу явно вкажи **`namespace: dev`** і порт **8080**:
42
-
43
- ```yaml title="…/k8s/base/hr.yaml (фрагмент)"
44
- spec:
45
- rules:
46
- - matches:
47
- - path:
48
- type: PathPrefix
49
- value: /
50
- backendRefs:
51
- - name: auth-run-hl
52
- namespace: dev
53
- port: 8080
54
- - name: file-link-hl
55
- namespace: dev
56
- port: 8080
57
- ```
58
-
59
- У **`ua/kustomization.yaml`** додай до того самого **inline** patch на **`HTTPRoute`** (той самий **`target.name`**) операції **JSON6902** з **`path`**: **`/spec/rules/<i>/backendRefs/<j>/namespace`**, де **`<i>`** / **`<j>`** — індекси відповідно до порядку **`spec.rules`** та **`backendRefs`** у base-файлі; **`value`**: **`ua`** (також дозволені **`ua-*`**). Якщо кілька таких **`backendRefs`**, потрібна окрема операція для кожного.
60
-
61
- ```yaml title="…/ua/kustomization.yaml (фрагмент)"
62
- - target:
63
- kind: HTTPRoute
64
- name: my-httproute
65
- patch: |-
66
- - op: replace
67
- path: /spec/hostnames
68
- value:
69
- - "abie.app" # зокрема vybeerai.com.ua, *.vybeerai.com.ua, *.abie.app
70
- - op: replace
71
- path: /spec/parentRefs/0/namespace
72
- value: ua
73
- - op: replace
74
- path: /spec/rules/0/backendRefs/0/namespace
75
- value: ua
76
- - op: replace
77
- path: /spec/rules/0/backendRefs/1/namespace
78
- value: ua
79
- ```
80
-
81
- ## k8s: overlay **ua** і nodeSelector
82
-
83
- У **`…/ua/kustomization.yaml`** того пакета, у дереві **`k8s`** якого є **Deployment**, потрібен patch на **`kind: Deployment`**: **`spec.template.spec.nodeSelector`** з **`preem: false`**. Форму **JSON6902** (шлях **`/spec/template/spec/nodeSelector`**, **`op`**) див. **k8s.mdc**.
9
+ ## Активація
84
10
 
85
- ```yaml title="…/ua/kustomization.yaml (фрагмент)"
86
- patches:
87
- - target:
88
- kind: Deployment
89
- name: my-app
90
- patch: |-
91
- - op: add
92
- path: /spec/template/spec/nodeSelector
93
- value:
94
- preem: 'false'
95
- ```
96
-
97
- ### Базовий Deployment (`…/base/`)
98
-
99
- Якщо **Deployment** у YAML під **`k8s`** лежить у шляху з сегментом **`base`**, у **`spec.template.spec.nodeSelector`** має бути **`preem`** зі значенням **істинно** (**`true`** або рядок **`'true'`**); overlay **ua** підміняє селектор.
11
+ Правило активується через **`.n-cursor.json`** у корені репозиторію:
100
12
 
101
- ```yaml title="…/base/deploy.yaml (фрагмент)"
102
- spec:
103
- template:
104
- spec:
105
- nodeSelector:
106
- preem: 'true' # буде замінено через kustomize
13
+ ```json
14
+ { "rules": ["abie"] }
107
15
  ```
108
16
 
109
- ## Внутрішньокластерні URL у env-файлах (dev / ua)
110
-
111
- Правило стосується **будь-якого** внутрішньокластерного URL у env-файлах abie-проєкту, а не лише `HASURA_GRAPHQL_ENDPOINT`. Це може бути URL до Hasura, KVCMS, `auth-run-hl`, `file-link-hl` чи будь-якого іншого Service у кластері — у всіх випадках DNS-суфікс і namespace-префікс мають відповідати **середовищу** з імені env-файлу.
112
-
113
- abie-проєкти живуть у **двох GKE-кластерах** (dev / ua), тож DNS-суфікс і namespace у URL відрізняються між `*.env`-файлами:
114
-
115
- | env-файл (basename) | namespace-префікс у URL | DNS-суфікс кластера | примітка |
116
- | --- | --- | --- | --- |
117
- | `dev.env`, `.dev.env` | `dev-…` | `abie-dev.internal` | GKE-кластер dev |
118
- | `ua.env`, `.ua.env` | `ua-…` | `abie-ua.internal` | GKE-кластер ua |
17
+ Без цього запису `@nitra/cursor` пропускає всі abie-перевірки (JS-концерни та rego-полісі).
119
18
 
120
- Канонічна форма URL — `http://<service>.<namespace>.svc.<cluster-dns-suffix>:<port>`. Суфікс — `<cluster>.internal`.
19
+ [k8s-hc-yaml](./js/hc_pairing.mdc)
121
20
 
122
- Приклади для одного env-файлу з двома сервісами (Hasura + KVCMS):
21
+ [k8s-http-route-base](./js/http_route_base.mdc)
123
22
 
124
- ```env title="hasura/.dev.env"
125
- HASURA_GRAPHQL_ENDPOINT=http://apruv-h-hl.dev-apruv.svc.abie-dev.internal:8080
126
- KVCMS_URL=http://kvcms-hl.dev-apruv.svc.abie-dev.internal:8080
127
- ```
128
-
129
- ```env title="hasura/.ua.env"
130
- HASURA_GRAPHQL_ENDPOINT=http://apruv-h-hl.ua-apruv.svc.abie-ua.internal:8080
131
- KVCMS_URL=http://kvcms-hl.ua-apruv.svc.abie-ua.internal:8080
132
- ```
23
+ [k8s-http-route-ua](./js/ua_http_route.mdc)
133
24
 
134
- `<namespace>` (наприклад `dev-apruv` / `ua-apruv`) — `metadata.name` цільового namespace після kustomize-overlay для відповідного середовища; `<service>` — `metadata.name` headless Service (`-hl`) того сервісу, до якого йде URL.
25
+ [k8s-nodeselector](./js/ua_node_selector.mdc)
135
26
 
136
- **Перевірка `js/env_dns.mjs`** сканує всі `*.env` файли, basename яких збігається з `dev.env` / `ua.env` (з провідною крапкою чи без), знаходить **усі** internal URL (`http://<svc>.<ns>.svc.<dns>` — як для Hasura-ендпоінта, так і для KVCMS чи будь-якого іншого) і вимагає, щоб для кожного:
137
-
138
- - DNS-суфікс відповідав env: `abie-dev.internal` / `abie-ua.internal`;
139
- - namespace починався з `dev-` / `ua-` відповідно.
140
-
141
- Загальне правило про **внутрішній** URL (не публічний домен) для `HASURA_GRAPHQL_ENDPOINT` лишається у **`hasura.mdc`** (для nitra і abie) — `rules/hasura/fix.mjs` приймає кластерний DNS-формат `<cluster>.internal`.
27
+ [env-dns](./js/env_dns.mdc)
142
28
 
143
29
  ## `@nitra/abie-shared` у `devDependencies`
144
30
 
@@ -148,9 +34,7 @@ KVCMS_URL=http://kvcms-hl.ua-apruv.svc.abie-ua.internal:8080
148
34
  bun add -d @nitra/abie-shared
149
35
  ```
150
36
 
151
- ## Firebase Hosting
152
-
153
- У **кожному** підкаталозі, що лежить **безпосередньо** в корені репозиторію, не тримати конфіг і кеш **Firebase Hosting**: у таких каталогах не повинно бути **`.firebaserc`**, **`firebase.json`** та каталогу **`.firebase/`** (у **самому** корені репозиторію ці імена перевіркою abie **не** розглядаються; `node_modules` / `.git` зі скану вилучаються).
37
+ [firebase](./js/firebase_hosting.mdc)
154
38
 
155
39
  ## Git branches
156
40
 
@@ -6,19 +6,19 @@ resource: npm/rules/doc-files/js/
6
6
 
7
7
  # npm/rules/doc-files/js
8
8
 
9
- | Файл | Тип |
10
- |---|---|
11
- | [docgen-crc.mjs](docgen-crc.md) | JS Module |
9
+ | Файл | Тип |
10
+ | ------------------------------------------------------- | --------- |
11
+ | [docgen-crc.mjs](docgen-crc.md) | JS Module |
12
12
  | [docgen-extract-anchors.mjs](docgen-extract-anchors.md) | JS Module |
13
- | [docgen-extract.mjs](docgen-extract.md) | JS Module |
14
- | [docgen-files-batch.mjs](docgen-files-batch.md) | JS Module |
15
- | [docgen-gen.mjs](docgen-gen.md) | JS Module |
16
- | [docgen-ignore.mjs](docgen-ignore.md) | JS Module |
17
- | [docgen-judge-measure.mjs](docgen-judge-measure.md) | JS Module |
18
- | [docgen-judge.mjs](docgen-judge.md) | JS Module |
19
- | [docgen-prompts.mjs](docgen-prompts.md) | JS Module |
20
- | [docgen-scan.mjs](docgen-scan.md) | JS Module |
21
- | [run-lint.mjs](run-lint.md) | JS Module |
22
- | [units-js.mjs](units-js.md) | JS Module |
23
- | [units-rs.mjs](units-rs.md) | JS Module |
24
- | [units.mjs](units.md) | JS Module |
13
+ | [docgen-extract.mjs](docgen-extract.md) | JS Module |
14
+ | [docgen-files-batch.mjs](docgen-files-batch.md) | JS Module |
15
+ | [docgen-gen.mjs](docgen-gen.md) | JS Module |
16
+ | [docgen-ignore.mjs](docgen-ignore.md) | JS Module |
17
+ | [docgen-judge-measure.mjs](docgen-judge-measure.md) | JS Module |
18
+ | [docgen-judge.mjs](docgen-judge.md) | JS Module |
19
+ | [docgen-prompts.mjs](docgen-prompts.md) | JS Module |
20
+ | [docgen-scan.mjs](docgen-scan.md) | JS Module |
21
+ | [run-lint.mjs](run-lint.md) | JS Module |
22
+ | [units-js.mjs](units-js.md) | JS Module |
23
+ | [units-rs.mjs](units-rs.md) | JS Module |
24
+ | [units.mjs](units.md) | JS Module |
@@ -10,19 +10,19 @@ docgen:
10
10
 
11
11
  ## Огляд
12
12
 
13
- Дозволяє запускати повний аналіз проєкту за допомогою `run`, виконувати лінтинг за допомогою `lint` або фільтрувати файли з розширенням JavaScript за допомогою `filterJsFiles`.
13
+ Модуль забезпечує виконання функцій `run`, `filterJsFiles` та `lint` для аналізу кодової бази. Він виконує стандартну перевірку проєкту, відбираючи файли з розширеннями JavaScript за допомогою `filterJsFiles` та запускаючи перевірку JS-коду за допомогою `lint`.
14
14
 
15
15
  ## Поведінка
16
16
 
17
17
  run виконує стандартну перевірку проєкту.
18
- filterJsFiles відбирає з наданого списку лише файли, що мають розширення, характерне для JavaScript.
19
- lint запускає перевірку проєкту: або повний аналіз усіх файлів, або класифікований аналіз лише змінених файлів.
18
+ filterJsFiles відбирає з наданого списку лише файли з розширеннями, характерними для JavaScript.
19
+ lint запускає перевірку JS-коду, виконуючи або повний аналіз проєкту, або класифіковану перевірку змінених файлів.
20
20
 
21
21
  ## Публічний API
22
22
 
23
- run — виконує повний цикл перевірки: аналіз конфігурації, перевірку логіки та посилання на метадані.
24
- filterJsFiles — відбирає лише файли з розширенням JavaScript.
25
- lint — запускає інструменти для форматування та стилізації коду (oxlint, eslint, jscpd, knip).
23
+ run — основна точка входу для виконання правил, що включає перевірку логіки застосування, логіки політик та посилань на метадані.
24
+ filterJsFiles — відбирає лише файли, схожі на JavaScript, з наданого списку.
25
+ lint — запускає інструменти oxlint та eslint (для окремих файлів або всього проекту) та jscpd+knip (тільки для всього проекту), з можливістю автоматичного виправлення або лише виявлення проблем.
26
26
 
27
27
  ## Гарантії поведінки
28
28
 
@@ -5,23 +5,24 @@ resource: npm/rules/js/js/check.mjs
5
5
  docgen:
6
6
  crc: 7ad4aa59
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
- score: 90
8
+ score: 100
9
9
  ---
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль перевіряє відповідність структури та конфігураційних файлів проєкту встановленим стандартам. Він валідує файли, такі як `package.json`, `.oxlintrc.json`, `.eslintrc.json` та файли робочих процесів GitHub, відповідно до вимог (js.mdc). Перевірка свідомо ігнорує шляхи `.github` та `.git`. Модуль забезпечує перехоплення помилок (fail-safe) під час виконання перевірок.
13
+ Модуль виконує валідацію конфігураційних файлів, включаючи `package.json`, `.oxlintrc.json`, `knip.json`, `knip-canonical.json` та `.eslintrc.json`. Він перевіряє відповідність структури та конфігурацій встановленим стандартам. (js.mdc) (text.mdc)
14
14
 
15
15
  ## Поведінка
16
16
 
17
- 1. Викликати `check` для запуску перевірок конфігурації проєкту.
18
- 2. Перевірити наявність конфігурацій ESLint (flat config) та валідувати їх вміст відповідно до вимог (js.mdc).
19
- 3. Перевірити `package.json` у корені та у всіх пакетах workspace на відповідність вимогам: наявність `"type": "module"` та мінімальні версії `engines.node` (>=24) та `engines.bun` (>=1.3) (js.mdc).
20
- 4. Перевірити конфігураційний файл `.oxlintrc.json` на відповідність канонічному шаблону (js.mdc).
21
- 5. Перевірити файли робочих процесів (`.github/workflows/lint-js.yml` та `.github/workflows/lint.yml`) на відповідність політикам лінтингу (js.mdc).
22
- 6. Перевірити наявність конфігурацій Knip (`knip.json`). Якщо відсутній, створити його, скопіювавши канонічний шаблон (js.mdc).
23
- 7. Перевірити наявність застарілих конфігурацій ESLint (наприклад, `.eslintrc.*`) та повідомити про їхнє використання.
24
- 8. Ігнорувати перевірки у каталогах `.github` та `.git`.
17
+ 1. Викликається функція check.
18
+ 2. Ініціалізується механізм збору результатів перевірок.
19
+ 3. Перевіряється конфігураційний файл ESLint.
20
+ 4. Перевіряється структура пакетів у workspace'ах, включаючи наявність `"type": "module"` та вимоги до версій Node та Bun у `package.json` кожного пакета.
21
+ 5. Перевіряється конфігураційний файл `.oxlintrc.json` на відповідність канонічному шаблону.
22
+ 6. Перевіряється структура файлів у робочих процесах GitHub, зокрема наявність `lint-js.yml` та відсутність дублювання кроків лінтингу в `lint.yml`.
23
+ 7. Перевіряється наявність `knip.json` у корені проєкту. Якщо відсутній, він створюється з канонічного шаблону.
24
+ 8. Після виконання всіх перевірок, сканується проєкт на наявність застарілих конфігураційних файлів ESLint.
25
+ 9. Повертається код виходу, що відображає загальний статус виконання перевірок.
25
26
 
26
27
  ## Публічний API
27
28
 
@@ -10,19 +10,19 @@ docgen:
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль визначає шляхи до канонічних JSON-файлів для інструментів oxlint та knip через функції OXLINT_CANONICAL_JSON_PATH та KNIP_CANONICAL_JSON_PATH. Він також надає функцію verifyOxlintRcAgainstCanonical для валідації конфігурацій, перевіряючи, чи відповідає `.oxlintrc.json` правилам, визначеним у oxlint-canonical.json.
13
+ Визначає шляхи до канонічних JSON-файлів для інструментів oxlint та knip через OXLINT_CANONICAL_JSON_PATH та KNIP_CANONICAL_JSON_PATH. Також перевіряє відповідність конфігураційного файлу .oxlintrc.json значенням, встановленим у oxlint-canonical.json, за допомогою verifyOxlintRcAgainstCanonical.
14
14
 
15
15
  ## Поведінка
16
16
 
17
- OXLINT_CANONICAL_JSON_PATH — Вказує на шлях до канонічного JSON-файлу для oxlint у цьому пакеті.
18
- KNIP_CANONICAL_JSON_PATH — Вказує на шлях до канонічного JSON-файлу для knip у цьому пакеті.
19
- verifyOxlintRcAgainstCanonical — Перевіряє конфігурацію `.oxlintrc.json` на відповідність канонічному файлу oxlint-canonical.json, виявляючи відхилення у правилах та інших полях.
17
+ OXLINT_CANONICAL_JSON_PATH — Вказує шлях до канонічного JSON-файлу для oxlint у цьому пакеті.
18
+ KNIP_CANONICAL_JSON_PATH — Вказує шлях до канонічного JSON-файлу для knip у цьому пакеті.
19
+ verifyOxlintRcAgainstCanonical — Перевіряє конфігураційний файл `.oxlintrc.json` на відповідність канонічним значенням, визначеним у `oxlint-canonical.json`.
20
20
 
21
21
  ## Публічний API
22
22
 
23
- OXLINT_CANONICAL_JSON_PATH — вказує на файл з еталонними налаштуваннями oxlint у пакеті.
24
- KNIP_CANONICAL_JSON_PATH — вказує на файл з еталонними налаштуваннями knip, який копіюється у корінь проєкту, якщо його там немає.
25
- verifyOxlintRcAgainstCanonical — порівнює конфігураційний файл `.oxlintrc.json` з еталоном, перевіряючи, чи всі правила з еталону присутні, а інші поля збігаються з `oxlint-canonical.json`.
23
+ OXLINT_CANONICAL_JSON_PATH — Вказує на файл з еталонними налаштуваннями oxlint для валідації.
24
+ KNIP_CANONICAL_JSON_PATH — Шлях до еталонних налаштувань knip, які копіюються у корінь проєкту, якщо їх немає.
25
+ verifyOxlintRcAgainstCanonical — Порівнює конфігураційний файл `.oxlintrc.json` з еталоном, перевіряючи, чи всі правила з еталону присутні, а інші поля збігаються з каноном.
26
26
 
27
27
  ## Гарантії поведінки
28
28
 
@@ -10,21 +10,22 @@ docgen:
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль сканує файли у монорепозиторії. Він зчитує вміст JavaScript/TypeScript файлів та витягує всі рядкові імпорти. На основі конфігурації `.n-cursor.json` він перевіряє, чи не містять імпорти заборонених відносних шляхів, реєструючи відповідний статус у логіці (js.mdc). Публічна функція `check` виконує цю перевірку, свідомо пропускаючи шляхи `.git` та `node_modules`.
13
+ Модуль сканує монорепозиторій для пошуку каталогів `utils` та аналізу їхнього вмісту. Аналіз файлів JS/TS у цих каталогах здійснюється на відповідність шаблону забороненого відносного імпорту, що базується на конфігурації, визначеній у `.n-cursor.json`. При виявленні порушень, система генерує повідомлення, позначене як (js.mdc).
14
14
 
15
15
  ## Поведінка
16
16
 
17
- 1. Визначає корінь проекту.
18
- 2. Зчитує список шляхів, які слід ігнорувати, на основі конфігурації .n-cursor.json.
19
- 3. Визначає кореневі каталоги пакетів у монорепозиторії.
20
- 4. Для кожного кореневого каталогу пакета рекурсивно шукає каталоги з назвою `utils`, ігноруючи типові артефакти (наприклад, node_modules, .git, dist).
21
- 5. Якщо знайдено каталоги `utils`, для кожного з них рекурсивно збирає всі файли з розширеннями `.js`, `.jsx`, `.ts`, `.tsx`, які не є тестовими.
22
- 6. Для кожного зібраного файлу зчитує його вміст.
23
- 7. Витягує з вмісту файлу всі рядкові імпорти (статичні, динамічні та виклики `require`).
24
- 8. Для кожного витягнутого імпорту перевіряє, чи відповідає він шаблону забороненого відносного шляху, що вказує на імпорт з іншого каталогу, який не є загальним.
25
- 9. Якщо заборонений імпорт знайдено, реєструє помилку, посилаючись на файл та заборонений імпорт (js.mdc).
26
- 10. Якщо жодних порушень не знайдено, реєструє успіх (js.mdc).
27
- 11. Повертає код виходу, що відображає статус перевірки.
17
+ 1. Визначає кореневий каталог для аналізу.
18
+ 2. Зчитує шляхи, які слід ігнорувати, на основі конфігурації .n-cursor.json.
19
+ 3. Знаходить усі каталоги з назвою `utils` у межах кореневих каталогів пакетів монорепозиторію, ігноруючи типові артефакти (наприклад, node_modules, .git, dist).
20
+ 4. Якщо знайдено жодних каталогів `utils`, перевірка вважається успішною і завершується.
21
+ 5. Для кожного знайденого каталогу `utils` збирає всі джерела файлів, які відповідають шаблону JS/TS, виключаючи тестові файли та файли у каталогах `tests/` чи `__fixtures__/`.
22
+ 6. Для кожного зібраного файлу:
23
+ а. Зчитує вміст файлу.
24
+ б. Витягує всі рядкові імпорти (статичні, динамічні, `require`) з коду.
25
+ в. Перевіряє кожен витягнутий імпорт на відповідність шаблону забороненого відносного імпорту.
26
+ г. Якщо імпорт є забороненим, фіксує порушення, вказуючи повний шлях до файлу та сам імпорт.
27
+ 7. Після перевірки всіх файлів, якщо порушень не знайдено, перевірка вважається успішною (js.mdc).
28
+ 8. Повертає код завершення, що відображає успіх або виявлені порушення (js.mdc).
28
29
 
29
30
  ## Гарантії поведінки
30
31