@nitra/cursor 3.26.0 → 3.28.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.
- package/CHANGELOG.md +18 -0
- package/bin/n-cursor.js +29 -9
- package/package.json +1 -1
- package/rules/abie/js/applies.mjs +1 -5
- package/rules/abie/js/env_dns.mjs +1 -9
- package/rules/abie/js/firebase_hosting.mjs +1 -5
- package/rules/abie/js/hc_pairing.mjs +1 -8
- package/rules/abie/js/ua_http_route.mjs +1 -10
- package/rules/abie/js/ua_node_selector.mjs +1 -8
- package/rules/adr/js/hooks.mjs +1 -20
- package/rules/bun/js/layout.mjs +1 -19
- package/rules/capacitor/js/platforms.mjs +1 -23
- package/rules/changelog/js/consistency.mjs +1 -29
- package/rules/ci4/js/marksman_config.mjs +1 -19
- package/rules/docker/js/lint.mjs +1 -34
- package/rules/ga/docs/fix.md +16 -149
- package/rules/ga/js/docs/lint.md +12 -93
- package/rules/ga/js/docs/workflows.md +28 -213
- package/rules/ga/js/workflows.mjs +1 -16
- package/rules/ga/lint/docs/lint.md +24 -206
- package/rules/graphql/js/tooling.mjs +1 -9
- package/rules/hasura/js/internal_urls.mjs +1 -24
- package/rules/image-avif/js/avif_generation.mjs +1 -27
- package/rules/image-compress/js/package_setup.mjs +1 -18
- package/rules/js-bun-db/js/safety.mjs +1 -31
- package/rules/js-bun-redis/js/imports.mjs +1 -12
- package/rules/js-lint/js/docs/lint-findings.md +30 -0
- package/rules/js-lint/js/lint-findings.mjs +1 -7
- package/rules/js-lint/js/lint.mjs +1 -10
- package/rules/js-lint/js/tooling.mjs +1 -13
- package/rules/js-lint/js/utils_imports.mjs +1 -18
- package/rules/js-lint-ci/js/lint.mjs +1 -6
- package/rules/js-mssql/js/deps.mjs +1 -10
- package/rules/js-run/js/runtime.mjs +1 -37
- package/rules/js-run/lib/docs/temporal-scan.md +25 -0
- package/rules/k8s/js/manifests.mjs +1 -137
- package/rules/nginx-default-tpl/js/template.mjs +1 -18
- package/rules/npm-module/js/docs/header_doc_pointer.md +25 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +82 -0
- package/rules/npm-module/js/package_structure.mjs +1 -28
- package/rules/npm-module/js/rule_meta.mjs +1 -10
- package/rules/npm-module/js/skill_meta.mjs +1 -13
- package/rules/php/js/tooling.mjs +1 -11
- package/rules/python/js/applies.mjs +1 -8
- package/rules/python/js/tooling.mjs +1 -21
- package/rules/rego/js/applies.mjs +1 -11
- package/rules/rust/js/applies.mjs +1 -7
- package/rules/security/js/sample_secret.mjs +1 -28
- package/rules/security/js/trufflehog.mjs +1 -8
- package/rules/style-lint/js/lint.mjs +1 -5
- package/rules/style-lint/js/tooling.mjs +1 -19
- package/rules/tauri/js/cargo_mutants_config.mjs +1 -20
- package/rules/tauri/js/tooling.mjs +1 -21
- package/rules/test/js/cargo_mutants_config.mjs +1 -12
- package/rules/test/js/location.mjs +1 -9
- package/rules/test/js/no-process-chdir.mjs +1 -21
- package/rules/test/js/no-relative-fs-path.mjs +1 -23
- package/rules/test/js/stryker_config.mjs +4 -25
- package/rules/test/js/vitest-config-pool-forks.mjs +1 -17
- package/rules/text/js/forbidden-prettier.mjs +1 -10
- package/rules/text/js/formatting.mjs +1 -31
- package/rules/vue/js/packages.mjs +1 -24
- package/scripts/docs/coverage-fix-extract.md +32 -0
- package/scripts/docs/lint-cli.md +25 -0
- package/scripts/docs/post-tool-use-fix.md +27 -0
- package/scripts/docs/rename-yaml-extensions.md +36 -0
- package/scripts/docs/skills-cli.md +35 -0
- package/scripts/docs/sync-claude-config.md +52 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +26 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +29 -0
- package/scripts/docs/worktree-cli.md +46 -0
- package/scripts/lib/docs/assert-project-root.md +28 -0
- package/scripts/lib/docs/diff-added-lines.md +34 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +28 -0
- package/scripts/lib/docs/resolve-target-files.md +34 -0
- package/scripts/lib/docs/root-notice.md +28 -0
- package/scripts/lib/docs/rule-meta-helpers.md +34 -0
- package/scripts/lib/docs/rule-meta.md +34 -0
- package/scripts/lib/docs/rule-predicates.md +30 -0
- package/scripts/lib/docs/run-conftest-batch.md +26 -0
- package/scripts/lib/docs/run-lint-step.md +25 -0
- package/scripts/lib/docs/run-rule-cli.md +27 -0
- package/scripts/lib/docs/run-rule.md +32 -0
- package/scripts/lib/docs/run-standard-lint.md +22 -0
- package/scripts/lib/docs/run-standard-rule.md +24 -0
- package/scripts/lib/docs/skill-meta.md +31 -0
- package/scripts/lib/docs/sync-gitignore-worktree.md +31 -0
- package/scripts/lib/docs/template.md +40 -0
- package/scripts/lib/docs/timing-summary.md +24 -0
- package/scripts/lib/docs/workspaces.md +30 -0
- package/scripts/lib/docs/worktree-notice.md +27 -0
- package/scripts/lib/docs/worktree.md +38 -0
- package/scripts/utils/docs/ast-scan-utils.md +50 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +28 -0
- package/scripts/utils/docs/find-package-json-paths.md +26 -0
- package/scripts/utils/docs/lock-cache-dir.md +25 -0
- package/scripts/utils/docs/pass.md +25 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +23 -0
- package/scripts/utils/docs/resolve-cmd.md +29 -0
- package/scripts/utils/docs/resolve-js-root.md +25 -0
- package/scripts/utils/docs/test-helpers.md +36 -0
- package/scripts/utils/docs/walk-cache.md +27 -0
- package/scripts/utils/docs/walkDir.md +32 -0
- package/scripts/utils/docs/with-lock.md +25 -0
- package/scripts/utils/docs/worktree-fingerprint.md +27 -0
- package/skills/docgen/js/docgen-batch.mjs +95 -0
- package/skills/docgen/js/docgen-extract.mjs +33 -18
- package/skills/docgen/js/docgen-gen.mjs +258 -30
- package/skills/docgen/js/docgen-ignore.mjs +4 -7
- package/skills/docgen/js/docgen-prompts.mjs +40 -23
- package/skills/docgen/js/docgen-scan.mjs +1 -8
- package/skills/docgen/js/docs/docgen-extract.md +28 -0
- package/skills/docgen/js/docs/docgen-gen.md +41 -0
- package/skills/docgen/js/docs/docgen-ignore.md +24 -0
- package/skills/docgen/js/docs/docgen-prompts.md +24 -0
- package/skills/docgen/js/docs/docgen-scan.md +48 -0
- package/skills/fix/SKILL.md +5 -31
- package/skills/fix/js/docs/llm-worker.md +27 -0
- package/skills/fix/js/docs/orchestrator.md +32 -0
- package/skills/fix/js/docs/t0.md +29 -0
- package/skills/fix/js/llm-worker.mjs +216 -0
- package/skills/fix/js/orchestrator.mjs +119 -0
- package/skills/fix/js/t0.mjs +213 -0
- package/skills/fix/meta.json +1 -1
- package/skills/start-check/js/check.mjs +1 -16
- package/skills/start-check/js/docs/check.md +34 -0
- package/skills/taze/js/diff.mjs +1 -15
- package/skills/taze/js/docs/diff.md +33 -0
|
@@ -1,140 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє Kubernetes YAML у шляхах з сегментом `k8s` (див. k8s.mdc).
|
|
3
|
-
*
|
|
4
|
-
* Перший рядок `# yaml-language-server: $schema=…` (URL за `https://`), без дублікатів, розширення `.yaml`
|
|
5
|
-
* (окрім `kustomization.yaml`); URL схеми за першим документом — kustomization / yannh / datree
|
|
6
|
-
* (**виняток:** `apiVersion: alb.yc.io/v1alpha1`, `kind: HttpBackendGroup` — рядка `# yaml-language-server:` у файлі бути не має).
|
|
7
|
-
* (datree за замовчуванням: GitHub Pages `https://datreeio.github.io/CRDs-catalog/…`).
|
|
8
|
-
*
|
|
9
|
-
* Modeline **опційний**: якщо публічної схеми немає (yannh/datree/schemastore не покривають це поєднання
|
|
10
|
-
* apiVersion/kind), залиш файл **без** рядка `# yaml-language-server: $schema=…` — `check-k8s` пропустить
|
|
11
|
-
* перевірку URL. **Заборонено** ставити `$schema=file:…` як заглушку (це фальшива валідація). Якщо modeline
|
|
12
|
-
* присутній, він має бути **першим рядком** і містити `https://` URL, що відповідає очікуваному за apiVersion/kind.
|
|
13
|
-
*
|
|
14
|
-
* Додатково: у кожному YAML-документі з **`kind: Deployment`** у кожного контейнера
|
|
15
|
-
* **`spec.template.spec.containers[]`** має бути **`resources.requests.cpu`** і **`resources.requests.memory`**
|
|
16
|
-
* (непорожні скаляри). У шарі **`…/k8s/…/base/…`** значення жорстко **`cpu: '0.02'`**, **`memory: '128Mi'`**
|
|
17
|
-
* (для **cpu** допускається число **`0.02`**). Поза base, якщо ще не підібрано власні
|
|
18
|
-
* ліміти — орієнтир **`DEFAULT_CONTAINER_CPU_REQUEST`** = **`"0.5"`**, **`DEFAULT_CONTAINER_MEMORY_REQUEST`**
|
|
19
|
-
* = **`"512Mi"`**. Поле **`imagePullPolicy`**
|
|
20
|
-
* не перевіряється — діють типові правила Kubernetes (`:latest` або коли тег не вказано → **Always**,
|
|
21
|
-
* інші теги → **IfNotPresent**). Якщо серед **`containers`** / **`initContainers`** є образ
|
|
22
|
-
* **`hasura/graphql-engine`**, дозволено лише канонічний тег зі списку `allowed_hasura_images`
|
|
23
|
-
* у rego-пакеті `k8s.manifest` (`policy/manifest/manifest.rego`) — пер-документна перевірка делегована rego.
|
|
24
|
-
*
|
|
25
|
-
* **Namespace і Kustomize:** YAML у **`…/k8s/base/`** (окрім імені **`kustomization.yaml`**)
|
|
26
|
-
* завжди має **непорожній** **`metadata.namespace`** у відповідних документах (узгоджено з dev у репозиторії),
|
|
27
|
-
* навіть якщо **`namespace:`** заданий у **`base/kustomization.yaml`**.
|
|
28
|
-
* Поза **`k8s/base`**: для файлів, досяжних з kustomization через **`resources`**, **`bases`**, **`components`**,
|
|
29
|
-
* **`crds`**, **`patches[].path`**, **`patchesStrategicMerge`**, **`metadata.namespace`** у маніфесті **не** додають;
|
|
30
|
-
* файли **поза** цим графом — **непорожній** **`metadata.namespace`** (крім **кластерних** kind; див. k8s.mdc).
|
|
31
|
-
*
|
|
32
|
-
* **`kind: Ingress`** заборонено (потрібен перехід на Gateway API).
|
|
33
|
-
* **`apiVersion: autoscaling/v1`** заборонено (мігруй **HorizontalPodAutoscaler** на **`autoscaling/v2`**).
|
|
34
|
-
* Рядок **`apiVersion: batch/v1beta1`** (CronJob, Job) **автоматично** переписується на **`apiVersion: batch/v1`**
|
|
35
|
-
* (окрім рядків-коментарів і рядків, де після значення йде наприклад `# …`).
|
|
36
|
-
*
|
|
37
|
-
* Файли під **`k8s`**, де всі YAML-документи — лише **`kind: BackendConfig`**, **видаляються** автоматично.
|
|
38
|
-
* Якщо **BackendConfig** змішано з іншими ресурсами в одному файлі — перевірка завершується помилкою (розділи маніфести).
|
|
39
|
-
*
|
|
40
|
-
* У **`kind: Service`** у **`metadata.annotations`** не повинно бути ключів **`cloud.google.com/neg`**
|
|
41
|
-
* та **`cloud.google.com/backend-config`** (див. k8s.mdc).
|
|
42
|
-
*
|
|
43
|
-
* Файли **`svc.yaml`** / **`svc-hl.yaml`** у **одному каталозі** (див. k8s.mdc): для кожного **`svc.yaml`**
|
|
44
|
-
* поруч обов’язковий **`svc-hl.yaml`** (headless-копія: той самий селектор/порти, **`metadata.name`** з суфіксом **`-hl`**,
|
|
45
|
-
* **`spec.clusterIP: None`**). У **`svc.yaml`** кожен **Service** має **`spec.type: ClusterIP`**. У **`svc-hl.yaml`**
|
|
46
|
-
* кожен **Service** — **`spec.clusterIP: None`** та ім’я на **`-hl`**. У маршрутах **Gateway API**
|
|
47
|
-
* (**`HTTPRoute`**, **`GRPCRoute`**, **`TCPRoute`**, **`TLSRoute`**, **`UDPRoute`**, група **`gateway.networking.k8s.io`**)
|
|
48
|
-
* посилання **`backendRefs` / `backendRef`** на **Service** мають вказувати лише сервіси з суфіксом **`-hl`** у **`name`**.
|
|
49
|
-
* Поле **`namespace`** у **`backendRef`**, що збігається з **`metadata.namespace`** самого маршруту, — надлишкове:
|
|
50
|
-
* прибери його, бо за замовчуванням Gateway API визначає backend у тому ж namespace, що й маршрут (див. k8s.mdc).
|
|
51
|
-
* **HealthCheckPolicy** (**`networking.gke.io/v1`**, GKE): **`spec.targetRef`** на **Service** — **`name`** з суфіксом **`-hl`** (див. k8s.mdc).
|
|
52
|
-
* Якщо **`kustomization.yaml`** посилається на **`svc.yaml`** (**`resources`**, **`bases`**, **`components`**, **`crds`**,
|
|
53
|
-
* **`patches[].path`**, **`patchesStrategicMerge`**), у **тому ж** файлі має бути посилання на відповідний **`svc-hl.yaml`**
|
|
54
|
-
* в **тому ж каталозі**, що й **`svc.yaml`** (логіка збігається з **`pathsFromKustomizationObject`**).
|
|
55
|
-
*
|
|
56
|
-
* Структура **Kustomize** (див. k8s.mdc): заборона шляхів **`…/k8s/dev/…`**; у **`k8s/base/kustomization.yaml`**
|
|
57
|
-
* завжди має бути непорожнє поле **`namespace:`** (перевірка, якщо файл існує). У **`apiVersion: kustomize.config.k8s.io/…`**, **`kind: Kustomization`**
|
|
58
|
-
* перелік **`resources:`** (лише непорожні рядки) має бути відсортовано за алфавітом (**en**, `localeCompare`).
|
|
59
|
-
*
|
|
60
|
-
* **Структурний сорт `patches[]` у kustomization.yaml:** масив **`patches`** має бути відсортовано за tuple
|
|
61
|
-
* **`[target.kind, target.name, target.namespace, path]`** (`localeCompare('en', base)`). Поля **`group`** / **`version`**
|
|
62
|
-
* у tuple не входять — для них діє правило «patches[].target: лише kind і name». Додатково: вміст
|
|
63
|
-
* **inline `patches[i].patch`** (literal block scalar — масив JSON6902-операцій) має бути відсортовано за **`path`**,
|
|
64
|
-
* але **лише** якщо всі операції — **`add`** / **`replace`** і всі **`path`** попарно дизʼюнктні (жоден не префікс іншого).
|
|
65
|
-
* Інакше порядок не чіпається — `move` / `copy` / `test` / `remove` чи спільні шляхи можуть бути семантично залежні (RFC 6902).
|
|
66
|
-
*
|
|
67
|
-
* **Inline JSON6902** у **`patches`** (і зовнішні файли з **`patches[].path`** під **`k8s`**, якщо вміст — масив JSON Patch): не допускається пара **`remove`** і **`add`**
|
|
68
|
-
* на один і той самий **`path`** у межах одного фрагмента — потрібен **`op: replace`** (k8s.mdc). **check-k8s** це перевіряє.
|
|
69
|
-
*
|
|
70
|
-
* **Мішень patch:** у **`patches[].target`** і **`patchesJson6902[].target`** (без **labelSelector** / **annotationSelector**)
|
|
71
|
-
* має існувати відповідний ресурс у зібраному з **`resources`**, **`bases`**, **`components`**, **`crds`** каталозі (рекурсивно для підкаталогів з **`kustomization.yaml`**).
|
|
72
|
-
* Для **`patchesStrategicMerge`** і для **`patches[].path`** без **`target`** і без inline **`patch`** (зовнішній strategic-merge)
|
|
73
|
-
* кожен YAML-документ з кореневим **`kind`** і **`metadata.name`** також звіряється з цим каталогом.
|
|
74
|
-
*
|
|
75
|
-
* **Зайві `group` / `version` у `patches[].target` / `patchesJson6902[].target`:** якщо в інвентарі **`resources`** /
|
|
76
|
-
* **`bases`** / **`components`** / **`crds`** (рекурсивно) за **`kind`** + **`name`** немає колізії між різними
|
|
77
|
-
* API-групами/версіями, поля **`group`** і **`version`** у **`target`** треба прибрати — Kustomize визначає ціль
|
|
78
|
-
* за **GVK + name**, а зайві поля ламаються мовчки під час змін API (k8s.mdc «patches[].target: лише kind і name»).
|
|
79
|
-
*
|
|
80
|
-
* Явні винятки до загальної логіки yannh/datree — таблиця **`EXPLICIT_K8S_SCHEMAS`** (`Map`): ключ
|
|
81
|
-
* **`apiVersion`, `kind`, `type`** (для CRD без поля `type` у маніфесті — зірочка **`*`** як третій
|
|
82
|
-
* компонент). Спочатку шукається збіг за фактичним `type`, потім за **`*`**.
|
|
83
|
-
* Dockerfile — правило docker.mdc, скрипт rules/docker/fix.mjs.
|
|
84
|
-
*
|
|
85
|
-
* **Структура `HTTPRoute` для Hasura-Deployment:** звіряється канон 4 правил у **`spec.rules`** (редиректи **`<prefix>/ql`** і **`<prefix>/ql/`** на **`<prefix>/ql/console`** 302, **`PathPrefix <prefix>/ql`** + **URLRewrite** на **`/`**, окреме WebSocket-правило з **`RequestHeaderModifier`** remove **`Authorization`**). **Префікс параметризовано** (рядок перед **`/ql`** у першому Hasura-правилі). **Прив'язка** — за **`metadata.name`** у тому ж каталозі, що й **Deployment** з образом **`hasura/graphql-engine`** (див. k8s.mdc). **Додаткові правила** поверх канону дозволені.
|
|
86
|
-
*
|
|
87
|
-
* **ConfigMap для Hasura-Deployment:** якщо в `k8s/base/` є `configmap.yaml` і поруч Deployment з образом
|
|
88
|
-
* **`hasura/graphql-engine`**, то в `data` ConfigMap обов'язково має бути ключ
|
|
89
|
-
* **`HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS`** зі значенням **`"true"`** (приймається булеве `true`
|
|
90
|
-
* або рядок `"true"`, без регістрової залежності).
|
|
91
|
-
*
|
|
92
|
-
* **HPA / PDB / topologySpreadConstraints:** для кожного **`Deployment`** у шарі **`…/k8s/…/base/`**
|
|
93
|
-
* (будь-який `.yaml` у цьому каталозі) обов'язкові канонічні **topologySpreadConstraints**, а HPA і PDB
|
|
94
|
-
* живуть у sibling каталозі **`…/k8s/…/components/`** (Kustomize Component, фіксована назва каталогу `components`). У `base/`
|
|
95
|
-
* заборонено тримати локальні `hpa.yaml` і `pdb.yaml` (file-existence error) і також у дереві
|
|
96
|
-
* base-kustomize не повинно бути HPA/PDB через `resources` / `components` / `bases`.
|
|
97
|
-
* **NetworkPolicy:** для кожного **`Deployment`**, **`StatefulSet`**, **`DaemonSet`**, **`Job`**, **`CronJob`** під `k8s`
|
|
98
|
-
* обов'язковий канонічний NetworkPolicy у `networkpolicy.yaml` поруч з workload-маніфестом — у base
|
|
99
|
-
* (`base/networkpolicy.yaml`, підключений через `base/kustomization.yaml` `resources:` — обмеження діють і на dev)
|
|
100
|
-
* і у не-base overlay (опційно — overlay-specific override).
|
|
101
|
-
* Egress: kube-dns; **TCP 80/443** на `0.0.0.0/0`; інші порти — `namespaceSelector: {}` (in-cluster / `*.svc`). Заборонено `egress: [{}]`.
|
|
102
|
-
* Відсутні документи **`check k8s`** створює автоматично (multi-doc у одному файлі, якщо workload-ів кілька).
|
|
103
|
-
* Структура `components/`: `kustomization.yaml` з `apiVersion: kustomize.config.k8s.io/v1alpha1`, `kind: Component`,
|
|
104
|
-
* `resources` що містять `hpa.yaml` і `pdb.yaml`, `hpa.yaml` (валідний `autoscaling/v2`
|
|
105
|
-
* HorizontalPodAutoscaler з `scaleTargetRef.name` = ім'я Deployment, dev-like `min=max=1`), `pdb.yaml` (валідний
|
|
106
|
-
* `policy/v1` PodDisruptionBudget з `selector.matchLabels.app` = мітка `app` Deployment, dev-like `minAvailable=0`).
|
|
107
|
-
* Overlays (`ua/`, прод-overlays) підключають `components: [- ../components]` і додають JSON6902-патчі для
|
|
108
|
-
* прод-значень: `/spec/minReplicas`, `/spec/maxReplicas` (HPA), `/spec/minAvailable` (PDB). HPA поруч із Deployment
|
|
109
|
-
* у не-base оверлеях — як раніше (див. k8s.mdc).
|
|
110
|
-
* Env-залежні межі за сегментом після `/k8s/`: **dev-like** (`base`, `dev`, `*-qa`) — для HPA, що лишився після
|
|
111
|
-
* збірки, `minReplicas === 1`, `maxReplicas === 1`, PDB `minAvailable === 0`; **прод** — `minReplicas >= 2`,
|
|
112
|
-
* `maxReplicas >= 2`, `minAvailable >= 1`.
|
|
113
|
-
*
|
|
114
|
-
* **Прод-оверрайди в kustomization.yaml:** для прод overlays (не dev-like) у `patches[]` потрібні перевизначення
|
|
115
|
-
* **`/spec/minReplicas`** і **`/spec/maxReplicas`** для **HorizontalPodAutoscaler** і **`/spec/minAvailable`** для
|
|
116
|
-
* **PDB** — якщо overlay-tree (через `resources` / `components`) містить HPA / PDB (тобто overlay підключив
|
|
117
|
-
* `…/k8s/…/components/`). Формат patch — JSON6902 або Strategic Merge; наявність шляхів —
|
|
118
|
-
* `kustomizationPatchPathsByTargetKind`.
|
|
119
|
-
*
|
|
120
|
-
* **Існування шляхів у `kustomization.yaml`:** кожне локальне посилання (без `://`) з `resources` / `bases` /
|
|
121
|
-
* `components` / `crds`, `patchesStrategicMerge`, `patches[].path`, `patchesJson6902[].path`, `configurations[]`,
|
|
122
|
-
* `replacements[].path` має вказувати на наявний у репозиторії файл (`.yaml` / `.yml`) або каталог; інакше
|
|
123
|
-
* помилка `check k8s` (k8s.mdc).
|
|
124
|
-
*
|
|
125
|
-
* **Images у Kustomize — `images:`, не patch:** для кожного `kustomization.yaml` автоматично:
|
|
126
|
-
* (а) конвертує JSON6902 `op: replace` на `/spec/template/spec/containers/<N>/image` (target `kind: Deployment`) у
|
|
127
|
-
* запис **`images:`** — `name` береться з оригінального `image:` у base (без тегу), `newName` — з patch.value (без тегу),
|
|
128
|
-
* `newTag` — лише якщо тег у patch.value відрізняється від тега в base; якщо `patches[]` після цього порожній — ключ
|
|
129
|
-
* прибирається; (б) чистить існуючий блок **`images:`** — зрізає `:tag` з `name` (digest `@…` не чіпає) і видаляє
|
|
130
|
-
* `newTag`, який збігається з відрізаним тегом.
|
|
131
|
-
*
|
|
132
|
-
* **HPA / PDB заборонені у base-дереві Kustomize:** у дереві з `…/k8s/…/base/kustomization.yaml` не дозволяти
|
|
133
|
-
* `HorizontalPodAutoscaler` / `PodDisruptionBudget` у `resources` / `bases` / `components` / `crds` (рекурсивно)
|
|
134
|
-
* взагалі. Канон — HPA/PDB у sibling `…/k8s/…/components/` (Kustomize Component) і підключаються лише з overlay.
|
|
135
|
-
* У `kustomization.yaml` overlay, який підключає каталог `…/k8s/…/base`, не додавай окремі YAML-файли з HPA / PDB,
|
|
136
|
-
* поки в наслідуваному `base` у дереві не з'явиться такий Deployment (k8s.mdc).
|
|
137
|
-
*/
|
|
1
|
+
/** @see ./docs/manifests.md */
|
|
138
2
|
import { existsSync, readFileSync } from 'node:fs'
|
|
139
3
|
import { readFile, readdir, stat, unlink, writeFile } from 'node:fs/promises'
|
|
140
4
|
import { basename, dirname, join, relative, resolve } from 'node:path'
|
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє nginx-шаблон і супутні файли за правилом nginx-default-tpl.mdc.
|
|
3
|
-
*
|
|
4
|
-
* Якщо в дереві є **default.conf.template**: канонічні директиви (порт 8080, /healthz, gzip_static,
|
|
5
|
-
* без proxy), поруч **\*.ini** (ключі з ini мають зустрічатися в шаблоні як **$KEY**), у будь-якому
|
|
6
|
-
* Dockerfile — **find** + **gzip** для каталогу `/usr/share/nginx/html` та **envsubst** з
|
|
7
|
-
* **default.conf.template**. Приклад **HTTPRoute** з правила — для рев’ю; автоматична перевірка
|
|
8
|
-
* вимкнена (різні схеми маршрутизації). Функція **`httpRouteMatchesNginxDefaultTpl`** лишається для
|
|
9
|
-
* тестів і майбутнього вузького застосування. VSCode: **extensions.json** та **settings.json** з
|
|
10
|
-
* форматером nginx і **formatOnSave**.
|
|
11
|
-
*
|
|
12
|
-
* У дереві від **cwd** усі **default.tpl.conf** стають **default.conf.template**: перейменування, або
|
|
13
|
-
* якщо **default.conf.template** уже є — він перезаписується вмістом **default.tpl.conf**, після чого
|
|
14
|
-
* **default.tpl.conf** видаляється. Якщо після міграції шаблону немає — перевірка пропускається (0).
|
|
15
|
-
*
|
|
16
|
-
* Невалідна директива **`error_log off;`** (nginx трактує "off" як ім'я файлу `/etc/nginx/off` і падає під
|
|
17
|
-
* readOnlyRootFilesystem) автоматично замінюється на **`error_log /dev/null crit;`** у кожному шаблоні.
|
|
18
|
-
*/
|
|
1
|
+
/** @see ./docs/template.md */
|
|
19
2
|
import { existsSync } from 'node:fs'
|
|
20
3
|
import { readdir, readFile, rename, unlink, writeFile } from 'node:fs/promises'
|
|
21
4
|
import { basename, dirname, join, relative } from 'node:path'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# header_doc_pointer.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Концерн правила `npm-module`, що закріплює контракт між `docs/<stem>.md` і module-level JSDoc у скриптах правил і скілів. Якщо файл вже описано у `docs/<stem>.md` — наратив у заголовному коментарі файлу є дублюванням і заборонений. Якщо `docs` немає — header залишається єдиним джерелом опису поведінки і жодних обмежень немає.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Сканує всі `.mjs`-файли (крім `.test.mjs`) у `npm/rules/*/js/` та `npm/skills/*/js/`.
|
|
10
|
+
2. Для кожного файлу перевіряє наявність `docs/<stem>.md` поруч із `js/`.
|
|
11
|
+
3. Якщо `docs/<stem>.md` **відсутній** — пропускає файл: перевірка не застосовується.
|
|
12
|
+
4. Якщо `docs/<stem>.md` **присутній** — знаходить module-level JSDoc (перший `/** ... */` до першого `import`/`export` на початку рядка).
|
|
13
|
+
5. Рахує непорожні змістовні рядки блоку (після зрізання відступу `*`). Більше одного → порушення.
|
|
14
|
+
|
|
15
|
+
Допустимі форми при наявних docs:
|
|
16
|
+
- відсутній module-level JSDoc (0 рядків)
|
|
17
|
+
- `/** @see ./docs/<stem>.md */` (1 рядок)
|
|
18
|
+
- `/** Контракт: ./docs/<stem>.md */` (1 рядок)
|
|
19
|
+
|
|
20
|
+
## Гарантії поведінки
|
|
21
|
+
|
|
22
|
+
- Файли без `docs/`-відповідника повністю ігноруються — перевірка не створює обмежень до того, як docgen запишеться.
|
|
23
|
+
- Якщо у файлі немає жодного module-level JSDoc — перевірка проходить.
|
|
24
|
+
- Тестові файли (`*.test.mjs`) не скануються.
|
|
25
|
+
- Підкаталоги `tests/`, `data/`, `templates/` у `js/` не скануються (discovery бере лише `*.mjs` безпосередньо в `js/`, не рекурсивно).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** Контракт: ./docs/header_doc_pointer.md */
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import { readFile, readdir } from 'node:fs/promises'
|
|
4
|
+
import { basename, join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|
|
7
|
+
|
|
8
|
+
/** Перший JSDoc-блок у файлі (не-жадібний). */
|
|
9
|
+
const MODULE_JSDOC_RE = /\/\*\*[\s\S]*?\*\//
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* `import` або `export` на початку рядка — межа між module-level і body.
|
|
13
|
+
* Regex, не AST: нас цікавить тільки текстова позиція, не семантика JS.
|
|
14
|
+
*/
|
|
15
|
+
const CODE_START_RE = /^(?:import|export)\b/m
|
|
16
|
+
|
|
17
|
+
/** Кількість непорожніх рядків між `/**` і `*\/` (після зрізання `*`-відступу). */
|
|
18
|
+
function contentLineCount(block) {
|
|
19
|
+
return block
|
|
20
|
+
.split('\n')
|
|
21
|
+
.slice(1, -1)
|
|
22
|
+
.filter(l => /\S/.test(l.replace(/^\s*\*\s?/, '')))
|
|
23
|
+
.length
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Повертає module-level JSDoc або `null`, якщо його немає. */
|
|
27
|
+
function moduleJsDoc(source) {
|
|
28
|
+
const codeStart = CODE_START_RE.exec(source)
|
|
29
|
+
const prefix = codeStart ? source.slice(0, codeStart.index) : source
|
|
30
|
+
const m = MODULE_JSDOC_RE.exec(prefix)
|
|
31
|
+
return m ? m[0] : null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Сканує `npm/rules/*\/js/*.mjs` і `npm/skills/*\/js/*.mjs`.
|
|
36
|
+
* Якщо поряд існує `docs/<stem>.md` — module-level JSDoc має бути pointer (≤1 рядок),
|
|
37
|
+
* а не наратив; якщо docs немає — без обмежень.
|
|
38
|
+
* @param {string} [cwd] корінь репозиторію
|
|
39
|
+
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
40
|
+
*/
|
|
41
|
+
export async function check(cwd = process.cwd()) {
|
|
42
|
+
const reporter = createCheckReporter()
|
|
43
|
+
|
|
44
|
+
for (const baseSegment of ['npm/rules', 'npm/skills']) {
|
|
45
|
+
const absBase = join(cwd, baseSegment)
|
|
46
|
+
if (!existsSync(absBase)) continue
|
|
47
|
+
|
|
48
|
+
for (const ruleEntry of await readdir(absBase, { withFileTypes: true })) {
|
|
49
|
+
if (!ruleEntry.isDirectory() || ruleEntry.name.startsWith('.')) continue
|
|
50
|
+
|
|
51
|
+
const jsDir = join(absBase, ruleEntry.name, 'js')
|
|
52
|
+
if (!existsSync(jsDir)) continue
|
|
53
|
+
|
|
54
|
+
for (const fileEntry of await readdir(jsDir, { withFileTypes: true })) {
|
|
55
|
+
if (
|
|
56
|
+
!fileEntry.isFile() ||
|
|
57
|
+
!fileEntry.name.endsWith('.mjs') ||
|
|
58
|
+
fileEntry.name.endsWith('.test.mjs')
|
|
59
|
+
)
|
|
60
|
+
continue
|
|
61
|
+
|
|
62
|
+
const stem = basename(fileEntry.name, '.mjs')
|
|
63
|
+
const docsPath = join(jsDir, 'docs', `${stem}.md`)
|
|
64
|
+
if (!existsSync(docsPath)) continue
|
|
65
|
+
|
|
66
|
+
const filePath = join(jsDir, fileEntry.name)
|
|
67
|
+
const source = await readFile(filePath, 'utf8')
|
|
68
|
+
const block = moduleJsDoc(source)
|
|
69
|
+
if (!block) continue
|
|
70
|
+
|
|
71
|
+
const count = contentLineCount(block)
|
|
72
|
+
if (count > 1) {
|
|
73
|
+
reporter.fail(
|
|
74
|
+
`${filePath.slice(cwd.length + 1)}: docs/${stem}.md вже описує поведінку — module-level JSDoc має бути pointer (≤1 рядок, зараз ${count})`
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return reporter.getExitCode()
|
|
82
|
+
}
|
|
@@ -1,31 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє структуру npm-модуля в монорепо за правилом npm-module.mdc.
|
|
3
|
-
*
|
|
4
|
-
* Workspace `npm/`, `npm/package.json`, workflow `npm-publish.yml` з OIDC, `on.push.paths` з glob для каталогу npm.
|
|
5
|
-
*
|
|
6
|
-
* Якщо під `npm/src` є хоча б один файл `.js`, очікується канонічний layout: `types` → `./types/index.d.ts`,
|
|
7
|
-
* згенерований `index.d.ts` у `npm/types/`, і hk з викликом `tsc` по файлах під `npm/src`.
|
|
8
|
-
*
|
|
9
|
-
* Якщо таких файлів немає — layout через `npm/tsconfig.emit-types.json`: поле `types` має вказувати на існуючий
|
|
10
|
-
* файл під `./types/…`, у hk — `tsc -p tsconfig.emit-types.json`, у JSON-конфігу — потрібні compilerOptions для emit.
|
|
11
|
-
*
|
|
12
|
-
* Поля workflow перевіряються після **YAML parse**, щоб не плутати з коментарями.
|
|
13
|
-
*
|
|
14
|
-
* Компактність опублікованого пакета (cross-file / FS / AST частина):
|
|
15
|
-
* - Пер-документні структурні deny для `npm/package.json` (`files` whitelist обовʼязковий,
|
|
16
|
-
* без `devDependencies`) — у rego-пакеті `npm_module.npm_package_json` (Rego-authoritative).
|
|
17
|
-
* - Тут лишається лише `checkNoTestsInPublishedFiles`: walk шляхів з `"files"` (з урахуванням
|
|
18
|
-
* негативних glob-патернів) і скан test-style каталогів (`tests/`, `__tests__/`, `fixtures/`,
|
|
19
|
-
* `__fixtures__/`, `spec/`, `test/`), імен файлів (`*.test.*` / `*.spec.*`) і AST-імпортів
|
|
20
|
-
* test-фреймворків (`bun:test`, `node:test`, `vitest`, `@jest/globals`, `mocha`, `jest`, `ava`, …).
|
|
21
|
-
* Виняток: `*_test.rego` дозволені поруч з полісі — це конвенція conftest.
|
|
22
|
-
*
|
|
23
|
-
* Версія та CHANGELOG тут НЕ перевіряються: єдиний артефакт зміни — change-файл, а узгодженість
|
|
24
|
-
* `version`/`CHANGELOG.md` (включно з drift від ручного bump) валідує `changelog/js/consistency.mjs`
|
|
25
|
-
* за моделлю `n-changelog.mdc`. Інваріант «верхня секція CHANGELOG == package.json.version» істинний
|
|
26
|
-
* лише post-release і його гарантує `n-cursor release` у CI — локально його не підтримують руками.
|
|
27
|
-
* @param {string} cwd корінь репозиторію
|
|
28
|
-
*/
|
|
1
|
+
/** @see ./docs/package_structure.md */
|
|
29
2
|
import { existsSync } from 'node:fs'
|
|
30
3
|
import { readFile, stat } from 'node:fs/promises'
|
|
31
4
|
import { join, sep } from 'node:path'
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевірка метаданих правил пакета `@nitra/cursor` (концерн правила npm-module).
|
|
3
|
-
*
|
|
4
|
-
* Кожен `npm/rules/<id>/` має містити валідний `meta.json`:
|
|
5
|
-
* - `auto` (якщо присутнє) — розпізнане `parseRuleAutoSpec` (завжди / масив / glob / predicate);
|
|
6
|
-
* - для `predicate` — імʼя є в реєстрі `RULE_PREDICATES`;
|
|
7
|
-
* - залишковий `auto.md` заборонено (міграція на meta.json завершена).
|
|
8
|
-
*
|
|
9
|
-
* Застосовний лише в репо пакета (де є `npm/rules/`); у споживача каталогу нема — пропуск.
|
|
10
|
-
*/
|
|
1
|
+
/** @see ./docs/rule_meta.md */
|
|
11
2
|
import { existsSync, readdirSync } from 'node:fs'
|
|
12
3
|
import { join } from 'node:path'
|
|
13
4
|
|
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевірка метаданих скілів пакета `@nitra/cursor` (концерн правила npm-module).
|
|
3
|
-
*
|
|
4
|
-
* Кожен `npm/skills/<id>/` має містити валідний `meta.json`:
|
|
5
|
-
* - `worktree` присутнє і boolean;
|
|
6
|
-
* - `auto` (якщо присутнє) — розпізнане (`"завжди"` або непорожній масив рядків);
|
|
7
|
-
* - `requireRoot` (якщо присутнє) — boolean; не може бути `false` при `worktree:true`
|
|
8
|
-
* (worktree вже вимагає кореня — суперечність вводить в оману);
|
|
9
|
-
* - залишковий `auto.md` заборонено (міграція на meta.json завершена).
|
|
10
|
-
*
|
|
11
|
-
* Концерн застосовний лише в репо самого пакета (де є `npm/skills/`); у споживача
|
|
12
|
-
* каталогу `npm/skills/` нема, тож перевірка мовчки проходить.
|
|
13
|
-
*/
|
|
1
|
+
/** @see ./docs/skill_meta.md */
|
|
14
2
|
import { existsSync, readdirSync } from 'node:fs'
|
|
15
3
|
import { join } from 'node:path'
|
|
16
4
|
|
package/rules/php/js/tooling.mjs
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє вимоги правила php.mdc для PHP-проєктів.
|
|
3
|
-
*
|
|
4
|
-
* **Що тут лишилося** (FS-existence — не покривається conftest):
|
|
5
|
-
* - наявність `composer.json` у корені;
|
|
6
|
-
* - наявність `.github/workflows/lint-php.yml`.
|
|
7
|
-
*
|
|
8
|
-
* **Що покрила Rego** (`npx \@nitra/cursor check`):
|
|
9
|
-
* - `npm/policy/php/package_json/` — наявність скрипта `lint-php` у `package.json`;
|
|
10
|
-
* - `npm/policy/php/lint_php_yml/` — крок `run: bun run lint-php` у workflow.
|
|
11
|
-
*/
|
|
1
|
+
/** @see ./docs/tooling.md */
|
|
12
2
|
import { existsSync } from 'node:fs'
|
|
13
3
|
|
|
14
4
|
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Applies-гейт правила `python` (python.mdc): правило застосовне, лише якщо в корені є
|
|
3
|
-
* `pyproject.toml`. Інакше CLI пропускає всі concerns (JS і policy) — інакше rego
|
|
4
|
-
* `python/package_json` хибно вимагає `scripts.lint-python` навіть для не-Python репо.
|
|
5
|
-
*
|
|
6
|
-
* JS тут — гейт на наявність кореневого `pyproject.toml`. Подальші FS-перевірки
|
|
7
|
-
* (`uv.lock`, `package.json`, `lint-python.yml`, заборона Poetry) — у `tooling.mjs`.
|
|
8
|
-
*/
|
|
1
|
+
/** @see ./docs/applies.md */
|
|
9
2
|
import { existsSync } from 'node:fs'
|
|
10
3
|
import { join } from 'node:path'
|
|
11
4
|
|
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє FS-вимоги правила python.mdc для Python-проєктів на uv.
|
|
3
|
-
*
|
|
4
|
-
* **Що тут лишилося** (FS-existence — не покривається conftest):
|
|
5
|
-
* - наявність `uv.lock` поруч (uv-проєкт коммітить lock-файл);
|
|
6
|
-
* - наявність кореневого `package.json` (для `bun run lint-python`);
|
|
7
|
-
* - наявність `.github/workflows/lint-python.yml`;
|
|
8
|
-
* - заборона Poetry-артефактів `poetry.lock` / `poetry.toml` (міграція на uv).
|
|
9
|
-
*
|
|
10
|
-
* Гейт на `pyproject.toml` робить `applies.mjs` — CLI пропускає правило цілком
|
|
11
|
-
* без нього. Захисний early-return лишається тут лише для прямого виклику
|
|
12
|
-
* `check()` (тести/standalone) без `applies.mjs`-гейту.
|
|
13
|
-
*
|
|
14
|
-
* **Що покрила Rego** (`npx \@nitra/cursor fix python`):
|
|
15
|
-
* - `python/pyproject_toml/` — заборона `[tool.poetry]` + вимога PEP 621 `[project].name/version`;
|
|
16
|
-
* - `python/package_json/` — наявність скрипта `lint-python` у `package.json`;
|
|
17
|
-
* - `python/lint_python_yml/` — `uses`/`run`-кроки канонічного workflow.
|
|
18
|
-
*
|
|
19
|
-
* `.venv/` навмисно НЕ перевіряється: uv теж створює `.venv`, тож його наявність
|
|
20
|
-
* не є ознакою Poetry й давала б хибні спрацювання.
|
|
21
|
-
*/
|
|
1
|
+
/** @see ./docs/tooling.md */
|
|
22
2
|
import { existsSync } from 'node:fs'
|
|
23
3
|
import { join } from 'node:path'
|
|
24
4
|
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Applies-гейт правила `rego` (rego.mdc): правило застосовне, лише якщо в репозиторії є
|
|
3
|
-
* хоча б один `.rego`-файл (під типовими skip-ами і `.n-cursor.json:ignore`).
|
|
4
|
-
*
|
|
5
|
-
* Якщо `.rego` нема — CLI пропускає правило цілком (включно з polices `package_json`,
|
|
6
|
-
* `vscode_extensions`, `vscode_settings`), бо вимоги rego-tooling неактуальні. Якщо є — CLI
|
|
7
|
-
* прогонить policy-концерни через `target.json`-маніфести у `rules/rego/policy/<name>/`.
|
|
8
|
-
*
|
|
9
|
-
* JS тут лишається лише як cross-file гейт: walkDir не виразити декларативно через `target.json`.
|
|
10
|
-
* Друк короткого pass-повідомлення з контекстом робить `check()` (необовʼязковий).
|
|
11
|
-
*/
|
|
1
|
+
/** @see ./docs/applies.md */
|
|
12
2
|
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|
|
13
3
|
import { loadCursorIgnorePaths } from '../../../scripts/lib/load-cursor-config.mjs'
|
|
14
4
|
import { walkDir } from '../../../scripts/utils/walkDir.mjs'
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Applies-гейт правила rust: маркер — наявність `Cargo.toml` у `cwd` або
|
|
3
|
-
* в будь-якому workspace-підкаталозі (рекурсивний пошук з пропуском
|
|
4
|
-
* `node_modules`, `.git`, `.next`, `.turbo`). Якщо повертає `false` —
|
|
5
|
-
* `runStandardRule` пропускає всі концерни (JS і policy) цього правила.
|
|
6
|
-
* `check()` друкує тільки context-pass; реальна робота — у policy-концернах.
|
|
7
|
-
*/
|
|
1
|
+
/** @see ./docs/applies.md */
|
|
8
2
|
import { existsSync } from 'node:fs'
|
|
9
3
|
import { join } from 'node:path'
|
|
10
4
|
|
|
@@ -1,31 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FS-частина правила `security`: concern `sample_secret`.
|
|
3
|
-
*
|
|
4
|
-
* Перевіряє, що фейкові credential-значення у *прикладних* файлах записані як
|
|
5
|
-
* канонічний placeholder `sample-secret`, а не як bare `secret`.
|
|
6
|
-
*
|
|
7
|
-
* `sample-secret` містить підрядок `sample`, який є у вшитому списку
|
|
8
|
-
* `DefaultFalsePositives` TruffleHog — таке значення сканер відсіює
|
|
9
|
-
* гарантовано й незалежно від версії. Bare `secret` наразі не фіксується сканером
|
|
10
|
-
* лише тому, що випадково присутнє у словнику `fp_words.txt`; це крихка поведінка,
|
|
11
|
-
* що залежить від версії інструмента, на яку не варто покладатися.
|
|
12
|
-
*
|
|
13
|
-
* Прикладними вважаються файли, чий basename має суфікс `.example` / `.sample`
|
|
14
|
-
* / `.template` / `.dist` або infix `.example.` / `.sample.` / `.template.`, а
|
|
15
|
-
* також будь-які файли всередині каталогів `fixtures` / `fixture` /
|
|
16
|
-
* `__fixtures__`. Решта файлів не сканується — там `secret` майже завжди
|
|
17
|
-
* частина реального коду, а не placeholder.
|
|
18
|
-
*
|
|
19
|
-
* Порушенням є лише `secret` у *позиції значення* — одразу після `=`, `:` чи
|
|
20
|
-
* `=>` (з опційними лапками). Імена ключів (`client_secret`, `JWT_SECRET`) не
|
|
21
|
-
* чіпаються: матч прив'язаний до значення, не до ключа.
|
|
22
|
-
*
|
|
23
|
-
* Чому regex, а не AST: прикладні файли — різнорідні конфіги (`.env`, YAML,
|
|
24
|
-
* JSON, TOML, plain `.dist`), єдиного AST для них немає, тож скан порядковий.
|
|
25
|
-
* Чому JS, а не Rego: щоб знайти прикладні файли, треба обійти дерево
|
|
26
|
-
* (`readdir`), а вміст — неструктурований текст (conftest парсить лише
|
|
27
|
-
* структуровані документи).
|
|
28
|
-
*/
|
|
1
|
+
/** @see ./docs/sample_secret.md */
|
|
29
2
|
import { readFile } from 'node:fs/promises'
|
|
30
3
|
import { relative, sep } from 'node:path'
|
|
31
4
|
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FS-частина правила `security`.
|
|
3
|
-
*
|
|
4
|
-
* Перевіряє:
|
|
5
|
-
* - наявність `package.json` (структуру валідує policy security.package_json);
|
|
6
|
-
* - наявність `.trufflehog-exclude` у корені та subset канонічних patterns
|
|
7
|
-
* (text-subset, бо `.trufflehog-exclude` — plain text, не структурований).
|
|
8
|
-
*/
|
|
1
|
+
/** @see ./docs/trufflehog.md */
|
|
9
2
|
import { existsSync } from 'node:fs'
|
|
10
3
|
import { readFile } from 'node:fs/promises'
|
|
11
4
|
import { dirname, join } from 'node:path'
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Quick-крок lint правила style-lint: stylelint --fix по css/scss/vue.
|
|
3
|
-
*
|
|
4
|
-
* `files` (quick) → лише style-файли з них; undefined (ci) → весь glob `**\/*.{css,scss,vue}`.
|
|
5
|
-
*/
|
|
1
|
+
/** @see ./docs/lint.md */
|
|
6
2
|
import { spawnSync } from 'node:child_process'
|
|
7
3
|
|
|
8
4
|
const STYLE_EXT_RE = /\.(?:css|scss|vue)$/u
|
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє CSS/SCSS лінт за правилом style-lint.mdc.
|
|
3
|
-
*
|
|
4
|
-
* **Що тут лишилося** (FS / cross-file — не покривається conftest):
|
|
5
|
-
* - наявність зовнішнього файлу конфігу stylelint (`.stylelintrc.*`,
|
|
6
|
-
* `stylelint.config.js`) як альтернатива полю `stylelint` у `package.json`
|
|
7
|
-
* (cross-file: треба знати, чи є поле, чи немає);
|
|
8
|
-
* - `.stylelintignore` у корені.
|
|
9
|
-
*
|
|
10
|
-
* **Що покрила Rego** (`npx \@nitra/cursor check`):
|
|
11
|
-
* - `npm/policy/style_lint/package_json/` — скрипт `lint-style` через `npx stylelint`,
|
|
12
|
-
* `@nitra/stylelint-config` у `devDependencies`, поле `stylelint.extends`;
|
|
13
|
-
* - `npm/policy/style_lint/lint_style_yml/` — `npx stylelint` у `run` workflow;
|
|
14
|
-
* - `npm/policy/style_lint/vscode_extensions/` — `stylelint.vscode-stylelint`
|
|
15
|
-
* у `recommendations` `.vscode/extensions.json`;
|
|
16
|
-
* - `npm/policy/style_lint/vscode_settings/` — `css.validate`/`scss.validate`/
|
|
17
|
-
* `less.validate: false` у `.vscode/settings.json`.
|
|
18
|
-
* @param {string} cwd корінь репозиторію
|
|
19
|
-
*/
|
|
1
|
+
/** @see ./docs/tooling.md */
|
|
20
2
|
import { existsSync } from 'node:fs'
|
|
21
3
|
import { readFile } from 'node:fs/promises'
|
|
22
4
|
import { join } from 'node:path'
|
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Концерн `cargo_mutants_config` правила tauri (tauri.mdc): для кожного
|
|
3
|
-
* `<workspace>/src-tauri/Cargo.toml` без дублювання гарантує наявність
|
|
4
|
-
* Tauri-specific cargo-mutants налаштувань у `<workspace>/src-tauri/.cargo/mutants.toml`.
|
|
5
|
-
*
|
|
6
|
-
* Семантика (фіксована між Tauri-проєктами):
|
|
7
|
-
* - `src/main.rs` — binary shell entrypoint (smoke/e2e, не mutation unit);
|
|
8
|
-
* - `src/**\/{android,ios,mobile}.rs` — mobile plugin bridge / platform glue;
|
|
9
|
-
* - `src/**\/{macos,windows,linux,desktop}.rs` — desktop platform bridge / OS integration glue.
|
|
10
|
-
*
|
|
11
|
-
* Self-gating: silently skip, якщо в monorepo не знайдено жодного
|
|
12
|
-
* `<ws>/src-tauri/Cargo.toml` (test rule сам створить нейтральний baseline там,
|
|
13
|
-
* де потрібно).
|
|
14
|
-
*
|
|
15
|
-
* Ідемпотентність:
|
|
16
|
-
* - якщо файл відсутній — створює з Tauri-canonical baseline;
|
|
17
|
-
* - якщо файл існує і всі канонічні ключі вже є — `manual cargo-mutants config preserved`;
|
|
18
|
-
* - якщо файл існує, але якихось канонічних top-level ключів немає — додає
|
|
19
|
-
* лише відсутні ключі окремим блоком у кінці; існуючих значень не торкається.
|
|
20
|
-
*/
|
|
1
|
+
/** @see ./docs/cargo_mutants_config.md */
|
|
21
2
|
import { existsSync } from 'node:fs'
|
|
22
3
|
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
23
4
|
import { dirname, join, relative } from 'node:path'
|
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє інструментарій Tauri (tauri.mdc): VSCode `extensions.json` для
|
|
3
|
-
* проєктів, у яких є маркер Tauri.
|
|
4
|
-
*
|
|
5
|
-
* Cross-file gating (JS):
|
|
6
|
-
* 1. Tauri-маркер визначаємо обходом усіх workspace-пакетів через
|
|
7
|
-
* `getMonorepoPackageRootDirs()` (корінь + workspaces). Кожен workspace
|
|
8
|
-
* перевіряється за **будь-яким** з:
|
|
9
|
-
* - існує каталог `<ws>/src-tauri/`;
|
|
10
|
-
* - існує файл `<ws>/src-tauri/Cargo.toml`;
|
|
11
|
-
* - існує файл `<ws>/src-tauri/tauri.conf.json`;
|
|
12
|
-
* - існує файл `<ws>/tauri.conf.json` (legacy flat-layout);
|
|
13
|
-
* - `<ws>/package.json#dependencies` чи `devDependencies` містить ключ
|
|
14
|
-
* з префіксом `@tauri-apps/`.
|
|
15
|
-
* 2. Якщо маркера немає — пропустити перевірку (tauri-tooling не вимагається).
|
|
16
|
-
* 3. Інакше — для `.vscode/extensions.json` зробити FS-existence + делегувати
|
|
17
|
-
* content `rego.tauri.vscode_extensions` через `runConftestBatch`.
|
|
18
|
-
*
|
|
19
|
-
* Rego-полісі глобально без `target.json` поруч (не auto-discoverable через `n-cursor fix`) — це conditional
|
|
20
|
-
* правило. Plan B: Rego-authoritative + JS-orchestrator з `runConftestBatch`.
|
|
21
|
-
*/
|
|
1
|
+
/** @see ./docs/tooling.md */
|
|
22
2
|
import { existsSync, statSync } from 'node:fs'
|
|
23
3
|
import { readFile } from 'node:fs/promises'
|
|
24
4
|
import { join } from 'node:path'
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Концерн `cargo_mutants_config` правила test (test.mdc): якщо `rust` присутнє
|
|
3
|
-
* в `.n-cursor.json#rules` і не у `disable-rules` — визначає ВСІ Cargo.toml
|
|
4
|
-
* (cwd і всі workspaces, з підтримкою Tauri-патерну) і копіює canonical
|
|
5
|
-
* baseline `.cargo/mutants.toml` у каталог кожного manifest'а, якщо файлу немає.
|
|
6
|
-
*
|
|
7
|
-
* Self-gating: концерн silently skips коли `rust` не enabled.
|
|
8
|
-
* Якщо `rust` enabled, але жодного Cargo.toml не знайдено — теж silently skip
|
|
9
|
-
* (manifest може з'явитися пізніше; це не помилка).
|
|
10
|
-
*
|
|
11
|
-
* Baseline — порожній файл з коментарем; cargo-mutants має робочі defaults.
|
|
12
|
-
*/
|
|
1
|
+
/** @see ./docs/cargo_mutants_config.md */
|
|
13
2
|
import { existsSync } from 'node:fs'
|
|
14
3
|
import { copyFile, mkdir } from 'node:fs/promises'
|
|
15
4
|
import { dirname, join, relative } from 'node:path'
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє, що всі `*.test.mjs` лежать у каталозі `tests/` (а не поряд із джерельним файлом).
|
|
3
|
-
*
|
|
4
|
-
* Конвенція (test.mdc): `dir/foo.mjs` → тест у `dir/tests/foo.test.mjs`.
|
|
5
|
-
* `*_test.rego` виключені: Rego unit-тести живуть поряд із полісі (OPA community convention).
|
|
6
|
-
*
|
|
7
|
-
* Пропускає: `node_modules`, `.git`, `dist`, `build`, `.venv`, `venv` (через `walkDir`)
|
|
8
|
-
* і шляхи з `.n-cursor.json:ignore`.
|
|
9
|
-
*/
|
|
1
|
+
/** @see ./docs/location.md */
|
|
10
2
|
import { basename, dirname, relative } from 'node:path'
|
|
11
3
|
|
|
12
4
|
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|