@nitra/cursor 1.8.221 → 1.8.222

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 (29) hide show
  1. package/.claude-template/npm-CLAUDE.md +4 -0
  2. package/CHANGELOG.md +15 -0
  3. package/bin/auto-rules.md +2 -0
  4. package/mdc/tauri.mdc +20 -0
  5. package/package.json +1 -1
  6. package/policy/k8s/base_kustomization/base_kustomization.rego +40 -0
  7. package/policy/k8s/base_kustomization/base_kustomization_test.rego +36 -0
  8. package/policy/k8s/base_manifest/base_manifest.rego +154 -0
  9. package/policy/k8s/base_manifest/base_manifest_test.rego +94 -0
  10. package/policy/k8s/gateway/gateway.rego +151 -0
  11. package/policy/k8s/gateway/gateway_test.rego +122 -0
  12. package/policy/k8s/hasura_configmap/hasura_configmap.rego +69 -0
  13. package/policy/k8s/hasura_configmap/hasura_configmap_test.rego +49 -0
  14. package/policy/k8s/hasura_httproute/hasura_httproute.rego +298 -0
  15. package/policy/k8s/hasura_httproute/hasura_httproute_test.rego +148 -0
  16. package/policy/k8s/hpa_pdb/hpa_pdb.rego +139 -0
  17. package/policy/k8s/hpa_pdb/hpa_pdb_test.rego +101 -0
  18. package/policy/k8s/kustomization/kustomization.rego +220 -0
  19. package/policy/k8s/kustomization/kustomization_test.rego +128 -0
  20. package/policy/k8s/kustomize_managed/kustomize_managed.rego +31 -0
  21. package/policy/k8s/kustomize_managed/kustomize_managed_test.rego +30 -0
  22. package/policy/k8s/manifest/manifest.rego +151 -4
  23. package/policy/k8s/manifest/manifest_test.rego +309 -0
  24. package/policy/k8s/svc_hl_yaml/svc_hl_yaml.rego +51 -0
  25. package/policy/k8s/svc_hl_yaml/svc_hl_yaml_test.rego +42 -0
  26. package/policy/k8s/svc_yaml/svc_yaml.rego +31 -0
  27. package/policy/k8s/svc_yaml/svc_yaml_test.rego +41 -0
  28. package/scripts/lint-conftest.mjs +73 -1
  29. package/scripts/lint-rego.mjs +19 -4
@@ -79,6 +79,16 @@ const K8S_DIR_PATH_RE = /(^|\/)k8s\//u
79
79
  const K8S_HC_YAML_PATH_RE = /(^|\/)k8s\/.+\/hc\.yaml$/u
80
80
  /** `…/k8s/…/base/…/hr.yaml` (HTTPRoute у base-шарі). */
81
81
  const K8S_BASE_HR_YAML_PATH_RE = /(^|\/)k8s\/.*base\/.*hr\.yaml$/u
82
+ /** `kustomization.yaml` будь-де під сегментом `k8s/`. */
83
+ const K8S_KUSTOMIZATION_PATH_RE = /(^|\/)k8s\/.*\/kustomization\.yaml$/u
84
+ /** `…/k8s/.../base/.../kustomization.yaml`. */
85
+ const K8S_BASE_KUSTOMIZATION_PATH_RE = /(^|\/)k8s\/.*base\/(?:.*\/)?kustomization\.yaml$/u
86
+ /** Будь-який ресурсний `*.yaml` під сегментом `…/k8s/.../base/...`, окрім `kustomization.yaml`. */
87
+ const K8S_BASE_MANIFEST_PATH_RE = /(^|\/)k8s\/.*base\//u
88
+ /** `…/k8s/.../svc.yaml` (cluster-IP Service). */
89
+ const K8S_SVC_YAML_PATH_RE = /(^|\/)k8s\/.+\/svc\.yaml$/u
90
+ /** `…/k8s/.../svc-hl.yaml` (headless Service). */
91
+ const K8S_SVC_HL_YAML_PATH_RE = /(^|\/)k8s\/.+\/svc-hl\.yaml$/u
82
92
 
83
93
  /** @type {ConftestTarget[]} */
