@nitra/cursor 12.6.0 → 12.7.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/.claude-template/settings.template.json +1 -1
- package/CHANGELOG.md +16 -0
- package/bin/docs/n-cursor.md +4 -20
- package/bin/n-cursor.js +7 -53
- package/docs/stryker.config.md +20 -28
- package/package.json +1 -1
- package/rules/abie/docs/index.md +1 -0
- package/rules/abie/docs/main.md +29 -0
- package/rules/abie/{fix.mjs → main.mjs} +5 -3
- package/rules/adr/docs/index.md +1 -0
- package/rules/adr/docs/main.md +29 -0
- package/rules/adr/{fix.mjs → main.mjs} +5 -3
- package/rules/bun/docs/index.md +1 -0
- package/rules/bun/docs/main.md +30 -0
- package/rules/bun/js/docs/layout.md +11 -36
- package/rules/bun/{fix.mjs → main.mjs} +5 -3
- package/rules/capacitor/docs/index.md +1 -0
- package/rules/capacitor/docs/main.md +29 -0
- package/rules/capacitor/{fix.mjs → main.mjs} +5 -3
- package/rules/changelog/docs/index.md +1 -0
- package/rules/changelog/docs/main.md +27 -0
- package/rules/changelog/main.mjs +20 -0
- package/rules/ci4/docs/index.md +1 -0
- package/rules/ci4/docs/main.md +30 -0
- package/rules/ci4/main.mjs +20 -0
- package/rules/doc-files/docs/index.md +1 -0
- package/rules/doc-files/docs/main.md +31 -0
- package/rules/doc-files/js/docgen-files-batch.mjs +47 -3
- package/rules/doc-files/js/docgen-scan.mjs +89 -9
- package/rules/doc-files/js/docs/docgen-files-batch.md +15 -15
- package/rules/doc-files/js/docs/docgen-scan.md +34 -34
- package/rules/doc-files/js/docs/index.md +1 -0
- package/rules/doc-files/js/docs/run-lint.md +27 -0
- package/rules/doc-files/{lint/lint.mjs → js/run-lint.mjs} +23 -9
- package/rules/doc-files/{js/lint.mjs → main.mjs} +60 -10
- package/rules/docker/docs/index.md +1 -0
- package/rules/docker/docs/main.md +28 -0
- package/rules/docker/js/docs/lint.md +26 -54
- package/rules/docker/js/lint.mjs +11 -0
- package/rules/docker/lib/docker-hadolint.mjs +1 -1
- package/rules/docker/lib/docs/docker-hadolint.md +16 -173
- package/rules/docker/main.mjs +20 -0
- package/rules/efes/docs/index.md +1 -0
- package/rules/efes/docs/main.md +29 -0
- package/rules/efes/main.mjs +20 -0
- package/rules/feedback/docs/index.md +1 -0
- package/rules/feedback/docs/main.md +30 -0
- package/rules/feedback/main.mjs +20 -0
- package/rules/ga/docs/index.md +1 -0
- package/rules/ga/docs/main.md +29 -0
- package/rules/ga/{lint/lint.mjs → main.mjs} +36 -10
- package/rules/graphql/docs/index.md +1 -0
- package/rules/graphql/docs/main.md +36 -0
- package/rules/graphql/main.mjs +20 -0
- package/rules/hasura/docs/index.md +1 -0
- package/rules/hasura/docs/main.md +30 -0
- package/rules/hasura/main.mjs +20 -0
- package/rules/image-avif/docs/index.md +1 -0
- package/rules/image-avif/docs/main.md +30 -0
- package/rules/image-avif/js/docs/avif_generation.md +20 -233
- package/rules/image-avif/main.mjs +20 -0
- package/rules/image-compress/docs/index.md +1 -0
- package/rules/image-compress/docs/main.md +29 -0
- package/rules/image-compress/js/docs/package_setup.md +12 -11
- package/rules/image-compress/{js/lint.mjs → main.mjs} +21 -5
- package/rules/js-bun-db/docs/index.md +1 -0
- package/rules/js-bun-db/docs/main.md +30 -0
- package/rules/js-bun-db/main.mjs +20 -0
- package/rules/js-bun-redis/docs/index.md +1 -0
- package/rules/js-bun-redis/docs/main.md +29 -0
- package/rules/js-bun-redis/main.mjs +20 -0
- package/rules/js-lint/docs/index.md +1 -0
- package/rules/js-lint/docs/main.md +29 -0
- package/rules/js-lint/js/check.mjs +268 -0
- package/rules/js-lint/js/docs/check.md +39 -0
- package/rules/js-lint/js/docs/index.md +1 -1
- package/rules/js-lint/js/docs/tooling.md +12 -32
- package/rules/js-lint/js/tooling.mjs +1 -265
- package/rules/js-lint/{js/lint.mjs → main.mjs} +19 -2
- package/rules/js-lint-ci/docs/index.md +1 -0
- package/rules/js-lint-ci/docs/main.md +27 -0
- package/rules/js-lint-ci/main.mjs +33 -0
- package/rules/js-mssql/docs/index.md +1 -0
- package/rules/js-mssql/docs/main.md +30 -0
- package/rules/js-mssql/main.mjs +20 -0
- package/rules/js-run/docs/index.md +1 -0
- package/rules/js-run/docs/main.md +30 -0
- package/rules/js-run/main.mjs +20 -0
- package/rules/k8s/docs/index.md +1 -0
- package/rules/k8s/docs/main.md +40 -0
- package/rules/k8s/js/docs/index.md +12 -0
- package/rules/k8s/{lint/lint.mjs → main.mjs} +32 -10
- package/rules/nginx-default-tpl/docs/index.md +1 -0
- package/rules/nginx-default-tpl/docs/main.md +30 -0
- package/rules/nginx-default-tpl/main.mjs +20 -0
- package/rules/npm-module/docs/index.md +1 -0
- package/rules/npm-module/docs/main.md +29 -0
- package/rules/npm-module/js/docs/rule_meta.md +17 -16
- package/rules/npm-module/js/rule_meta.mjs +13 -3
- package/rules/npm-module/main.mjs +20 -0
- package/rules/php/docs/index.md +1 -0
- package/rules/php/docs/main.md +33 -0
- package/rules/php/js/docs/tooling.md +10 -10
- package/rules/php/{lint/lint.mjs → main.mjs} +32 -6
- package/rules/python/docs/index.md +1 -0
- package/rules/python/docs/main.md +31 -0
- package/rules/python/js/docs/tooling.md +17 -17
- package/rules/python/{lint/lint.mjs → main.mjs} +29 -5
- package/rules/rego/docs/index.md +1 -0
- package/rules/rego/docs/main.md +37 -0
- package/rules/rego/{lint/lint.mjs → main.mjs} +27 -5
- package/rules/release/docs/index.md +1 -0
- package/rules/release/docs/main.md +29 -0
- package/rules/release/docs/release.md +0 -3
- package/rules/release/release.mdc +10 -0
- package/rules/rust/docs/index.md +1 -0
- package/rules/rust/docs/main.md +27 -0
- package/rules/rust/{js/lint.mjs → main.mjs} +20 -3
- package/rules/security/docs/index.md +1 -0
- package/rules/security/docs/main.md +28 -0
- package/rules/security/main.mjs +45 -0
- package/rules/style-lint/docs/index.md +1 -0
- package/rules/style-lint/docs/main.md +29 -0
- package/rules/style-lint/{js/lint.mjs → main.mjs} +19 -1
- package/rules/tauri/docs/index.md +1 -0
- package/rules/tauri/docs/main.md +29 -0
- package/rules/tauri/main.mjs +20 -0
- package/rules/test/docs/index.md +1 -0
- package/rules/test/docs/main.md +30 -0
- package/rules/test/main.mjs +20 -0
- package/rules/text/docs/index.md +1 -0
- package/rules/text/docs/main.md +29 -0
- package/rules/text/js/docs/cspell-fix.md +30 -0
- package/rules/text/js/docs/formatting.md +12 -45
- package/rules/text/js/docs/index.md +4 -0
- package/rules/text/js/docs/run-dotenv-linter.md +31 -0
- package/rules/text/js/docs/run-shellcheck.md +28 -0
- package/rules/text/js/docs/run-v8r.md +29 -0
- package/rules/text/{lint/lint.mjs → main.mjs} +38 -9
- package/rules/text/text.mdc +5 -14
- package/rules/tool-surface/docs/index.md +1 -0
- package/rules/tool-surface/docs/main.md +29 -0
- package/rules/tool-surface/main.mjs +20 -0
- package/rules/vue/docs/index.md +1 -0
- package/rules/vue/docs/main.md +29 -0
- package/rules/vue/main.mjs +20 -0
- package/rules/worktree/docs/index.md +1 -0
- package/rules/worktree/docs/main.md +28 -0
- package/rules/worktree/main.mjs +20 -0
- package/scripts/docs/index.md +1 -0
- package/scripts/docs/post-tool-use-check.md +29 -0
- package/scripts/docs/sync-claude-config.md +64 -92
- package/scripts/lib/adr/docs/normalize-cli.md +0 -3
- package/scripts/lib/adr/docs/normalize-pipeline.md +0 -3
- package/scripts/lib/docs/gha-workflow.md +25 -317
- package/scripts/lib/docs/index.md +1 -0
- package/scripts/lib/docs/list-project-rules-mdc.md +5 -4
- package/scripts/lib/docs/list-rule-ids.md +15 -148
- package/scripts/lib/docs/read-n-cursor-config-lite.md +12 -16
- package/scripts/lib/docs/run-lint-step.md +13 -13
- package/scripts/lib/docs/run-lint.md +30 -0
- package/scripts/lib/docs/run-rule-cli.md +14 -10
- package/scripts/lib/docs/run-standard-lint.md +27 -10
- package/scripts/lib/docs/run-standard-rule.md +12 -11
- package/scripts/lib/docs/timing-summary.md +11 -12
- package/scripts/lib/docs/worktree-notice.md +0 -3
- package/scripts/lib/fix/docs/index.md +1 -0
- package/scripts/lib/fix/docs/orchestrator.md +23 -18
- package/scripts/lib/fix/docs/run-conformance-check.md +32 -0
- package/scripts/lib/fix/docs/t0.md +10 -9
- package/scripts/lib/fix/orchestrator.mjs +5 -5
- package/scripts/lib/fix/{run-fix-check.mjs → run-conformance-check.mjs} +13 -13
- package/scripts/lib/fix/t0.mjs +3 -3
- package/scripts/lib/gha-workflow.mjs +1 -1
- package/scripts/lib/list-project-rules-mdc.mjs +1 -1
- package/scripts/lib/list-rule-ids.mjs +12 -3
- package/scripts/lib/read-n-cursor-config-lite.mjs +2 -2
- package/scripts/lib/run-lint-step.mjs +1 -1
- package/{rules/lint/js/orchestrate.mjs → scripts/lib/run-lint.mjs} +42 -20
- package/scripts/lib/run-rule-cli.mjs +4 -4
- package/scripts/lib/run-standard-lint.mjs +19 -6
- package/scripts/lib/run-standard-rule.mjs +4 -4
- package/scripts/lib/timing-summary.mjs +1 -1
- package/scripts/{post-tool-use-fix.mjs → post-tool-use-check.mjs} +9 -9
- package/scripts/sync-claude-config.mjs +2 -2
- package/rules/changelog/fix.mjs +0 -18
- package/rules/ci4/fix.mjs +0 -18
- package/rules/doc-files/fix.mjs +0 -19
- package/rules/doc-files/js/docs/lint.md +0 -34
- package/rules/doc-files/lint/docs/index.md +0 -11
- package/rules/doc-files/lint/docs/lint.md +0 -35
- package/rules/docker/fix.mjs +0 -18
- package/rules/docker/lint/docs/index.md +0 -11
- package/rules/docker/lint/docs/lint.md +0 -200
- package/rules/docker/lint/lint.mjs +0 -95
- package/rules/efes/fix.mjs +0 -18
- package/rules/feedback/fix.mjs +0 -18
- package/rules/ga/fix.mjs +0 -18
- package/rules/ga/js/docs/lint.md +0 -20
- package/rules/ga/js/lint.mjs +0 -12
- package/rules/ga/lint/docs/index.md +0 -11
- package/rules/ga/lint/docs/lint.md +0 -31
- package/rules/graphql/fix.mjs +0 -18
- package/rules/hasura/fix.mjs +0 -18
- package/rules/image-avif/fix.mjs +0 -18
- package/rules/image-compress/fix.mjs +0 -18
- package/rules/image-compress/js/docs/lint.md +0 -24
- package/rules/js-bun-db/fix.mjs +0 -18
- package/rules/js-bun-redis/fix.mjs +0 -18
- package/rules/js-lint/fix.mjs +0 -18
- package/rules/js-lint/js/docs/lint.md +0 -32
- package/rules/js-lint-ci/fix.mjs +0 -18
- package/rules/js-lint-ci/js/docs/lint.md +0 -22
- package/rules/js-lint-ci/js/lint.mjs +0 -15
- package/rules/js-mssql/fix.mjs +0 -18
- package/rules/js-run/fix.mjs +0 -18
- package/rules/k8s/fix.mjs +0 -18
- package/rules/k8s/js/lint.mjs +0 -14
- package/rules/k8s/lint/docs/index.md +0 -11
- package/rules/k8s/lint/docs/lint.md +0 -413
- package/rules/lint/docs/fix.md +0 -25
- package/rules/lint/docs/index.md +0 -11
- package/rules/lint/fix.mjs +0 -18
- package/rules/lint/js/docs/index.md +0 -11
- package/rules/lint/js/docs/orchestrate.md +0 -31
- package/rules/lint/meta.json +0 -1
- package/rules/nginx-default-tpl/fix.mjs +0 -18
- package/rules/npm-module/fix.mjs +0 -18
- package/rules/php/fix.mjs +0 -18
- package/rules/php/js/docs/lint.md +0 -20
- package/rules/php/js/lint.mjs +0 -15
- package/rules/php/lint/docs/index.md +0 -11
- package/rules/php/lint/docs/lint.md +0 -219
- package/rules/python/fix.mjs +0 -18
- package/rules/python/js/docs/lint.md +0 -21
- package/rules/python/js/lint.mjs +0 -14
- package/rules/python/lint/docs/index.md +0 -11
- package/rules/python/lint/docs/lint.md +0 -29
- package/rules/rego/fix.mjs +0 -18
- package/rules/rego/js/docs/lint.md +0 -21
- package/rules/rego/js/lint.mjs +0 -12
- package/rules/rego/lint/docs/index.md +0 -11
- package/rules/rego/lint/docs/lint.md +0 -208
- package/rules/rust/fix.mjs +0 -18
- package/rules/rust/js/docs/lint.md +0 -21
- package/rules/security/fix.mjs +0 -18
- package/rules/security/js/docs/lint.md +0 -175
- package/rules/security/js/lint.mjs +0 -26
- package/rules/style-lint/fix.mjs +0 -18
- package/rules/style-lint/js/docs/lint.md +0 -31
- package/rules/tauri/fix.mjs +0 -18
- package/rules/test/fix.mjs +0 -18
- package/rules/text/fix.mjs +0 -18
- package/rules/text/js/docs/lint.md +0 -23
- package/rules/text/js/lint.mjs +0 -15
- package/rules/text/lint/docs/cspell-fix.md +0 -32
- package/rules/text/lint/docs/index.md +0 -15
- package/rules/text/lint/docs/lint.md +0 -36
- package/rules/text/lint/docs/run-dotenv-linter.md +0 -161
- package/rules/text/lint/docs/run-shellcheck.md +0 -216
- package/rules/text/lint/docs/run-v8r.md +0 -201
- package/rules/tool-surface/fix.mjs +0 -18
- package/rules/vue/fix.mjs +0 -18
- package/rules/worktree/fix.mjs +0 -18
- /package/rules/release/{fix.mjs → main.mjs} +0 -0
- /package/rules/text/{lint → js}/cspell-fix.mjs +0 -0
- /package/rules/text/{lint → js}/run-dotenv-linter.mjs +0 -0
- /package/rules/text/{lint → js}/run-shellcheck.mjs +0 -0
- /package/rules/text/{lint → js}/run-v8r.mjs +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Light read-only `.n-cursor.json` reader для standalone `
|
|
2
|
+
* Light read-only `.n-cursor.json` reader для standalone `check.mjs` invocation.
|
|
3
3
|
*
|
|
4
4
|
* НЕ робить auto-rules detection, merge, schema sync — це справа повного `readConfig` у CLI.
|
|
5
5
|
* Тут лише: прочитати файл (якщо є), повернути `{ rules: string[], disableRules: string[] }`.
|
|
6
6
|
*
|
|
7
7
|
* Спостереження whitelist:
|
|
8
8
|
* - якщо `.n-cursor.json` НЕМАЄ → правило вважається enabled (поведінка "open by default"),
|
|
9
|
-
* щоб `bun rules/<id>/
|
|
9
|
+
* щоб `bun rules/<id>/check.mjs` з будь-якої тимчасової директорії працювало для debug.
|
|
10
10
|
* - якщо файл є з `rules:[…]`, але правила там немає → правило не enabled.
|
|
11
11
|
* - якщо правило в `disable-rules` → не enabled, навіть якщо у `rules:[…]`.
|
|
12
12
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* команди і прокидає stdout/stderr на користувацькі stream-и (`stdio: 'inherit'`), щоб виглядало
|
|
4
4
|
* як прямий виклик у shell.
|
|
5
5
|
*
|
|
6
|
-
* Використовується з
|
|
6
|
+
* Використовується з rule-адаптерів `n-cursor lint <rule>`, щоб не дублювати
|
|
7
7
|
* одну й ту саму обгортку у кожному `rules/<id>/js/lint.mjs` (jscpd-clone).
|
|
8
8
|
*/
|
|
9
9
|
import { spawnSync } from 'node:child_process'
|
|
@@ -1,19 +1,40 @@
|
|
|
1
|
-
/** @see ./docs/
|
|
1
|
+
/** @see ./docs/run-lint.md */
|
|
2
2
|
import { existsSync, readdirSync } from 'node:fs'
|
|
3
3
|
import { dirname, join } from 'node:path'
|
|
4
4
|
import { fileURLToPath } from 'node:url'
|
|
5
5
|
import { cwd as processCwd } from 'node:process'
|
|
6
6
|
import { spawnSync } from 'node:child_process'
|
|
7
7
|
|
|
8
|
-
import { parseRuleLintSpec, readRuleMetaRaw } from '
|
|
9
|
-
import { collectChangedFilesSince, resolveChangedBase } from '
|
|
10
|
-
import { resolveCmd } from '
|
|
11
|
-
import { isRuleEnabled, readNCursorConfigLite } from '
|
|
8
|
+
import { parseRuleLintSpec, readRuleMetaRaw } from './rule-meta.mjs'
|
|
9
|
+
import { collectChangedFilesSince, resolveChangedBase } from './changed-files.mjs'
|
|
10
|
+
import { resolveCmd } from '../utils/resolve-cmd.mjs'
|
|
11
|
+
import { isRuleEnabled, readNCursorConfigLite } from './read-n-cursor-config-lite.mjs'
|
|
12
12
|
|
|
13
|
-
// Цей файл: npm/
|
|
14
|
-
const PACKAGE_ROOT = dirname(dirname(
|
|
13
|
+
// Цей файл: npm/scripts/lib/run-lint.mjs → PACKAGE_ROOT = npm (два dirname угору).
|
|
14
|
+
const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)))
|
|
15
15
|
const RULES_DIR = join(PACKAGE_ROOT, 'rules')
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Чи має правило лінт-поверхню — `meta.json#lint` задано (`per-file`/`full`).
|
|
19
|
+
* Канонічний сигнал (ADR 2026-06-21): gate за meta, не за наявністю файлу.
|
|
20
|
+
* @param {Record<string, unknown> | undefined} raw meta-обʼєкт правила
|
|
21
|
+
* @returns {boolean} true — правило лінтить
|
|
22
|
+
*/
|
|
23
|
+
function hasLintSurface(raw) {
|
|
24
|
+
return parseRuleLintSpec(raw?.lint) !== null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Резолвить лінт-entrypoint правила: `main.mjs` з експортом `lint` (канон, ADR 2026-06-21).
|
|
29
|
+
* @param {string} rulesDir каталог rules
|
|
30
|
+
* @param {string} id rule-id
|
|
31
|
+
* @returns {string | null} шлях до `main.mjs`, або null якщо файлу нема
|
|
32
|
+
*/
|
|
33
|
+
function resolveLintEntrypoint(rulesDir, id) {
|
|
34
|
+
const main = join(rulesDir, id, 'main.mjs')
|
|
35
|
+
return existsSync(main) ? main : null
|
|
36
|
+
}
|
|
37
|
+
|
|
17
38
|
/**
|
|
18
39
|
* Конформність-фаза lint (whole-repo: config/file/workflow conformance — те, що раніше робив `fix`).
|
|
19
40
|
* Per-file декомпозиції немає, тож виконується лише у `--full`.
|
|
@@ -27,11 +48,11 @@ const RULES_DIR = join(PACKAGE_ROOT, 'rules')
|
|
|
27
48
|
*/
|
|
28
49
|
async function runConformance(cwd, readOnly, log, filter = []) {
|
|
29
50
|
if (!readOnly) {
|
|
30
|
-
const { runOrchestratorCli } = await import('
|
|
51
|
+
const { runOrchestratorCli } = await import('./fix/orchestrator.mjs')
|
|
31
52
|
return runOrchestratorCli(filter, cwd)
|
|
32
53
|
}
|
|
33
|
-
const {
|
|
34
|
-
const { rules } = await
|
|
54
|
+
const { runConformanceCheck } = await import('./fix/run-conformance-check.mjs')
|
|
55
|
+
const { rules } = await runConformanceCheck(filter, cwd)
|
|
35
56
|
const failed = rules.filter(x => !x.ok)
|
|
36
57
|
if (failed.length === 0) return 0
|
|
37
58
|
log(`❌ lint: конформність — ${failed.length} порушень: ${failed.map(x => x.ruleId).join(', ')}\n`)
|
|
@@ -97,9 +118,9 @@ async function runPerFileRules(ids, ctx) {
|
|
|
97
118
|
const { rulesDir, changed, cwd, readOnly, metaById, log } = ctx
|
|
98
119
|
let worst = 0
|
|
99
120
|
for (const id of ids) {
|
|
100
|
-
const lintPath =
|
|
101
|
-
if (!
|
|
102
|
-
log(`⚠️ lint: правило ${id} має lint
|
|
121
|
+
const lintPath = resolveLintEntrypoint(rulesDir, id)
|
|
122
|
+
if (!lintPath) {
|
|
123
|
+
log(`⚠️ lint: правило ${id} має lint-фазу (meta.lint), але немає main.mjs — пропускаю.\n`)
|
|
103
124
|
continue
|
|
104
125
|
}
|
|
105
126
|
// lintPath = join(rulesDir, id, …) — суто package-internal (rulesDir пакета + id зі
|
|
@@ -128,7 +149,7 @@ async function runPerFileRules(ids, ctx) {
|
|
|
128
149
|
*/
|
|
129
150
|
async function runFullConformancePhase(cwd, readOnly, log) {
|
|
130
151
|
const { escalationLogSize, maybeAnalyzeEscalation, reportRunStats } = await import(
|
|
131
|
-
'
|
|
152
|
+
'./fix/analyze-escalation.mjs'
|
|
132
153
|
)
|
|
133
154
|
const escOffset = readOnly ? 0 : escalationLogSize()
|
|
134
155
|
const conformanceCode = await runConformance(cwd, readOnly, log)
|
|
@@ -160,11 +181,12 @@ function runFormat(cwd, log) {
|
|
|
160
181
|
}
|
|
161
182
|
|
|
162
183
|
/**
|
|
163
|
-
* Scoped-режим (`lint <rule…>`): повний прогін НАЗВАНИХ правил — їх лінтер (
|
|
164
|
-
* whole-repo) для тих, що
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
184
|
+
* Scoped-режим (`lint <rule…>`): повний прогін НАЗВАНИХ правил — їх лінтер (entrypoint
|
|
185
|
+
* `main.mjs::lint`, whole-repo) для тих, що мають лінт-поверхню
|
|
186
|
+
* (`meta.json#lint`), + конформність для всіх названих. Дзеркалить `--full`, але звужено
|
|
187
|
+
* до правил, тож `lint ga` ≡ standalone `lint-ga`. Конформність-only правила (напр.
|
|
188
|
+
* `changelog` із hk) без `meta.lint` → проганяється лише їх конформність (зворотна
|
|
189
|
+
* сумісність із колишнім `fix <rule>`). oxfmt у scoped НЕ запускається — це
|
|
168
190
|
* таргетований прогін правил, а не глобальне форматування.
|
|
169
191
|
* @param {string[]} rules id названих правил
|
|
170
192
|
* @param {{ cwd: string, readOnly: boolean, rulesDir: string, conformance: boolean, log: (s: string) => void }} ctx контекст (`conformance` — чи запускати конформність; false для юніт-тестів із кастомним rulesDir, де реальний пакет недоступний)
|
|
@@ -173,7 +195,7 @@ function runFormat(cwd, log) {
|
|
|
173
195
|
async function runScopedRules(rules, ctx) {
|
|
174
196
|
const { cwd, readOnly, rulesDir, conformance, log } = ctx
|
|
175
197
|
const metaById = readAllMeta(rulesDir)
|
|
176
|
-
const linterIds = rules.filter(id =>
|
|
198
|
+
const linterIds = rules.filter(id => hasLintSurface(metaById[id]))
|
|
177
199
|
let worst = 0
|
|
178
200
|
if (linterIds.length > 0) {
|
|
179
201
|
const perFile = await runPerFileRules(linterIds, { rulesDir, changed: undefined, cwd, readOnly, metaById, log })
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Standalone CLI runner для одного правила. Викликається з `rules/<id>/
|
|
3
|
-
* у блоці `if (import.meta.main)` — це робить `bun rules/<id>/
|
|
2
|
+
* Standalone CLI runner для одного правила. Викликається з `rules/<id>/check.mjs`
|
|
3
|
+
* у блоці `if (import.meta.main)` — це робить `bun rules/<id>/check.mjs` повним
|
|
4
4
|
* еквівалентом `npx \@nitra/cursor fix <id>`: друкує summary, повертає aggregated exit-code.
|
|
5
5
|
*
|
|
6
6
|
* **Без whitelist-гейту.** Гейтинг активних правил — єдине джерело: `resolveCheckRuleIds`
|
|
7
|
-
* (`scripts/lib/fix/run-
|
|
7
|
+
* (`scripts/lib/fix/run-conformance-check.mjs`) за `.n-cursor.json`. Прямий `bun rules/<id>/check.mjs` —
|
|
8
8
|
* свідомий запуск саме цього правила (debug / override), тож виконується беззастережно;
|
|
9
9
|
* усі автоматичні шляхи (lint-конформність, orchestrator, t0, hook) уже спавнять лише активні.
|
|
10
10
|
*
|
|
@@ -15,7 +15,7 @@ import { basename } from 'node:path'
|
|
|
15
15
|
import { runStandardRule } from './run-standard-rule.mjs'
|
|
16
16
|
import { getOrCreateWalkCache } from '../utils/walk-cache.mjs'
|
|
17
17
|
|
|
18
|
-
// Re-export для зворотної сумісності: уся `rules/<id>/
|
|
18
|
+
// Re-export для зворотної сумісності: уся `rules/<id>/check.mjs` уже імпортує `isRunAsCli`
|
|
19
19
|
// саме звідси. Канонічна реалізація — у `scripts/cli-entry.mjs`. Caller передає
|
|
20
20
|
// `import.meta.url`: `if (isRunAsCli(import.meta.url)) …`.
|
|
21
21
|
export { isRunAsCli } from '../cli-entry.mjs'
|
|
@@ -7,29 +7,42 @@
|
|
|
7
7
|
* патчилися в кожному `rules/<rule>/lint/lint.mjs`.
|
|
8
8
|
*
|
|
9
9
|
* Зараз робить рівно одне: серіалізує + дедуплікує запуски через `withLock('lint-<ruleId>')`.
|
|
10
|
-
* `ruleId` виводиться зі
|
|
10
|
+
* `ruleId` виводиться зі шляху незалежно від глибини виклику: `rules/<id>` (з `main.mjs`),
|
|
11
|
+
* `rules/<id>/js` або `rules/<id>/lint` → `<id>` (сегмент одразу після `rules/`).
|
|
11
12
|
*
|
|
12
13
|
* Інтеграція з боку правила:
|
|
13
14
|
*
|
|
14
15
|
* ```js
|
|
15
|
-
* import { runStandardLint } from '
|
|
16
|
+
* import { runStandardLint } from '../../scripts/lib/run-standard-lint.mjs'
|
|
16
17
|
*
|
|
17
18
|
* async function runLintFooSteps() { ... }
|
|
18
19
|
*
|
|
19
|
-
* export
|
|
20
|
+
* export function lint(_files) { return runStandardLint(import.meta.dirname, runLintFooSteps) }
|
|
20
21
|
* ```
|
|
21
22
|
*/
|
|
22
|
-
import { basename
|
|
23
|
+
import { basename } from 'node:path'
|
|
23
24
|
|
|
24
25
|
import { withLock } from '../utils/with-lock.mjs'
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
|
-
*
|
|
28
|
+
* Виводить `<id>` зі шляху каталогу правила незалежно від глибини: сегмент одразу після
|
|
29
|
+
* останнього `rules/`. Fallback — `basename(dir)`, якщо `rules/` у шляху немає.
|
|
30
|
+
* @param {string} dir абсолютний шлях каталогу (`rules/<id>`, `rules/<id>/js`, …)
|
|
31
|
+
* @returns {string} rule-id
|
|
32
|
+
*/
|
|
33
|
+
function ruleIdFromDir(dir) {
|
|
34
|
+
const parts = dir.split(/[/\\]/u)
|
|
35
|
+
const i = parts.lastIndexOf('rules')
|
|
36
|
+
return i !== -1 && parts[i + 1] ? parts[i + 1] : basename(dir)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {string} lintDir абсолютний шлях до каталогу правила (передавай `import.meta.dirname`)
|
|
28
41
|
* @param {() => number | Promise<number>} stepsFn реальна робота лінту; повертає код виходу
|
|
29
42
|
* @param {{ttl?:number, staleThreshold?:number, waitTimeout?:number, pollInterval?:number, cacheDir?:string, getFingerprint?:() => string | null}} [opts] прокидаються у `withLock`
|
|
30
43
|
* @returns {Promise<number>} код виходу
|
|
31
44
|
*/
|
|
32
45
|
export function runStandardLint(lintDir, stepsFn, opts) {
|
|
33
|
-
const ruleId =
|
|
46
|
+
const ruleId = ruleIdFromDir(lintDir)
|
|
34
47
|
return withLock(`lint-${ruleId}`, stepsFn, opts)
|
|
35
48
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public API per-rule orchestration. Викликається з `rules/<id>/
|
|
2
|
+
* Public API per-rule orchestration. Викликається з `rules/<id>/check.mjs`.
|
|
3
3
|
*
|
|
4
4
|
* Інкапсулює: `discoverOneRule` → `runRule(applies → JS → policy → mdc-refs)`.
|
|
5
5
|
* Локальна логіка в правилах заборонена; розширення поведінки — через `ctx`-опції.
|
|
6
6
|
*
|
|
7
7
|
* Серіалізація: загортає виконання у `withLock('fix-<ruleId>')` — паралельні запуски
|
|
8
|
-
* того самого правила (через `npx \@nitra/cursor fix`, прямий `bun rules/<id>/
|
|
8
|
+
* того самого правила (через `npx \@nitra/cursor fix`, прямий `bun rules/<id>/check.mjs`
|
|
9
9
|
* чи `run(ctx)`-композицію) дедупляться за станом git-дерева; різні правила можуть
|
|
10
10
|
* виконуватись паралельно. Точка інтеграції — тут, щоб не дублювати лок у кожному
|
|
11
|
-
* `
|
|
11
|
+
* `check.mjs`.
|
|
12
12
|
*/
|
|
13
13
|
import { basename, dirname } from 'node:path'
|
|
14
14
|
|
|
@@ -24,7 +24,7 @@ import { withLock } from '../utils/with-lock.mjs'
|
|
|
24
24
|
* Зарезервовано на майбутнє (поки не реалізовано — додається, коли з'явиться потреба):
|
|
25
25
|
* - `skipMdcRefs`, `skipApplies`, `onlyConcerns`.
|
|
26
26
|
* Розширення поведінки правила робиться лише через нові поля тут, не через локальну
|
|
27
|
-
* логіку в `rules/<id>/
|
|
27
|
+
* логіку в `rules/<id>/check.mjs`.
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Формат таблиці-резюме часу виконання для orchestrator `fix` / `lint`.
|
|
3
3
|
*
|
|
4
4
|
* Дві спільні точки використання:
|
|
5
|
-
* - `runFixCommand` у `bin/n-cursor.js` — після прогону всіх `rules/<id>/
|
|
5
|
+
* - `runFixCommand` у `bin/n-cursor.js` — після прогону всіх `rules/<id>/check.mjs`.
|
|
6
6
|
* - `runLintCli` у `scripts/lib/run-lint-cli.mjs` — після прогону `lint-*` скриптів з кореневого `package.json`.
|
|
7
7
|
*
|
|
8
8
|
* Чиста функція без I/O — повертає готовий рядок (з фінальним `\n`), друк — на стороні виклику.
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Раніше хук маршрутизував змінений файл у релевантні правила й ганяв повний `fix` (автофікс
|
|
6
6
|
* + LLM) — дорого, тож звужували. Тепер хук — **детект** (нуль мутацій, нуль LLM), тож роутинг
|
|
7
|
-
* зайвий: один виклик `_fix-check` (per-rule `
|
|
7
|
+
* зайвий: один виклик `_fix-check` (per-rule `check.mjs run()` = перевірка) по всіх правилах.
|
|
8
8
|
*
|
|
9
9
|
* Контракт:
|
|
10
10
|
* - stdin Claude Code: JSON із `tool_input.file_path`; якщо файлу немає (напр. Bash) — exit 0 (skip);
|
|
11
|
-
* - інакше пряма `
|
|
11
|
+
* - інакше пряма `runConformanceCheck` (детект усіх правил, без subprocess-обгортки), exit-код прозоро:
|
|
12
12
|
* 1 — є порушення конформності (PostToolUse не блокує turn, але код лишаємо інформативним).
|
|
13
13
|
*/
|
|
14
14
|
import { once } from 'node:events'
|
|
15
15
|
import { cwd as processCwd } from 'node:process'
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { runConformanceCheck } from './lib/fix/run-conformance-check.mjs'
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Зчитує stdin до EOF як utf8 рядок. На TTY — повертає `''` одразу.
|
|
@@ -57,20 +57,20 @@ export function extractFilePath(stdinJson) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
* Точка входу. Викликається з `bin/n-cursor.js` коли argv[0] === `post-tool-use-
|
|
60
|
+
* Точка входу. Викликається з `bin/n-cursor.js` коли argv[0] === `post-tool-use-check`.
|
|
61
61
|
* Параметри доступні для інʼєкції для тестів: `stdinJson` обходить read від `process.stdin`,
|
|
62
|
-
* `
|
|
63
|
-
* @param {{ stdinJson?: string,
|
|
62
|
+
* `runConformanceCheckFn` — заміна `runConformanceCheck`.
|
|
63
|
+
* @param {{ stdinJson?: string, runConformanceCheckFn?: typeof runConformanceCheck }} [options] параметри для тестів
|
|
64
64
|
* @returns {Promise<number>} exit code (0 — пропущено / конформність ОК; 1 — є порушення)
|
|
65
65
|
*/
|
|
66
|
-
export async function
|
|
66
|
+
export async function runPostToolUseCheckCli(options = {}) {
|
|
67
67
|
const stdinJson = options.stdinJson ?? (await readStdin())
|
|
68
68
|
const filePath = extractFilePath(stdinJson)
|
|
69
69
|
// Тільки після редагування файлу (Edit/Write/MultiEdit мають file_path); Bash тощо — skip.
|
|
70
70
|
if (filePath === null) {
|
|
71
71
|
return 0
|
|
72
72
|
}
|
|
73
|
-
const check = options.
|
|
73
|
+
const check = options.runConformanceCheckFn ?? runConformanceCheck
|
|
74
74
|
// Один read-only детект конформності всіх активованих правил (пряма функція, без subprocess).
|
|
75
75
|
try {
|
|
76
76
|
const { failed, rules } = await check([], processCwd())
|
|
@@ -80,7 +80,7 @@ export async function runPostToolUseFixCli(options = {}) {
|
|
|
80
80
|
}
|
|
81
81
|
return 1
|
|
82
82
|
} catch (error) {
|
|
83
|
-
process.stderr.write(`post-tool-use-
|
|
83
|
+
process.stderr.write(`post-tool-use-check: не вдалося запустити детект конформності — ${error.message}\n`)
|
|
84
84
|
return 1
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -30,8 +30,8 @@ import { existsSync } from 'node:fs'
|
|
|
30
30
|
import { chmod, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises'
|
|
31
31
|
import { join } from 'node:path'
|
|
32
32
|
|
|
33
|
-
/** Маркер PostToolUse fix-hook'а (`npx --no \@nitra/cursor post-tool-use-
|
|
34
|
-
export const MANAGED_HOOK_COMMAND_MARKER = '@nitra/cursor post-tool-use-
|
|
33
|
+
/** Маркер PostToolUse fix-hook'а (`npx --no \@nitra/cursor post-tool-use-check`). */
|
|
34
|
+
export const MANAGED_HOOK_COMMAND_MARKER = '@nitra/cursor post-tool-use-check'
|
|
35
35
|
/** Маркер doc-files staleness-hook'ів (PostToolUse `--hook` і Stop-гейт `--git`). */
|
|
36
36
|
export const DOC_FILES_HOOK_COMMAND_MARKER = '@nitra/cursor lint-doc-files'
|
|
37
37
|
/** Legacy-маркер старих doc-files hook'ів (`doc-files check`) — cleanup при ресинку наявних інсталяцій. */
|
package/rules/changelog/fix.mjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
-
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
6
|
-
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
7
|
-
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
8
|
-
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
9
|
-
*/
|
|
10
|
-
export function run(ctx) {
|
|
11
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (isRunAsCli(import.meta.url)) {
|
|
15
|
-
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
16
|
-
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
17
|
-
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
18
|
-
}
|
package/rules/ci4/fix.mjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
-
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
6
|
-
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
7
|
-
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
8
|
-
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
9
|
-
*/
|
|
10
|
-
export function run(ctx) {
|
|
11
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (isRunAsCli(import.meta.url)) {
|
|
15
|
-
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
16
|
-
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
17
|
-
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
18
|
-
}
|
package/rules/doc-files/fix.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
-
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Запускає правило doc-files: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
6
|
-
* Структурні concerns (наявність workflow lint-doc-files.yml, скрипт у package.json) закриває
|
|
7
|
-
* policy-канал; контентні порушення (відсутні/застарілі доки) — поза `n-cursor fix`, їх закриває
|
|
8
|
-
* `fix-doc-files` (генерація). Library mode: викликається через `import + run(ctx)`.
|
|
9
|
-
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону
|
|
10
|
-
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
11
|
-
*/
|
|
12
|
-
export function run(ctx) {
|
|
13
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (isRunAsCli(import.meta.url)) {
|
|
17
|
-
// Standalone: bun rules/doc-files/fix.mjs — еквівалент `npx @nitra/cursor fix doc-files`.
|
|
18
|
-
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
19
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/doc-files/js/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: ca055f8f
|
|
7
|
-
score: 100
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Адаптер правила doc-files до агрегатора `n-cursor lint`. Дає агрегатору відповідь на одне
|
|
11
|
-
питання: чи має кожен дотичний кодовий файл актуальну файлову документацію поряд із собою.
|
|
12
|
-
|
|
13
|
-
## Поведінка
|
|
14
|
-
|
|
15
|
-
У quick-фазі отримує список змінених файлів і зводить його до набору джерел для перевірки в
|
|
16
|
-
**обидва** боки: змінене джерело перевіряється проти своєї доки, а змінена або видалена дока
|
|
17
|
-
(`<dir>/docs/<stem>.md`) повертається до відповідного джерела з тим самим іменем у каталозі над
|
|
18
|
-
`docs/`. У ci-фазі (списку немає) обходить усе дерево.
|
|
19
|
-
|
|
20
|
-
Порушенням вважається відсутня дока (`missing`) або розбіжність контрольної суми джерела з тією,
|
|
21
|
-
що записана у frontmatter доки (`crc-mismatch`). Документ із низькою якістю, але свіжою сумою —
|
|
22
|
-
не порушення.
|
|
23
|
-
|
|
24
|
-
## Публічний API
|
|
25
|
-
|
|
26
|
-
`lint` — перевіряє документацію для переданого набору змінених файлів (або всього репозиторію,
|
|
27
|
-
якщо набір не задано); повертає код виходу `1`, якщо є застарілі чи відсутні доки, інакше `0`.
|
|
28
|
-
Список проблемних файлів друкується у stderr із підказкою регенерувати.
|
|
29
|
-
|
|
30
|
-
## Гарантії поведінки
|
|
31
|
-
|
|
32
|
-
- Детермінованість: жодного виклику мовної моделі, рішення лише за контрольною сумою.
|
|
33
|
-
- Реверс-мапінг доки до джерела перебирає лише кодові розширення і повертає наявний файл-кандидат.
|
|
34
|
-
- Порожній набір змінених файлів дає код `0` без обходу дерева.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/doc-files/lint/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: a30dd81f
|
|
7
|
-
score: 100
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
CLI-команда `lint-doc-files` — детермінований детектор застарілості файлових док. Працює без
|
|
11
|
-
мовної моделі скрізь: локально, в hook'ах і в CI.
|
|
12
|
-
|
|
13
|
-
## Поведінка
|
|
14
|
-
|
|
15
|
-
Без прапорців або з переліком шляхів робить повний чи точковий детект і повертає код `1`, якщо є
|
|
16
|
-
застарілі/відсутні доки. `--missing-only` звужує до самих відсутніх. `--json` друкує машинний
|
|
17
|
-
лістинг усіх кандидатів зі станом і завершується кодом `0`. Режими `--hook`, `--git` і
|
|
18
|
-
`--degraded` делегуються детектору hook-протоколу (PostToolUse за одним файлом зі stdin, Stop-гейт
|
|
19
|
-
за зміненими у задачі джерелами з порогом, інформаційний звіт про доки нижчої якості).
|
|
20
|
-
|
|
21
|
-
Повний прогін серіалізується спільним локом під ключем, виведеним зі шляху каталогу, тож паралельні
|
|
22
|
-
запуски не накладаються; hook-форми навмисно виконуються без локу заради завжди-свіжого вердикту.
|
|
23
|
-
|
|
24
|
-
## Публічний API
|
|
25
|
-
|
|
26
|
-
`runLintDocFilesCli` — точка входу команди: маршрутизує між делегатом hook-протоколу, JSON-лістингом
|
|
27
|
-
і повним/точковим детектом; повертає код виходу.
|
|
28
|
-
`runLintDocFilesSteps` — сама робота повного чи точкового детекту, придатна для прямого виклику з
|
|
29
|
-
тестів без локу; повертає `1` за наявності застарілих док, інакше `0`.
|
|
30
|
-
|
|
31
|
-
## Гарантії поведінки
|
|
32
|
-
|
|
33
|
-
- Неіснуючий корінь дає зрозумілу помилку і код `1`.
|
|
34
|
-
- Повний прогін — код `1` (конвенція `lint-*`); hook/git — код `2` (blocking feedback для Claude Code).
|
|
35
|
-
- Жодних викликів мовної моделі.
|
package/rules/docker/fix.mjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
-
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
6
|
-
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
7
|
-
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
8
|
-
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
9
|
-
*/
|
|
10
|
-
export function run(ctx) {
|
|
11
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (isRunAsCli(import.meta.url)) {
|
|
15
|
-
// Standalone: bun rules/<id>/fix.mjs — повний еквівалент `npx @nitra/cursor fix <id>`
|
|
16
|
-
// (config-loading + whitelist + summary). Дві ролі fix.mjs: library (run) + standalone (main).
|
|
17
|
-
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
18
|
-
}
|