@nitra/cursor 1.13.83 → 1.13.85
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/.claude-template/commands/n-check.md +2 -2
- package/CHANGELOG.md +56 -27
- package/README.md +10 -10
- package/bin/n-cursor.js +40 -60
- package/package.json +1 -1
- package/rules/abie/abie.mdc +2 -2
- package/rules/abie/fix.mjs +5 -1
- package/rules/adr/fix.mjs +5 -1
- package/rules/adr/js/hooks/check.mjs +1 -1
- package/rules/bun/bun.mdc +1 -1
- package/rules/bun/fix.mjs +5 -1
- package/rules/bun/js/layout/check.mjs +1 -1
- package/rules/capacitor/fix.mjs +5 -1
- package/rules/capacitor/policy/package_json/package_json.rego +3 -3
- package/rules/changelog/changelog.mdc +1 -1
- package/rules/changelog/fix.mjs +5 -1
- package/rules/ci4/ci4.mdc +1 -1
- package/rules/ci4/fix.mjs +5 -1
- package/rules/docker/docker.mdc +6 -6
- package/rules/docker/fix.mjs +5 -1
- package/rules/docker/lint/lint.mjs +10 -3
- package/rules/docker/policy/package_json/package_json.rego +1 -1
- package/rules/efes/efes.mdc +1 -1
- package/rules/efes/fix.mjs +5 -1
- package/rules/feedback/feedback.mdc +2 -2
- package/rules/feedback/fix.mjs +5 -1
- package/rules/ga/fix.mjs +5 -1
- package/rules/ga/lint/lint.mjs +5 -5
- package/rules/ga/policy/workflow_common/workflow_common.rego +1 -1
- package/rules/graphql/fix.mjs +5 -1
- package/rules/graphql/policy/vscode_extensions/vscode_extensions.rego +2 -2
- package/rules/hasura/fix.mjs +5 -1
- package/rules/image-avif/fix.mjs +5 -1
- package/rules/image-avif/image-avif.mdc +1 -1
- package/rules/image-avif/js/avif_generation/check.mjs +1 -1
- package/rules/image-compress/fix.mjs +5 -1
- package/rules/image-compress/js/package_setup/check.mjs +1 -1
- package/rules/js-bun-db/fix.mjs +5 -1
- package/rules/js-bun-redis/fix.mjs +5 -1
- package/rules/js-lint/fix.mjs +5 -1
- package/rules/js-lint/js/tooling/check.mjs +2 -2
- package/rules/js-lint/js-lint.mdc +1 -1
- package/rules/js-mssql/fix.mjs +5 -1
- package/rules/js-mssql/policy/package_json/package_json.rego +2 -2
- package/rules/js-run/fix.mjs +5 -1
- package/rules/js-run/js/runtime/check.mjs +3 -3
- package/rules/k8s/fix.mjs +5 -1
- package/rules/k8s/js/manifests/check.mjs +1 -1
- package/rules/k8s/k8s.mdc +12 -12
- package/rules/k8s/lint/lint.mjs +12 -5
- package/rules/k8s/policy/base_kustomization/base_kustomization.rego +3 -3
- package/rules/k8s/policy/base_manifest/base_manifest.rego +2 -2
- package/rules/k8s/policy/gateway/gateway.rego +2 -2
- package/rules/k8s/policy/hasura_configmap/hasura_configmap.rego +3 -3
- package/rules/k8s/policy/hasura_httproute/hasura_httproute.rego +1 -1
- package/rules/k8s/policy/hpa_pdb/hpa_pdb.rego +1 -1
- package/rules/k8s/policy/kustomization/kustomization.rego +2 -2
- package/rules/k8s/policy/manifest/manifest.rego +4 -4
- package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml.rego +2 -2
- package/rules/k8s/policy/svc_yaml/svc_yaml.rego +2 -2
- package/rules/nginx-default-tpl/fix.mjs +5 -1
- package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions.rego +2 -2
- package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings.rego +1 -1
- package/rules/npm-module/fix.mjs +5 -1
- package/rules/npm-module/js/package_structure/check.mjs +2 -2
- package/rules/php/fix.mjs +5 -1
- package/rules/php/js/tooling/check.mjs +2 -2
- package/rules/rego/fix.mjs +5 -1
- package/rules/rego/lint/lint.mjs +12 -2
- package/rules/security/fix.mjs +5 -1
- package/rules/security/security.mdc +1 -1
- package/rules/style-lint/fix.mjs +5 -1
- package/rules/style-lint/js/tooling/check.mjs +2 -2
- package/rules/tauri/fix.mjs +5 -1
- package/rules/tauri/js/tooling/check.mjs +1 -1
- package/rules/tauri/policy/vscode_extensions/vscode_extensions.rego +2 -2
- package/rules/test/fix.mjs +5 -1
- package/rules/test/test.mdc +1 -1
- package/rules/text/fix.mjs +5 -1
- package/rules/text/js/formatting/check.mjs +2 -2
- package/rules/text/lint/lint.mjs +9 -2
- package/rules/text/text.mdc +1 -1
- package/rules/vue/fix.mjs +5 -1
- package/rules/vue/js/packages/check.mjs +1 -1
- package/rules/vue/policy/package_json/package_json.rego +1 -1
- package/rules/vue/vue.mdc +1 -1
- package/schemas/n-cursor.json +1 -1
- package/scripts/build-agents-commands.mjs +1 -1
- package/scripts/claude-stop-hook.mjs +1 -1
- package/scripts/utils/discover-check-rules-from-cursor.mjs +1 -1
- package/scripts/utils/read-n-cursor-config-lite.mjs +59 -0
- package/scripts/utils/run-rule-cli.mjs +37 -0
- package/scripts/utils/run-standard-rule.mjs +12 -3
- package/scripts/utils/with-lock.mjs +2 -2
- package/skills/fix/SKILL.md +5 -5
- package/skills/lint/SKILL.md +1 -1
package/rules/abie/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
package/rules/adr/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -116,7 +116,7 @@ async function checkHookScript(reporter, scriptName) {
|
|
|
116
116
|
function checkProjectSettings(reporter) {
|
|
117
117
|
const { pass, fail } = reporter
|
|
118
118
|
if (existsSync(PROJECT_SETTINGS_PATH)) {
|
|
119
|
-
pass(`${PROJECT_SETTINGS_PATH} є (Stop-hook перевіряє npx @nitra/cursor
|
|
119
|
+
pass(`${PROJECT_SETTINGS_PATH} є (Stop-hook перевіряє npx @nitra/cursor fix → adr.settings_json)`)
|
|
120
120
|
} else {
|
|
121
121
|
fail(`${PROJECT_SETTINGS_PATH} не існує — запусти \`npx @nitra/cursor\``)
|
|
122
122
|
}
|
package/rules/bun/bun.mdc
CHANGED
|
@@ -72,4 +72,4 @@ FROM oven/bun:alpine AS build-env
|
|
|
72
72
|
|
|
73
73
|
Якщо в **`.n-cursor.json`** у масиві **`rules`** є **`docker`**, у кореневому `package.json` **обов'язково** скрипт **`lint-docker`** (див. **`docker.mdc`**) і рядок **`bun run lint-docker`** у **`lint`**. Якщо є **`k8s`** — **обов'язково** **`lint-k8s`** і **`bun run lint-k8s`** у **`lint`** (див. **`k8s.mdc`**).
|
|
74
74
|
|
|
75
|
-
**Зворотній інваріант:** якщо правила **немає** в `rules` (або воно явно перенесене в **`disable-rules`**), скрипту **`lint-<id>`** у кореневому `package.json` бути **не може**, і ланцюжок агрегованого **`scripts.lint`** не має містити **`bun run lint-<id>`**. Інакше `bun run lint` падатиме на вимкненому правилі — `n-cursor lint-<id>` ігнорує `.n-cursor.json` і обходить дерево незалежно від `rules`/`disable-rules`. Для скриптів із кількома власниками (як **`lint-image`** — обслуговує і **`image-avif`**, і **`image-compress`**) скрипт лишається дозволеним, поки активний **хоч один** власник; зворотній інваріант тригериться лише коли в `rules` немає **жодного** з них. Перевірка — **`npx @nitra/cursor
|
|
75
|
+
**Зворотній інваріант:** якщо правила **немає** в `rules` (або воно явно перенесене в **`disable-rules`**), скрипту **`lint-<id>`** у кореневому `package.json` бути **не може**, і ланцюжок агрегованого **`scripts.lint`** не має містити **`bun run lint-<id>`**. Інакше `bun run lint` падатиме на вимкненому правилі — `n-cursor lint-<id>` ігнорує `.n-cursor.json` і обходить дерево незалежно від `rules`/`disable-rules`. Для скриптів із кількома власниками (як **`lint-image`** — обслуговує і **`image-avif`**, і **`image-compress`**) скрипт лишається дозволеним, поки активний **хоч один** власник; зворотній інваріант тригериться лише коли в `rules` немає **жодного** з них. Перевірка — **`npx @nitra/cursor fix bun`**.
|
package/rules/bun/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -183,7 +183,7 @@ export async function check() {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
if (existsSync('bunfig.toml')) {
|
|
186
|
-
pass('bunfig.toml є (структуру перевіряє npx @nitra/cursor
|
|
186
|
+
pass('bunfig.toml є (структуру перевіряє npx @nitra/cursor fix → bun.bunfig)')
|
|
187
187
|
} else {
|
|
188
188
|
fail('Відсутній bunfig.toml — створи з [install] linker = "hoisted" (bun.mdc)')
|
|
189
189
|
}
|
package/rules/capacitor/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Порт перевірки версії `@capacitor/core` з `npm/scripts/
|
|
1
|
+
# Порт перевірки версії `@capacitor/core` з `npm/scripts/rules/capacitor/fix.mjs`
|
|
2
2
|
# (capacitor.mdc) — мінімальна мажорна версія = 8.
|
|
3
3
|
#
|
|
4
4
|
# Запуск (локально, у пакеті з Capacitor):
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
# Підтримує `^8.0.0`, `>=8`, `8.x`, `workspace:*` тощо.
|
|
11
11
|
#
|
|
12
12
|
# Цей порт спрощує JS-логіку — повна семантика OR-діапазонів (`a || b`) і нижня
|
|
13
|
-
# межа діапазону лишається в JS (`
|
|
14
|
-
# JS-перевірка лишилась authoritative й бігає через `npx @nitra/cursor
|
|
13
|
+
# межа діапазону лишається в JS (`rules/capacitor/fix.mjs`: `capacitorVersionRangeMinMajor`).
|
|
14
|
+
# JS-перевірка лишилась authoritative й бігає через `npx @nitra/cursor fix capacitor`;
|
|
15
15
|
# ця Rego — швидкий gate для одиничного `package.json` (наприклад через IDE).
|
|
16
16
|
#
|
|
17
17
|
# FS-сканування пакетів через workspaces, iOS-специфічна логіка (Podfile), вибір
|
|
@@ -10,7 +10,7 @@ alwaysApply: true
|
|
|
10
10
|
|
|
11
11
|
1. **`version`** у `<ws>/package.json` (або `[project].version` у `pyproject.toml`) → **patch +1** відносно `git show HEAD:<ws>/package.json`, якщо ще не піднято.
|
|
12
12
|
2. **`CHANGELOG.md`** того workspace → **нова** секція `## [версія] - YYYY-MM-DD` **зверху** (не bullet-и в стару версію).
|
|
13
|
-
3. **`npx @nitra/cursor
|
|
13
|
+
3. **`npx @nitra/cursor fix changelog`** (у репо `@nitra/cursor`: `bun ./npm/bin/n-cursor.js check changelog`) → exit **`0`**.
|
|
14
14
|
|
|
15
15
|
**Тригер шляхів (приклади):** `npm/**`, `packages/foo/**`, будь-який каталог з власним `package.json` / `pyproject.toml`, куди потрапили правки.
|
|
16
16
|
|
package/rules/changelog/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
package/rules/ci4/ci4.mdc
CHANGED
|
@@ -30,7 +30,7 @@ RAG витягує **фрагменти**, не цілі документи. Т
|
|
|
30
30
|
|
|
31
31
|
## Docs-as-Code
|
|
32
32
|
|
|
33
|
-
Документація живе у Git поруч із кодом, проходить **той самий Code Review**, версіонується і автоматично перевіряється у CI (лінтери Markdown, валідатори посилань, `npx @nitra/cursor
|
|
33
|
+
Документація живе у Git поруч із кодом, проходить **той самий Code Review**, версіонується і автоматично перевіряється у CI (лінтери Markdown, валідатори посилань, `npx @nitra/cursor fix`). Биті посилання й документація, що «не компілюється», — **блокуючий баг**, не косметика.
|
|
34
34
|
|
|
35
35
|
## Трасування як документація недетермінованої поведінки
|
|
36
36
|
|
package/rules/ci4/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
package/rules/docker/docker.mdc
CHANGED
|
@@ -7,7 +7,7 @@ alwaysApply: false
|
|
|
7
7
|
|
|
8
8
|
# Docker — hadolint
|
|
9
9
|
|
|
10
|
-
Для образів з Docker Hub — **`oven/bun`**, **`alpine`**, **`nginxinc/nginx-unprivileged`**, **`node`** — у **`FROM`** треба вказувати дзеркало GCR, а не pull напряму з Hub: **`mirror.gcr.io/oven/bun`**, **`mirror.gcr.io/library/alpine`**, **`mirror.gcr.io/nginxinc/nginx-unprivileged`**, **`mirror.gcr.io/library/node`**. Перевіряє **`
|
|
10
|
+
Для образів з Docker Hub — **`oven/bun`**, **`alpine`**, **`nginxinc/nginx-unprivileged`**, **`node`** — у **`FROM`** треба вказувати дзеркало GCR, а не pull напряму з Hub: **`mirror.gcr.io/oven/bun`**, **`mirror.gcr.io/library/alpine`**, **`mirror.gcr.io/nginxinc/nginx-unprivileged`**, **`mirror.gcr.io/library/node`**. Перевіряє **`rules/docker/fix.mjs`**, деталі в **`npm/rules/docker/js/lint/docker-mirror.mjs`**.
|
|
11
11
|
|
|
12
12
|
Також Dockerfile/Containerfile **має бути multistage build**: окремий build stage (залежності/компіляція) і окремий runtime stage. У фінальному stage дозволені лише мінімальні базові образи:
|
|
13
13
|
|
|
@@ -90,20 +90,20 @@ CMD ["./app"]
|
|
|
90
90
|
|
|
91
91
|
## Область
|
|
92
92
|
|
|
93
|
-
- Усі файли з іменем **`Dockerfile`** або **`Dockerfile.*`** (наприклад `Dockerfile.prod`) у репозиторії, крім ігнорованих каталогів (`node_modules`, `.git`, `dist`, …) — як у **`
|
|
93
|
+
- Усі файли з іменем **`Dockerfile`** або **`Dockerfile.*`** (наприклад `Dockerfile.prod`) у репозиторії, крім ігнорованих каталогів (`node_modules`, `.git`, `dist`, …) — як у **`rules/docker/fix.mjs`**.
|
|
94
94
|
- Також скрипт перевірки обробляє **`Containerfile`** та **`Containerfile.*`** (Podman / альтернативні імена), навіть якщо glob правила спрацьовує переважно на `Dockerfile*`.
|
|
95
95
|
|
|
96
96
|
## lint-docker
|
|
97
97
|
|
|
98
98
|
CLI **`hadolint`** приймає лише **явні шляхи** (`[DOCKERFILE...]` у **`hadolint --help`**); обхід репозиторію робить CLI **`n-cursor lint-docker`** (реалізація — **`npm/rules/docker/js/run.mjs`**).
|
|
99
99
|
|
|
100
|
-
**Область lint-docker (вужча, ніж `check docker`):** лише файли з іменем **`Dockerfile`** та **`*.Dockerfile`** (суфікс **`.dockerfile`** без урахування регістру, наприклад **`api.Dockerfile`**). Файли **`Dockerfile.prod`**, **`Containerfile`** тощо **не** входять у **`lint-docker`**; їх ловить **`check docker`** (`
|
|
100
|
+
**Область lint-docker (вужча, ніж `check docker`):** лише файли з іменем **`Dockerfile`** та **`*.Dockerfile`** (суфікс **`.dockerfile`** без урахування регістру, наприклад **`api.Dockerfile`**). Файли **`Dockerfile.prod`**, **`Containerfile`** тощо **не** входять у **`lint-docker`**; їх ловить **`check docker`** (`rules/docker/fix.mjs`).
|
|
101
101
|
|
|
102
|
-
Обхід: **`walkDir`** з тими самими пропусками каталогів, що й **`
|
|
102
|
+
Обхід: **`walkDir`** з тими самими пропусками каталогів, що й **`rules/docker/fix.mjs`**. Виклик **`hadolint`**: **`PATH`**, інакше **`docker run`** — спільна логіка **`npm/rules/docker/js/lint/docker-hadolint.mjs`**.
|
|
103
103
|
|
|
104
104
|
- Канон `package.json#scripts.lint-docker`: [package.json.snippet.json](./policy/package_json/template/package.json.snippet.json)
|
|
105
105
|
|
|
106
|
-
Якщо правило **`docker`** підключено в **`.n-cursor.json`** (масив **`rules`**), у **кореневому** `package.json` **обов'язково** мають бути скрипт **`lint-docker`** і виклик **`bun run lint-docker`** у агрегованому **`lint`** (див. **`bun.mdc`**). Це перевіряє **`npx @nitra/cursor
|
|
106
|
+
Якщо правило **`docker`** підключено в **`.n-cursor.json`** (масив **`rules`**), у **кореневому** `package.json` **обов'язково** мають бути скрипт **`lint-docker`** і виклик **`bun run lint-docker`** у агрегованому **`lint`** (див. **`bun.mdc`**). Це перевіряє **`npx @nitra/cursor fix bun`**.
|
|
107
107
|
|
|
108
108
|
Додай workflow **`.github/workflows/lint-docker.yml`** (гілки **`dev`** і **`main`**, лише **`.yml`**, узгоджено з **`ga.mdc`**):
|
|
109
109
|
|
|
@@ -116,7 +116,7 @@ CLI **`hadolint`** приймає лише **явні шляхи** (`[DOCKERFILE
|
|
|
116
116
|
## Запуск
|
|
117
117
|
|
|
118
118
|
1. **`bun run lint-docker`** — **`run-docker.mjs`**: **`Dockerfile`** та **`*.Dockerfile`** (див. **`lint-docker`**); у CI встанови hadolint (приклад у workflow).
|
|
119
|
-
2. **`npx @nitra/cursor
|
|
119
|
+
2. **`npx @nitra/cursor fix docker`** — **`rules/docker/fix.mjs`**, виклик hadolint як у **`docker-hadolint.mjs`** (**`PATH`** або **`docker run`** з **`hadolint/hadolint:v2.12.0`**).
|
|
120
120
|
3. Кореневий **`.hadolint.yaml`**: вимкнення правил, trusted registries — [документація](https://github.com/hadolint/hadolint#configure). Щоб не додавати **`# hadolint ignore=DL3007`** у кожному **`FROM`** з **`:latest`**, у корені репозиторію задати глобально:
|
|
121
121
|
|
|
122
122
|
```yaml title=".hadolint.yaml"
|
package/rules/docker/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -14,6 +14,7 @@ import { lintDockerfileWithHadolint, posixRel } from '../js/lint/docker-hadolint
|
|
|
14
14
|
import { createCheckReporter } from '../../../scripts/utils/check-reporter.mjs'
|
|
15
15
|
import { loadCursorIgnorePaths } from '../../../scripts/utils/load-cursor-config.mjs'
|
|
16
16
|
import { walkDir } from '../../../scripts/utils/walkDir.mjs'
|
|
17
|
+
import { withLock } from '../../../scripts/utils/with-lock.mjs'
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Чи входить файл до набору lint-docker: Dockerfile або *.Dockerfile (*.dockerfile).
|
|
@@ -46,11 +47,10 @@ export async function findLintDockerfilePaths(root, ignorePaths = []) {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
|
-
*
|
|
50
|
-
* Експортовано як `runLintDocker` — використовується з `bin/n-cursor.js` як підкоманда `lint-docker`.
|
|
50
|
+
* Внутрішні кроки `lint-docker` без локу: hadolint по Dockerfile та *.Dockerfile.
|
|
51
51
|
* @returns {Promise<number>} 0 — OK, 1 — зауваження або помилка
|
|
52
52
|
*/
|
|
53
|
-
|
|
53
|
+
async function runLintDockerSteps() {
|
|
54
54
|
const reporter = createCheckReporter()
|
|
55
55
|
const { pass, fail } = reporter
|
|
56
56
|
|
|
@@ -80,6 +80,13 @@ export async function runLintDocker() {
|
|
|
80
80
|
return reporter.getExitCode()
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Публічна CLI-форма: серіалізує через `withLock('lint-docker')` + дедуп за станом git-дерева.
|
|
85
|
+
* Експортовано як `runLintDocker` — використовується з `bin/n-cursor.js` як підкоманда `lint-docker`.
|
|
86
|
+
* @returns {Promise<number>} код виходу
|
|
87
|
+
*/
|
|
88
|
+
export const runLintDocker = () => withLock('lint-docker', runLintDockerSteps)
|
|
89
|
+
|
|
83
90
|
if (isRunAsCli()) {
|
|
84
91
|
process.exitCode = await runLintDocker()
|
|
85
92
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
4
|
# Перевіряє ЛИШЕ зміст значення `scripts.lint-docker`, якщо ключ присутній.
|
|
5
5
|
# Умовну обовʼязковість (правило `docker` у `.n-cursor.json` → `scripts.lint-docker`
|
|
6
|
-
# зобовʼязаний існувати) перевіряє `
|
|
6
|
+
# зобовʼязаний існувати) перевіряє `rules/bun/fix.mjs` через cross-file логіку.
|
|
7
7
|
package docker.package_json
|
|
8
8
|
|
|
9
9
|
import rego.v1
|
package/rules/efes/efes.mdc
CHANGED
|
@@ -16,7 +16,7 @@ bun add -d @nitra/efes-docs
|
|
|
16
16
|
|
|
17
17
|
## Швидкий gate через conftest (Rego)
|
|
18
18
|
|
|
19
|
-
Пер-документні перевірки efes — rego-полісі у **`npm/rules/efes/policy/`** (запускається через **`npx @nitra/cursor
|
|
19
|
+
Пер-документні перевірки efes — rego-полісі у **`npm/rules/efes/policy/`** (запускається через **`npx @nitra/cursor fix efes`**; синтаксичний lint — через **`bun run lint-rego`**). Деталі шаблону — у **conftest.mdc** / **n-rego.mdc**.
|
|
20
20
|
|
|
21
21
|
Пакети (директорія в **`npm/rules/efes/policy/`** → namespace → що перевіряє):
|
|
22
22
|
|
package/rules/efes/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -4,7 +4,7 @@ alwaysApply: true
|
|
|
4
4
|
version: '1.0'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Правило про **зворотний звʼязок до пакета `@nitra/cursor`**. Виконуючи скіл пакета (`n-lint`, `n-fix`, `n-taze`, `n-adr-normalize`, `n-llm-patch`, `n-publish-telegram`, `mdc-check`), агент проходить крізь правила `.cursor/rules/`, інструкції `SKILL.md` і програмні перевірки `npx @nitra/cursor
|
|
7
|
+
Правило про **зворотний звʼязок до пакета `@nitra/cursor`**. Виконуючи скіл пакета (`n-lint`, `n-fix`, `n-taze`, `n-adr-normalize`, `n-llm-patch`, `n-publish-telegram`, `mdc-check`), агент проходить крізь правила `.cursor/rules/`, інструкції `SKILL.md` і програмні перевірки `npx @nitra/cursor fix`. Саме тут видно, що в пакеті недопрацьовано: неоднозначна інструкція, відсутня перевірка, хибне спрацювання, порушення без автофіксу. Ця інформація цінна для розробників пакета, але без явного кроку зникає разом із сесією.
|
|
8
8
|
|
|
9
9
|
## Коли застосовувати
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ version: '1.0'
|
|
|
17
17
|
**Тертя** — усе, що ускладнило роботу скілу й стосується самого пакета `@nitra/cursor`, а не коду користувацького проєкту:
|
|
18
18
|
|
|
19
19
|
- неоднозначна чи неповна інструкція в `SKILL.md` або `.mdc`;
|
|
20
|
-
- правило вимагає поведінку, яку можна перевірити програмно, але `check
|
|
20
|
+
- правило вимагає поведінку, яку можна перевірити програмно, але програмної перевірки (`rules/<id>/js/<concern>/check.mjs` або `rules/<id>/policy/<concern>/*.rego`) для неї немає;
|
|
21
21
|
- хибне спрацювання перевірки (false positive);
|
|
22
22
|
- порушення, яке правило вимагає виправляти вручну, хоча реальний автофікс можливий;
|
|
23
23
|
- повторюваний патерн, який варто закодувати в правило чи скіл.
|
package/rules/feedback/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
package/rules/ga/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
package/rules/ga/lint/lint.mjs
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* CLI-обгортка над канонічним `lint-ga` (ga.mdc): робить preflight на `shellcheck`, `uv` (для `uvx`)
|
|
3
3
|
* і `conftest` (для rego-полісі у `check-ga`),
|
|
4
4
|
* тоді послідовно виконує `bunx github-actionlint`, `uvx zizmor --offline --collect=workflows .` і
|
|
5
|
-
* делегує до `
|
|
5
|
+
* делегує до `rules/ga/fix.mjs::check()` — там і Rego-частина (через `runConftestBatch`),
|
|
6
6
|
* і JS cross-file перевірки правил `ga.mdc`.
|
|
7
7
|
*
|
|
8
8
|
* Plan B-патерн (rego-authoritative): Rego-полісі (`npm/policy/ga/`) запускає вже сам
|
|
9
|
-
* `
|
|
9
|
+
* `rules/ga/fix.mjs::check()` як перший крок — `lint-ga.mjs` про це не знає. Раніше `lint-ga.mjs` сам
|
|
10
10
|
* спавнив conftest для `ga.<name>` per-workflow і `ga.workflow_common` (PoC); тепер ця логіка
|
|
11
|
-
* централізована у `
|
|
11
|
+
* централізована у `rules/ga/fix.mjs`, тож одне джерело істини, без дублювання між
|
|
12
12
|
* `lint-ga` і `npx \@nitra/cursor check ga`.
|
|
13
13
|
*
|
|
14
14
|
* Без preflight `actionlint` (через `bunx github-actionlint`) мовчки пропускає shell-перевірки в
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* `uv` потрібен для `uvx zizmor`. Якщо його нема — `uvx zizmor` падає неінформативно («command not
|
|
19
19
|
* found»); підказка з командою встановлення коротша й корисніша.
|
|
20
20
|
*
|
|
21
|
-
* `conftest` потрібен для `
|
|
21
|
+
* `conftest` потрібен для `rules/ga/fix.mjs::runAllGaRego` (`runConftestBatch`). Без preflight крок
|
|
22
22
|
* check-ga кидає виняток, який глобальний `catch` у `bin/n-cursor.js` раніше ковтав без логу —
|
|
23
23
|
* локально це виглядало як мовчазний exit 1.
|
|
24
24
|
*
|
|
@@ -137,7 +137,7 @@ function preflight(dep) {
|
|
|
137
137
|
* 1) preflight: `shellcheck`, `uv` (для `uvx zizmor`) і `conftest` (для check-ga); відсутній → exit 1;
|
|
138
138
|
* 2) `bunx github-actionlint`;
|
|
139
139
|
* 3) `uvx zizmor --offline --collect=workflows .`;
|
|
140
|
-
* 4) `
|
|
140
|
+
* 4) `rules/ga/fix.mjs::check()` — Rego-полісі (батч conftest з `npm/policy/ga/`) + JS cross-file
|
|
141
141
|
* перевірки правил `ga.mdc`. Це **те саме**, що робить `npx \@nitra/cursor check ga`, тож
|
|
142
142
|
* `lint-ga` тепер є суперсетом перевірки правила: external-tools + check.
|
|
143
143
|
*
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Порт `verifyNoDirectBunOrCache`, `verifyNoRunShellLineContinuationBackslash`,
|
|
4
4
|
# `verifyCheckoutBeforeLocalSetupBunDeps` та `validateConcurrencyOnRoot` з
|
|
5
|
-
# `npm/scripts/
|
|
5
|
+
# `npm/scripts/rules/ga/fix.mjs`. На відміну від `lint_ga`/`clean_ga_workflows`/
|
|
6
6
|
# `clean_merged_branch`/`git_ai`, цей пакет не привʼязаний до конкретного
|
|
7
7
|
# workflow — `conftest test` запускається на кожному файлі окремо з
|
|
8
8
|
# `--namespace ga.workflow_common`, і `input` — це окремий розпарсений YAML.
|
package/rules/graphql/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Перевірка `.vscode/extensions.json` для graphql (graphql.mdc).
|
|
2
2
|
#
|
|
3
|
-
# Викликається з `
|
|
3
|
+
# Викликається з `rules/graphql/fix.mjs` через `runConftestBatch` лише ПІСЛЯ того,
|
|
4
4
|
# як JS виявив `gql\`…\`` tagged template literal у джерелах (умовне правило).
|
|
5
|
-
# Тому без `target.json` поруч (не auto-discoverable через `n-cursor
|
|
5
|
+
# Тому без `target.json` поруч (не auto-discoverable через `n-cursor fix`) —
|
|
6
6
|
# інакше були б false-positive порушення на проєктах без gql.
|
|
7
7
|
#
|
|
8
8
|
# Canonical (graphql.mdc):
|
package/rules/hasura/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
package/rules/image-avif/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -5,7 +5,7 @@ globs: "**/*.{png,jpg,jpeg,gif,avif,vue,html}"
|
|
|
5
5
|
alwaysApply: false
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
AVIF-двійники (`<name>.<ext>.avif`) генерує **виключно** `npx @nitra/cursor
|
|
8
|
+
AVIF-двійники (`<name>.<ext>.avif`) генерує **виключно** `npx @nitra/cursor fix image-avif` — у `lint-image` прапорець `--avif` заборонений (це валідує правило `image-compress`). Перевірка робить чотири кроки в порядку:
|
|
9
9
|
|
|
10
10
|
1. **Pre-scan**: шукає у `.vue`/`.html` хоча б одне raster-посилання, яке потенційно треба переписати на AVIF-двійник (`import x from '...png'` або `<img src="...png" />`). Пакети з opt-out `disable-avif: true` пропускаються. **Якщо жодного raster-посилання не знайдено — `check image-avif` завершується успіхом одразу: ні `npx --avif`, ні rewrite, ні cleanup-сиріт не виконуються** (нічого було б змінювати). Так уникаємо дорогого `npx @nitra/minify-image` у проєктах, де AVIF не вживається.
|
|
11
11
|
2. Запускає `npx @nitra/minify-image --src=. --write --avif` (≥ **3.3.1**) — генерує `<name>.<ext>.avif` поряд з кожним PNG/JPEG/GIF. CLI порівнює sha1 кожного raster-сорсу зі збереженим у `.n-minify-image.tsv` і перезаписує `<source>.avif` при зміні оригіналу.
|
|
@@ -218,7 +218,7 @@ async function checkVueAvifImportsInPackage(packageRoot, otherRootsAbs, ignorePa
|
|
|
218
218
|
VUE_RASTER_IMPORT_RE,
|
|
219
219
|
importPath =>
|
|
220
220
|
`[${label}] ${rel}: import з '${importPath}' має посилатись на AVIF-двійник '${importPath}.avif' ` +
|
|
221
|
-
`(\`npx @nitra/cursor
|
|
221
|
+
`(\`npx @nitra/cursor fix image-avif\` створює його поряд, якщо оригінал є на диску). Вимкнути локально: "@nitra/minify-image": { "disable-avif": true } у package.json пакета`
|
|
222
222
|
)
|
|
223
223
|
processMatches(
|
|
224
224
|
VUE_RASTER_STATIC_SRC_RE,
|
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -100,7 +100,7 @@ export async function check() {
|
|
|
100
100
|
fail('package.json не знайдено в корені — додай (image-compress.mdc)')
|
|
101
101
|
return reporter.getExitCode()
|
|
102
102
|
}
|
|
103
|
-
pass('package.json є (структуру перевіряє npx @nitra/cursor
|
|
103
|
+
pass('package.json є (структуру перевіряє npx @nitra/cursor fix → image_compress.package_json)')
|
|
104
104
|
|
|
105
105
|
await checkHashCacheNotIgnored(pass, fail)
|
|
106
106
|
await checkLegacyCacheRemoved(pass, fail)
|
package/rules/js-bun-db/fix.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|
|
@@ -2,6 +2,7 @@ import { runStandardRule } from '../../scripts/utils/run-standard-rule.mjs'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
5
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
5
6
|
* @param {import('../../scripts/utils/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
6
7
|
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
7
8
|
*/
|
|
@@ -10,6 +11,9 @@ export function run(ctx) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (import.meta.main) {
|
|
14
|
+
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
15
|
+
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
16
|
+
const { runRuleCli } = await import('../../scripts/utils/run-rule-cli.mjs')
|
|
13
17
|
// eslint-disable-next-line unicorn/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
14
|
-
process.exit(await
|
|
18
|
+
process.exit(await runRuleCli(import.meta.dirname))
|
|
15
19
|
}
|