84
94
  const TARGETS = [
@@ -221,11 +231,73 @@ const TARGETS = [
221
231
  // Усі YAML у дереві з сегментом `k8s` — пер-документні структурні правила.
222
232
  {
223
233
  namespace: 'k8s.manifest',
224
- policyDir: 'k8s',
234
+ policyDir: 'k8s/manifest',
225
235
  rule: 'k8s',
226
236
  walk: { match: rel => K8S_DIR_PATH_RE.test(rel) && (rel.endsWith('.yaml') || rel.endsWith('.yml')) }
227
237
  },
228
238
 
239
+ // Gateway API + HealthCheckPolicy — застосовується до будь-якого YAML під k8s
240
+ // (правила перевіряють лише відповідні kind / apiVersion).
241
+ {
242
+ namespace: 'k8s.gateway',
243
+ policyDir: 'k8s/gateway',
244
+ rule: 'k8s',
245
+ walk: { match: rel => K8S_DIR_PATH_RE.test(rel) && (rel.endsWith('.yaml') || rel.endsWith('.yml')) }
246
+ },
247
+
248
+ // Структурні перевірки HPA / PDB (apiVersion / behavior / metrics / selector).
249
+ {
250
+ namespace: 'k8s.hpa_pdb',
251
+ policyDir: 'k8s/hpa_pdb',
252
+ rule: 'k8s',
253
+ walk: { match: rel => K8S_DIR_PATH_RE.test(rel) && (rel.endsWith('.yaml') || rel.endsWith('.yml')) }
254
+ },
255
+
256
+ // Kustomization-файли: resources sort, patches sort, JSON6902 conflicts.
257
+ {
258
+ namespace: 'k8s.kustomization',
259
+ policyDir: 'k8s/kustomization',
260
+ rule: 'k8s',
261
+ walk: { match: rel => K8S_KUSTOMIZATION_PATH_RE.test(rel) }
262
+ },
263
+
264
+ // svc.yaml — cluster-IP Service.
265
+ {
266
+ namespace: 'k8s.svc_yaml',
267
+ policyDir: 'k8s/svc_yaml',
268
+ rule: 'k8s',
269
+ walk: { match: rel => K8S_SVC_YAML_PATH_RE.test(rel) }
270
+ },
271
+
272
+ // svc-hl.yaml — headless Service з суфіксом `-hl`.
273
+ {
274
+ namespace: 'k8s.svc_hl_yaml',
275
+ policyDir: 'k8s/svc_hl_yaml',
276
+ rule: 'k8s',
277
+ walk: { match: rel => K8S_SVC_HL_YAML_PATH_RE.test(rel) }
278
+ },
279
+
280
+ // base/kustomization.yaml — обов'язкове непорожнє поле `namespace:`.
281
+ {
282
+ namespace: 'k8s.base_kustomization',
283
+ policyDir: 'k8s/base_kustomization',
284
+ rule: 'k8s',
285
+ walk: { match: rel => K8S_BASE_KUSTOMIZATION_PATH_RE.test(rel) }
286
+ },
287
+
288
+ // Ресурсні маніфести під `…/k8s/.../base/...` (окрім kustomization.yaml).
289
+ {
290
+ namespace: 'k8s.base_manifest',
291
+ policyDir: 'k8s/base_manifest',
292
+ rule: 'k8s',
293
+ walk: {
294
+ match: rel =>
295
+ K8S_BASE_MANIFEST_PATH_RE.test(rel) &&
296
+ !K8S_BASE_KUSTOMIZATION_PATH_RE.test(rel) &&
297
+ (rel.endsWith('.yaml') || rel.endsWith('.yml'))
298
+ }
299
+ },
300
+
229
301
  // abie HealthCheckPolicy: `hc.yaml` у дереві k8s.
230
302
  {
231
303
  namespace: 'abie.health_check_policy',
@@ -1,13 +1,17 @@
1
1
  /**
2
2
  * Лінт Rego-полісі (`conftest.mdc` + `rego.mdc`): preflight на `opa` і `regal`,
3
- * далі послідовно `opa check --strict` і `regal lint`.
3
+ * далі послідовно `opa check --strict`, `regal lint` і опційний
4
+ * `conftest verify` (для `*_test.rego`-файлів) якщо conftest у PATH.
4
5
  *
5
- * Чому два інструменти:
6
+ * Чому два-три інструменти:
6
7
  * - `opa check --strict` — компіляція з типами і строгим режимом (мертвий код, неоднозначні
7
8
  * правила, незадекларовані змінні). Ловить помилки, які `regal` навмисно лишає поза скоупом
8
9
  * (він — про стиль і ідіоматичність, а не про компіляцію).
9
10
  * - `regal lint` (https://docs.styra.com/regal) — статичний лінтер Rego: ловить v0-синтаксис,
10
11
  * неявні set-rules та інші відхилення від `rego.v1`, плюс bugs/idiomatic/performance-правила.
12
+ * - `conftest verify` (опційно) — виконує `test_*` правила у `*_test.rego` (юніт-тести політик).
13
+ * Якщо conftest відсутній у PATH — пропускаємо без помилки (тести опційні в локальному середовищі;
14
+ * у CI потрібно встановити conftest).
11
15
  *
12
16
  * Без preflight-у на бінарники лінт мовчки злетить з невиразним повідомленням від shell —
13
17
  * друкуємо явні install-hints (як це робить `lint-ga.mjs` для shellcheck/uv). `opa` додатково
@@ -16,7 +20,7 @@
16
20
  *
17
21
  * Цілі лінту: `npm/policy/` (місце, де поки що живуть Rego-полісі пакета `@nitra/cursor`).
18
22
  * Якщо в репозиторії з’являться інші *.rego поза цим деревом, додай шлях у `LINT_TARGETS` —
19
- * обидва інструменти приймають кілька шляхів і самі рекурсивно обходять директорії.
23
+ * усі три інструменти приймають кілька шляхів і самі рекурсивно обходять директорії.
20
24
  */
21
25
  import { spawnSync } from 'node:child_process'
22
26
  import { existsSync } from 'node:fs'
@@ -110,7 +114,18 @@ export function runLintRego(cwd = process.cwd()) {
110
114
  const opaCode = runStep(opa, ['check', '--strict', ...targets], root)
111
115
  if (opaCode !== 0) return opaCode
112
116
 
113
- return runStep(regal, ['lint', ...targets], root)
117
+ const regalCode = runStep(regal, ['lint', ...targets], root)
118
+ if (regalCode !== 0) return regalCode
119
+
120
+ const conftest = resolveCmd('conftest')
121
+ if (!conftest) {
122
+ console.log(
123
+ 'ℹ conftest не знайдено в PATH — пропускаю `conftest verify` (юніт-тести *_test.rego).\n' +
124
+ ' Встанови, щоб запустити локально: brew install conftest (macOS) або https://www.conftest.dev/install/'
125
+ )
126
+ return 0
127
+ }
128
+ return runStep(conftest, ['verify', ...targets.flatMap(t => ['-p', t])], root)
114
129
  }
115
130
 
116
131
  process.exitCode = runLintRego()