@nitra/cursor 1.13.14 → 1.13.25
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 +85 -0
- package/package.json +1 -1
- package/rules/abie/abie.mdc +1 -4
- package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches.rego +21 -40
- package/rules/abie/policy/clean_merged_ignore_branches/template/clean-merged-branch.yml.snippet.yml +9 -0
- package/rules/docker/docker.mdc +2 -50
- package/rules/docker/policy/lint_docker_yml/lint_docker_yml.rego +33 -47
- package/rules/docker/policy/lint_docker_yml/template/lint-docker.yml.snippet.yml +41 -0
- package/rules/docker/policy/package_json/package_json.rego +11 -28
- package/rules/docker/policy/package_json/template/package.json.snippet.json +1 -0
- package/rules/image-avif/policy/package_json/package_json.rego +21 -35
- package/rules/image-avif/policy/package_json/template/package.json.deny.json +5 -0
- package/rules/image-compress/image-compress.mdc +2 -8
- package/rules/image-compress/policy/package_json/package_json.rego +24 -65
- package/rules/image-compress/policy/package_json/template/package.json.contains.json +5 -0
- package/rules/image-compress/policy/package_json/template/package.json.deny.json +8 -0
- package/rules/js-bun-db/policy/package_json/package_json.rego +8 -21
- package/rules/js-bun-db/policy/package_json/template/package.json.deny.json +7 -0
- package/rules/js-bun-redis/policy/package_json/package_json.rego +8 -30
- package/rules/js-bun-redis/policy/package_json/template/package.json.deny.json +12 -0
- package/rules/js-lint/policy/jscpd/jscpd.rego +29 -23
- package/rules/js-lint/policy/jscpd/template/.jscpd.json.snippet.json +6 -0
- package/rules/js-lint/policy/lint_js_yml/lint_js_yml.rego +39 -47
- package/rules/js-lint/policy/lint_js_yml/template/lint-js.yml.snippet.yml +44 -0
- package/rules/js-lint/policy/package_json/package_json.rego +22 -42
- package/rules/js-lint/policy/package_json/template/package.json.snippet.json +6 -0
- package/rules/js-lint/policy/vscode_extensions/template/extensions.json.snippet.json +7 -0
- package/rules/js-lint/policy/vscode_extensions/vscode_extensions.rego +4 -17
- package/rules/js-run/policy/configmap/configmap.rego +11 -35
- package/rules/js-run/policy/configmap/template/configmap.yaml.contains.yml +4 -0
- package/rules/js-run/policy/jsconfig/jsconfig.rego +39 -46
- package/rules/js-run/policy/jsconfig/template/jsconfig.json.snippet.json +10 -0
- package/rules/js-run/policy/package_json/package_json.rego +10 -21
- package/rules/js-run/policy/package_json/template/package.json.deny.json +10 -0
- package/rules/npm-module/npm-module.mdc +7 -36
- package/rules/npm-module/policy/emit_types_config/emit_types_config.rego +18 -27
- package/rules/npm-module/policy/emit_types_config/template/tsconfig.emit-types.json.snippet.json +9 -0
- package/rules/npm-module/policy/npm_package_json/npm_package_json.rego +20 -30
- package/rules/npm-module/policy/npm_package_json/template/package.json.snippet.json +1 -0
- package/rules/npm-module/policy/npm_publish_yml/npm_publish_yml.rego +46 -38
- package/rules/npm-module/policy/npm_publish_yml/template/npm-publish.yml.snippet.yml +34 -0
- package/rules/npm-module/policy/root_package_json/root_package_json.rego +17 -17
- package/rules/npm-module/policy/root_package_json/template/package.json.snippet.json +1 -0
- package/rules/php/php.mdc +2 -56
- package/rules/php/policy/lint_php_yml/lint_php_yml.rego +15 -13
- package/rules/php/policy/lint_php_yml/template/lint-php.yml.snippet.yml +47 -0
- package/rules/php/policy/package_json/package_json.rego +9 -12
- package/rules/php/policy/package_json/template/package.json.contains.json +5 -0
- package/rules/style-lint/policy/lint_style_yml/lint_style_yml.rego +14 -16
- package/rules/style-lint/policy/lint_style_yml/template/lint-style.yml.snippet.yml +39 -0
- package/rules/style-lint/policy/package_json/package_json.rego +22 -30
- package/rules/style-lint/policy/package_json/template/package.json.contains.json +5 -0
- package/rules/style-lint/policy/package_json/template/package.json.snippet.json +5 -0
- package/rules/style-lint/policy/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/style-lint/policy/vscode_extensions/vscode_extensions.rego +5 -15
- package/rules/style-lint/policy/vscode_settings/template/settings.json.snippet.json +5 -0
- package/rules/style-lint/policy/vscode_settings/vscode_settings.rego +7 -16
- package/rules/text/policy/cspell/cspell.rego +39 -59
- package/rules/text/policy/cspell/template/.cspell.json.contains.json +3 -0
- package/rules/text/policy/cspell/template/.cspell.json.deny.json +5 -0
- package/rules/text/policy/cspell/template/.cspell.json.snippet.json +12 -0
- package/rules/text/policy/markdownlint/markdownlint.rego +37 -50
- package/rules/text/policy/markdownlint/template/.markdownlint-cli2.jsonc.snippet.jsonc +11 -0
- package/rules/text/policy/oxfmtrc/oxfmtrc.rego +23 -58
- package/rules/text/policy/oxfmtrc/template/.oxfmtrc.json.snippet.json +12 -0
- package/rules/text/policy/package_json/package_json.rego +14 -52
- package/rules/text/policy/package_json/template/package.json.deny.json +15 -0
- package/rules/text/policy/vscode_extensions/template/extensions.json.snippet.json +7 -0
- package/rules/text/policy/vscode_extensions/vscode_extensions.rego +4 -28
- package/rules/text/policy/vscode_settings/template/settings.json.snippet.json +9 -0
- package/rules/text/policy/vscode_settings/vscode_settings.rego +20 -42
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
#
|
|
2
|
-
# (npm-module.mdc) — масив `workspaces` має містити "npm".
|
|
3
|
-
#
|
|
4
|
-
# Запуск (локально):
|
|
5
|
-
# conftest test package.json -p npm/policy/npm_module \
|
|
6
|
-
# --namespace npm_module.root_package_json
|
|
1
|
+
# Перевірка кореневого `package.json` для npm-module (npm-module.mdc).
|
|
7
2
|
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/package.json.snippet.json.
|
|
5
|
+
# Snippet-array subset-of: кожне значення з template-масиву має бути у input-масиві.
|
|
8
6
|
# Решта кореневих `package.json`-перевірок (заборонені поля, devDeps лише @nitra/*)
|
|
9
|
-
# — у `bun.package_json`. FS-перевірки (наявність каталогу `npm/`,
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
13
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
14
|
-
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
7
|
+
# — у `bun.package_json`. FS-перевірки (наявність каталогу `npm/`, `npm/package.json`)
|
|
8
|
+
# — у JS.
|
|
15
9
|
package npm_module.root_package_json
|
|
16
10
|
|
|
17
11
|
import rego.v1
|
|
18
12
|
|
|
13
|
+
# Поле має бути масивом — інакше окрема deny.
|
|
19
14
|
deny contains msg if {
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
some field in object.keys(data.template.snippet)
|
|
16
|
+
not is_array(object.get(input, field, null))
|
|
17
|
+
msg := sprintf("package.json: масив %s відсутній або не масив (npm-module.mdc)", [field])
|
|
22
18
|
}
|
|
23
19
|
|
|
20
|
+
# Subset-of: кожне значення з template має бути в input-масиві.
|
|
24
21
|
deny contains msg if {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
some field, expected_values in data.template.snippet
|
|
23
|
+
is_array(object.get(input, field, null))
|
|
24
|
+
actual_set := {v | some v in input[field]}
|
|
25
|
+
some required in expected_values
|
|
26
|
+
not required in actual_set
|
|
27
|
+
msg := sprintf("package.json: %s має містити %q (npm-module.mdc)", [field, required])
|
|
28
28
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "workspaces": ["npm"] }
|
package/rules/php/php.mdc
CHANGED
|
@@ -65,13 +65,7 @@ composer audit
|
|
|
65
65
|
|
|
66
66
|
`composer`-інструмененти не мають єдиного CLI, який сам обходить репозиторій, тому `lint-php` зручно делегувати у JS-скрипт-обгортку (як `lint-docker`, `lint-k8s`).
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
"scripts": {
|
|
71
|
-
"lint-php": "bun ./npm/scripts/run-php.mjs"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
68
|
+
- Канон `package.json#scripts.lint-php` (substring requirement): [package.json.contains.json](./policy/package_json/template/package.json.contains.json)
|
|
75
69
|
|
|
76
70
|
Скрипт `run-php.mjs`:
|
|
77
71
|
|
|
@@ -82,52 +76,4 @@ composer audit
|
|
|
82
76
|
|
|
83
77
|
## CI: `.github/workflows/lint-php.yml`
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
name: Lint PHP
|
|
87
|
-
|
|
88
|
-
on:
|
|
89
|
-
push:
|
|
90
|
-
branches:
|
|
91
|
-
- dev
|
|
92
|
-
- main
|
|
93
|
-
paths:
|
|
94
|
-
- '**/*.php'
|
|
95
|
-
- 'composer.json'
|
|
96
|
-
- 'composer.lock'
|
|
97
|
-
- 'phpstan.neon'
|
|
98
|
-
- 'phpstan.neon.dist'
|
|
99
|
-
- 'psalm.xml'
|
|
100
|
-
- '.github/workflows/lint-php.yml'
|
|
101
|
-
|
|
102
|
-
pull_request:
|
|
103
|
-
branches:
|
|
104
|
-
- dev
|
|
105
|
-
- main
|
|
106
|
-
|
|
107
|
-
concurrency:
|
|
108
|
-
group: ${{ github.ref }}-${{ github.workflow }}
|
|
109
|
-
cancel-in-progress: true
|
|
110
|
-
|
|
111
|
-
jobs:
|
|
112
|
-
php:
|
|
113
|
-
runs-on: ubuntu-latest
|
|
114
|
-
permissions:
|
|
115
|
-
contents: read
|
|
116
|
-
steps:
|
|
117
|
-
- uses: actions/checkout@v6
|
|
118
|
-
with:
|
|
119
|
-
persist-credentials: false
|
|
120
|
-
|
|
121
|
-
- uses: ./.github/actions/setup-bun-deps
|
|
122
|
-
|
|
123
|
-
- name: Install PHP
|
|
124
|
-
uses: shivammathur/setup-php@v2
|
|
125
|
-
with:
|
|
126
|
-
php-version: '8.5'
|
|
127
|
-
|
|
128
|
-
- name: Install Composer dependencies
|
|
129
|
-
run: composer install --no-interaction --no-progress --prefer-dist
|
|
130
|
-
|
|
131
|
-
- name: Lint PHP
|
|
132
|
-
run: bun run lint-php
|
|
133
|
-
```
|
|
79
|
+
- Канон: [lint-php.yml.snippet.yml](./policy/lint_php_yml/template/lint-php.yml.snippet.yml)
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Перевірка `lint-php.yml` (php.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# Перевіряє: хоча б один крок `run` містить `bun run lint-php`. Універсальні
|
|
8
|
-
# workflow-перевірки — у `ga.workflow_common`.
|
|
9
|
-
#
|
|
10
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
11
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
12
|
-
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/lint-php.yml.snippet.yml.
|
|
5
|
+
# Маркер `run:` (bun run lint-php) збирається з template's php-job steps.
|
|
6
|
+
# Універсальні workflow-перевірки — у `ga.workflow_common`.
|
|
13
7
|
package php.lint_php_yml
|
|
14
8
|
|
|
15
9
|
import rego.v1
|
|
16
10
|
|
|
11
|
+
# Очікуваний `run:` маркер — конкатенація всіх run-блоків з template.
|
|
12
|
+
expected_run_blob := concat("\n", [r |
|
|
13
|
+
some step in data.template.snippet.jobs.php.steps
|
|
14
|
+
r := object.get(step, "run", "")
|
|
15
|
+
r != ""
|
|
16
|
+
])
|
|
17
|
+
|
|
17
18
|
all_run_text := concat("\n", [run_text |
|
|
18
19
|
some job in object.get(input, "jobs", {})
|
|
19
20
|
some step in object.get(job, "steps", [])
|
|
@@ -21,8 +22,9 @@ all_run_text := concat("\n", [run_text |
|
|
|
21
22
|
])
|
|
22
23
|
|
|
23
24
|
deny contains msg if {
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
expected_run_blob != ""
|
|
26
|
+
not contains(all_run_text, expected_run_blob)
|
|
27
|
+
msg := sprintf("lint-php.yml: жоден крок run не містить %q (php.mdc)", [expected_run_blob])
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
step_run_to_text(step) := step.run if is_string(step.run)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Lint PHP
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- dev
|
|
7
|
+
- main
|
|
8
|
+
paths:
|
|
9
|
+
- '**/*.php'
|
|
10
|
+
- 'composer.json'
|
|
11
|
+
- 'composer.lock'
|
|
12
|
+
- 'phpstan.neon'
|
|
13
|
+
- 'phpstan.neon.dist'
|
|
14
|
+
- 'psalm.xml'
|
|
15
|
+
- '.github/workflows/lint-php.yml'
|
|
16
|
+
|
|
17
|
+
pull_request:
|
|
18
|
+
branches:
|
|
19
|
+
- dev
|
|
20
|
+
- main
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: ${{ github.ref }}-${{ github.workflow }}
|
|
24
|
+
cancel-in-progress: true
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
php:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v6
|
|
33
|
+
with:
|
|
34
|
+
persist-credentials: false
|
|
35
|
+
|
|
36
|
+
- uses: ./.github/actions/setup-bun-deps
|
|
37
|
+
|
|
38
|
+
- name: Install PHP
|
|
39
|
+
uses: shivammathur/setup-php@v2
|
|
40
|
+
with:
|
|
41
|
+
php-version: '8.5'
|
|
42
|
+
|
|
43
|
+
- name: Install Composer dependencies
|
|
44
|
+
run: composer install --no-interaction --no-progress --prefer-dist
|
|
45
|
+
|
|
46
|
+
- name: Lint PHP
|
|
47
|
+
run: bun run lint-php
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Перевірка `package.json` (php.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Перевіряє: наявність скрипта `lint-php`. FS-перевірки (`composer.json`, наявність
|
|
7
|
-
# `package.json` як такого) — у JS.
|
|
8
|
-
#
|
|
9
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
10
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
11
|
-
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
3
|
+
# Канон надходить через --data: { "template": { "contains": ... } }
|
|
4
|
+
# Структура --data сформована з template/package.json.contains.json.
|
|
5
|
+
# FS-перевірки (`composer.json`, наявність `package.json` як такого) — у JS.
|
|
12
6
|
package php.package_json
|
|
13
7
|
|
|
14
8
|
import rego.v1
|
|
15
9
|
|
|
16
10
|
deny contains msg if {
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
some script_name, needles in data.template.contains.scripts
|
|
12
|
+
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
13
|
+
some needle in needles
|
|
14
|
+
not contains(actual, needle)
|
|
15
|
+
msg := sprintf("package.json: scripts.%s має містити %q (php.mdc)", [script_name, needle])
|
|
19
16
|
}
|
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Перевірка `lint-style.yml` (style-lint.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# Перевіряє: хоча б один крок `run` містить `npx stylelint` (саме через npx, не
|
|
8
|
-
# `bun run lint-style`). Універсальні workflow-перевірки (concurrency, заборонені
|
|
9
|
-
# setup-bun/cache/install) — у `ga.workflow_common`.
|
|
10
|
-
#
|
|
11
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
12
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
13
|
-
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/lint-style.yml.snippet.yml.
|
|
5
|
+
# Маркер `run:` (npx stylelint substring) збирається з template's stylelint-job steps.
|
|
6
|
+
# Універсальні workflow-перевірки — у `ga.workflow_common`.
|
|
14
7
|
package style_lint.lint_style_yml
|
|
15
8
|
|
|
16
9
|
import rego.v1
|
|
17
10
|
|
|
18
|
-
|
|
11
|
+
expected_run_blob := concat("\n", [r |
|
|
12
|
+
some step in data.template.snippet.jobs.stylelint.steps
|
|
13
|
+
r := object.get(step, "run", "")
|
|
14
|
+
r != ""
|
|
15
|
+
])
|
|
16
|
+
|
|
19
17
|
all_run_text := concat("\n", [run_text |
|
|
20
18
|
some job in object.get(input, "jobs", {})
|
|
21
19
|
some step in object.get(job, "steps", [])
|
|
@@ -23,11 +21,11 @@ all_run_text := concat("\n", [run_text |
|
|
|
23
21
|
])
|
|
24
22
|
|
|
25
23
|
deny contains msg if {
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
expected_run_blob != ""
|
|
25
|
+
not contains(all_run_text, expected_run_blob)
|
|
26
|
+
msg := sprintf("lint-style.yml: жоден крок run не містить %q (style-lint.mdc)", [expected_run_blob])
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
# Текст `run:` як один рядок: підтримує string і array форми (YAML).
|
|
31
29
|
step_run_to_text(step) := step.run if is_string(step.run)
|
|
32
30
|
|
|
33
31
|
else := concat("\n", [s | some s in step.run]) if is_array(step.run)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: StyleLint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- dev
|
|
7
|
+
- main
|
|
8
|
+
paths:
|
|
9
|
+
- '**/*.css'
|
|
10
|
+
- '**/*.scss'
|
|
11
|
+
- '**/*.vue'
|
|
12
|
+
|
|
13
|
+
pull_request:
|
|
14
|
+
branches:
|
|
15
|
+
- dev
|
|
16
|
+
- main
|
|
17
|
+
paths:
|
|
18
|
+
- '**/*.css'
|
|
19
|
+
- '**/*.scss'
|
|
20
|
+
- '**/*.vue'
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: ${{ github.ref }}-${{ github.workflow }}
|
|
24
|
+
cancel-in-progress: true
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
stylelint:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v6
|
|
33
|
+
with:
|
|
34
|
+
persist-credentials: false
|
|
35
|
+
|
|
36
|
+
- uses: ./.github/actions/setup-bun-deps
|
|
37
|
+
|
|
38
|
+
- name: StyleLint
|
|
39
|
+
run: npx stylelint '**/*.{css,scss,vue}' --fix
|
|
@@ -1,49 +1,41 @@
|
|
|
1
|
-
# Порт перевірок `package.json`
|
|
1
|
+
# Порт перевірок `package.json` (style-lint.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "contains": ..., "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/package.json.{contains,snippet}.json.
|
|
5
|
+
# FS-альтернативи (`.stylelintrc.*` файли) + `.stylelintignore` — у JS.
|
|
5
6
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# (зовнішні `.stylelintrc.*` як альтернатива полю; `.stylelintignore`) лишається у JS.
|
|
9
|
-
#
|
|
10
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
11
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
12
|
-
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
7
|
+
# Логіка, що ЛИШАЄТЬСЯ у rego (inverse — не виноситься у template):
|
|
8
|
+
# - `@nitra/stylelint-config` має бути у devDependencies (presence-check).
|
|
13
9
|
package style_lint.package_json
|
|
14
10
|
|
|
15
11
|
import rego.v1
|
|
16
12
|
|
|
17
|
-
# ── deny:
|
|
13
|
+
# ── deny: substring requirements у scripts (contains) ────────────────────
|
|
18
14
|
|
|
19
15
|
deny contains msg if {
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
some script_name, needles in data.template.contains.scripts
|
|
17
|
+
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
18
|
+
some needle in needles
|
|
19
|
+
not contains(actual, needle)
|
|
20
|
+
msg := sprintf("package.json: scripts.%s має містити %q (style-lint.mdc)", [script_name, needle])
|
|
22
21
|
}
|
|
23
22
|
|
|
23
|
+
# ── deny: 2-level snippet walker (для stylelint.extends, якщо поле є) ────
|
|
24
|
+
|
|
24
25
|
deny contains msg if {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
some section, expected_inner in data.template.snippet
|
|
27
|
+
cfg := object.get(input, section, null)
|
|
28
|
+
is_object(cfg)
|
|
29
|
+
some leaf_key, expected_value in expected_inner
|
|
30
|
+
actual := object.get(cfg, leaf_key, null)
|
|
31
|
+
actual != expected_value
|
|
32
|
+
msg := sprintf("package.json: %s.%s має бути %q (style-lint.mdc)", [section, leaf_key, expected_value])
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
# ── deny: @nitra/stylelint-config у devDependencies
|
|
35
|
+
# ── deny: @nitra/stylelint-config у devDependencies (inverse) ────────────
|
|
32
36
|
|
|
33
37
|
deny contains msg if {
|
|
34
38
|
dev := object.get(input, "devDependencies", {})
|
|
35
39
|
not "@nitra/stylelint-config" in object.keys(dev)
|
|
36
40
|
msg := "@nitra/stylelint-config відсутній — bun add -d @nitra/stylelint-config (style-lint.mdc)"
|
|
37
41
|
}
|
|
38
|
-
|
|
39
|
-
# ── deny: поле stylelint.extends = "@nitra/stylelint-config" ──────────────
|
|
40
|
-
#
|
|
41
|
-
# JS-перевірка дозволяє альтернативу: окремий файл `.stylelintrc.*`. Цю частину
|
|
42
|
-
# перевіряємо в JS (FS-вибірка); тут — лише структурна валідація поля, якщо воно є.
|
|
43
|
-
|
|
44
|
-
deny contains msg if {
|
|
45
|
-
cfg := object.get(input, "stylelint", null)
|
|
46
|
-
is_object(cfg)
|
|
47
|
-
object.get(cfg, "extends", null) != "@nitra/stylelint-config"
|
|
48
|
-
msg := "package.json: stylelint.extends має бути \"@nitra/stylelint-config\" (style-lint.mdc)"
|
|
49
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "recommendations": ["stylelint.vscode-stylelint"] }
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
# Перевірка `.vscode/extensions.json` для style-lint (style-lint.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# --namespace style_lint.vscode_extensions
|
|
6
|
-
#
|
|
7
|
-
# Canonical (style-lint.mdc):
|
|
8
|
-
# { "recommendations": ["stylelint.vscode-stylelint"] }
|
|
9
|
-
#
|
|
10
|
-
# Канон задає мінімум — `recommendations` має МІСТИТИ `stylelint.vscode-stylelint`;
|
|
11
|
-
# додаткові записи (від інших правил — markdownlint, oxc тощо) дозволені.
|
|
12
|
-
#
|
|
13
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
14
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`.
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/extensions.json.snippet.json.
|
|
15
5
|
package style_lint.vscode_extensions
|
|
16
6
|
|
|
17
7
|
import rego.v1
|
|
18
8
|
|
|
19
9
|
deny contains msg if {
|
|
20
|
-
|
|
21
|
-
not
|
|
22
|
-
msg := ".vscode/extensions.json: recommendations має містити
|
|
10
|
+
some rec in data.template.snippet.recommendations
|
|
11
|
+
not rec in {r | some r in object.get(input, "recommendations", [])}
|
|
12
|
+
msg := sprintf(".vscode/extensions.json: recommendations має містити %q (style-lint.mdc)", [rec])
|
|
23
13
|
}
|
|
@@ -1,24 +1,15 @@
|
|
|
1
1
|
# Перевірка `.vscode/settings.json` для style-lint (style-lint.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# Canonical (style-lint.mdc): вимкнути вбудовану валідацію CSS/SCSS/Less, щоб
|
|
8
|
-
# stylelint був єдиним джерелом діагностики.
|
|
9
|
-
# { "css.validate": false, "less.validate": false, "scss.validate": false }
|
|
10
|
-
#
|
|
11
|
-
# `editor.codeActionsOnSave` у каноні є, але це smell-test — навмисно не deny,
|
|
12
|
-
# щоб не падати на пакетах, які мають свій codeActionsOnSave-конфіг.
|
|
13
|
-
#
|
|
14
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
15
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`.
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/settings.json.snippet.json.
|
|
5
|
+
# Top-level літеральні keys — leaf-by-leaf walker.
|
|
16
6
|
package style_lint.vscode_settings
|
|
17
7
|
|
|
18
8
|
import rego.v1
|
|
19
9
|
|
|
20
10
|
deny contains msg if {
|
|
21
|
-
some key in
|
|
22
|
-
object.get(input, key, null)
|
|
23
|
-
|
|
11
|
+
some key, expected_value in data.template.snippet
|
|
12
|
+
actual := object.get(input, key, null)
|
|
13
|
+
actual != expected_value
|
|
14
|
+
msg := sprintf(".vscode/settings.json: \"%s\" має бути %v (style-lint.mdc)", [key, expected_value])
|
|
24
15
|
}
|
|
@@ -1,91 +1,71 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Перевірка `.cspell.json` (text.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ..., "contains": ..., "deny": ... } }
|
|
4
|
+
# Структура --data сформована з template/.cspell.json.{snippet,contains,deny}.json.
|
|
5
5
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# (text.mdc).
|
|
9
|
-
#
|
|
10
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
11
|
-
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
12
|
-
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
6
|
+
# Логіка, що ЛИШАЄТЬСЯ у rego (inverse — не виноситься у template):
|
|
7
|
+
# - `language` має бути присутнє (presence-only).
|
|
13
8
|
package text.cspell
|
|
14
9
|
|
|
15
10
|
import rego.v1
|
|
16
11
|
|
|
17
|
-
# ──
|
|
12
|
+
# ── deny: top-level snippet leafs (version etc) ──────────────────────────
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"*.svg",
|
|
27
|
-
"**/k8s/**/*.yaml",
|
|
14
|
+
deny contains msg if {
|
|
15
|
+
some key, expected_value in data.template.snippet
|
|
16
|
+
not is_array(expected_value)
|
|
17
|
+
not is_object(expected_value)
|
|
18
|
+
actual := object.get(input, key, null)
|
|
19
|
+
actual != expected_value
|
|
20
|
+
msg := sprintf(".cspell.json: %s має бути %v (text.mdc)", [key, expected_value])
|
|
28
21
|
}
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
legacy_dict_marker := "@cspell/dict-"
|
|
33
|
-
|
|
34
|
-
# Шаблон повідомлення про заборонений імпорт `@cspell/dict-*` — через `concat`
|
|
35
|
-
# для regal style/line-length.
|
|
36
|
-
legacy_dict_import_template := concat(" ", [
|
|
37
|
-
".cspell.json не має імпортувати @cspell/dict-* —",
|
|
38
|
-
"використовуй лише @nitra/cspell-dict (знайдено: %s) (text.mdc)",
|
|
39
|
-
])
|
|
40
|
-
|
|
41
|
-
# ── deny: version / language ──────────────────────────────────────────────
|
|
23
|
+
# ── deny: ignorePaths subset-of ──────────────────────────────────────────
|
|
42
24
|
|
|
43
25
|
deny contains msg if {
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
some field, expected_values in data.template.snippet
|
|
27
|
+
is_array(expected_values)
|
|
28
|
+
is_array(object.get(input, field, null))
|
|
29
|
+
actual_set := {v | some v in input[field]}
|
|
30
|
+
some required in expected_values
|
|
31
|
+
not required in actual_set
|
|
32
|
+
msg := sprintf(".cspell.json %s: додай %q (text.mdc)", [field, required])
|
|
46
33
|
}
|
|
47
34
|
|
|
35
|
+
# ── deny: language presence (inverse, in rego) ───────────────────────────
|
|
36
|
+
|
|
48
37
|
deny contains msg if {
|
|
49
38
|
not object.get(input, "language", false)
|
|
50
39
|
msg := ".cspell.json: відсутнє поле language (text.mdc)"
|
|
51
40
|
}
|
|
52
41
|
|
|
53
|
-
# ── deny:
|
|
42
|
+
# ── deny: import substrings required (contains) ─────────────────────────
|
|
54
43
|
|
|
55
44
|
deny contains msg if {
|
|
56
|
-
|
|
45
|
+
some field, needles in data.template.contains
|
|
46
|
+
imports := object.get(input, field, [])
|
|
57
47
|
is_array(imports)
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
some needle in needles
|
|
49
|
+
not has_substring_in_array(imports, needle)
|
|
50
|
+
msg := sprintf(".cspell.json: %s має містити %q (text.mdc)", [field, needle])
|
|
60
51
|
}
|
|
61
52
|
|
|
53
|
+
# ── deny: import substrings forbidden ────────────────────────────────────
|
|
54
|
+
|
|
62
55
|
deny contains msg if {
|
|
56
|
+
some forbidden, reason in data.template.deny["import-substrings"]
|
|
63
57
|
imports := object.get(input, "import", [])
|
|
64
58
|
is_array(imports)
|
|
65
59
|
some imp in imports
|
|
66
60
|
is_string(imp)
|
|
67
|
-
contains(imp,
|
|
68
|
-
msg := sprintf(
|
|
61
|
+
contains(imp, forbidden)
|
|
62
|
+
msg := sprintf(".cspell.json import містить заборонений %q — %s", [imp, reason])
|
|
69
63
|
}
|
|
70
64
|
|
|
71
|
-
# ──
|
|
65
|
+
# ── helpers ──────────────────────────────────────────────────────────────
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
deny contains msg if {
|
|
79
|
-
is_array(input.ignorePaths)
|
|
80
|
-
some path in required_ignore_paths
|
|
81
|
-
not path in {p | some p in input.ignorePaths}
|
|
82
|
-
msg := sprintf(".cspell.json ignorePaths: додай %q (text.mdc)", [path])
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
# ── helpers ────────────────────────────────────────────────────────────────
|
|
86
|
-
|
|
87
|
-
has_nitra_dict_import(imports) if {
|
|
88
|
-
some imp in imports
|
|
89
|
-
is_string(imp)
|
|
90
|
-
contains(imp, nitra_cspell_dict_marker)
|
|
67
|
+
has_substring_in_array(arr, needle) if {
|
|
68
|
+
some item in arr
|
|
69
|
+
is_string(item)
|
|
70
|
+
contains(item, needle)
|
|
91
71
|
}
|