@nitra/cursor 12.6.1 → 12.8.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/.pi-template/extensions/n-cursor-adr/docs/index.md +2 -2
- package/CHANGELOG.md +25 -5
- package/bin/docs/n-cursor.md +4 -20
- package/bin/n-cursor.js +8 -54
- package/docs/index.md +3 -3
- package/docs/stryker.config.md +20 -28
- package/lib/docs/index.md +5 -5
- package/lib/docs/llm.md +4 -4
- package/package.json +2 -2
- package/rules/abie/docs/fix.md +8 -8
- package/rules/abie/docs/index.md +4 -3
- package/rules/abie/docs/main.md +29 -0
- package/rules/abie/js/docs/index.md +6 -6
- package/rules/abie/lib/docs/index.md +9 -9
- 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/fix.md +5 -5
- package/rules/bun/docs/index.md +4 -3
- package/rules/bun/docs/main.md +30 -0
- package/rules/bun/js/docs/index.md +2 -2
- package/rules/bun/js/docs/layout.md +11 -36
- package/rules/bun/{fix.mjs → main.mjs} +5 -3
- package/rules/capacitor/docs/fix.md +10 -10
- package/rules/capacitor/docs/index.md +4 -3
- package/rules/capacitor/docs/main.md +29 -0
- package/rules/capacitor/js/docs/index.md +2 -2
- package/rules/capacitor/{fix.mjs → main.mjs} +5 -3
- package/rules/changelog/docs/fix.md +11 -11
- package/rules/changelog/docs/index.md +4 -3
- package/rules/changelog/docs/main.md +27 -0
- package/rules/changelog/js/docs/consistency.md +12 -12
- package/rules/changelog/js/docs/index.md +2 -2
- package/rules/changelog/lib/docs/index.md +2 -2
- package/rules/changelog/main.mjs +20 -0
- package/rules/ci4/docs/fix.md +4 -4
- package/rules/ci4/docs/index.md +4 -3
- package/rules/ci4/docs/main.md +30 -0
- package/rules/ci4/js/docs/index.md +2 -2
- package/rules/ci4/main.mjs +20 -0
- package/rules/doc-files/docs/index.md +4 -3
- package/rules/doc-files/docs/main.md +31 -0
- package/rules/doc-files/js/docgen-crc.mjs +2 -8
- package/rules/doc-files/js/docgen-extract.mjs +5 -3
- package/rules/doc-files/js/docgen-files-batch.mjs +63 -4
- package/rules/doc-files/js/docgen-gen.mjs +11 -3
- package/rules/doc-files/js/docgen-judge-measure.mjs +67 -18
- package/rules/doc-files/js/docgen-judge.mjs +8 -1
- package/rules/doc-files/js/docgen-scan.mjs +99 -11
- package/rules/doc-files/js/docs/docgen-crc.md +25 -14
- package/rules/doc-files/js/docs/docgen-extract.md +15 -13
- package/rules/doc-files/js/docs/docgen-files-batch.md +15 -15
- package/rules/doc-files/js/docs/docgen-gen.md +15 -26
- package/rules/doc-files/js/docs/docgen-judge-measure.md +14 -12
- package/rules/doc-files/js/docs/docgen-scan.md +34 -34
- package/rules/doc-files/js/docs/index.md +16 -15
- 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/fix.md +6 -6
- package/rules/docker/docs/index.md +4 -3
- package/rules/docker/docs/main.md +28 -0
- package/rules/docker/js/docs/index.md +2 -2
- 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/lib/docs/index.md +5 -5
- package/rules/docker/main.mjs +20 -0
- package/rules/efes/docs/fix.md +8 -8
- package/rules/efes/docs/index.md +4 -3
- package/rules/efes/docs/main.md +29 -0
- package/rules/efes/main.mjs +20 -0
- package/rules/feedback/docs/fix.md +5 -5
- package/rules/feedback/docs/index.md +4 -3
- package/rules/feedback/docs/main.md +30 -0
- package/rules/feedback/main.mjs +20 -0
- package/rules/ga/docs/fix.md +5 -5
- package/rules/ga/docs/index.md +4 -3
- package/rules/ga/docs/main.md +29 -0
- package/rules/ga/js/docs/index.md +3 -3
- package/rules/ga/{lint/lint.mjs → main.mjs} +36 -10
- package/rules/graphql/docs/fix.md +8 -8
- package/rules/graphql/docs/index.md +4 -3
- package/rules/graphql/docs/main.md +36 -0
- package/rules/graphql/js/docs/index.md +2 -2
- package/rules/graphql/lib/docs/index.md +2 -2
- package/rules/graphql/main.mjs +20 -0
- package/rules/hasura/docs/fix.md +11 -11
- package/rules/hasura/docs/index.md +4 -3
- package/rules/hasura/docs/main.md +30 -0
- package/rules/hasura/js/docs/index.md +2 -2
- package/rules/hasura/main.mjs +20 -0
- package/rules/image-avif/docs/fix.md +3 -3
- package/rules/image-avif/docs/index.md +4 -3
- package/rules/image-avif/docs/main.md +30 -0
- package/rules/image-avif/js/docs/avif_generation.md +20 -233
- package/rules/image-avif/js/docs/index.md +2 -2
- package/rules/image-avif/main.mjs +20 -0
- package/rules/image-compress/docs/fix.md +2 -2
- package/rules/image-compress/docs/index.md +4 -3
- package/rules/image-compress/docs/main.md +29 -0
- package/rules/image-compress/js/docs/index.md +3 -3
- 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/fix.md +5 -5
- package/rules/js-bun-db/docs/index.md +4 -3
- package/rules/js-bun-db/docs/main.md +30 -0
- package/rules/js-bun-db/js/docs/index.md +2 -2
- package/rules/js-bun-db/lib/docs/index.md +2 -2
- package/rules/js-bun-db/main.mjs +20 -0
- package/rules/js-bun-redis/docs/fix.md +6 -6
- package/rules/js-bun-redis/docs/index.md +4 -3
- package/rules/js-bun-redis/docs/main.md +29 -0
- package/rules/js-bun-redis/js/docs/index.md +2 -2
- package/rules/js-bun-redis/lib/docs/index.md +2 -2
- package/rules/js-bun-redis/main.mjs +20 -0
- package/rules/js-lint/docs/fix.md +9 -9
- package/rules/js-lint/docs/index.md +4 -3
- 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 +4 -4
- 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/fix.md +3 -3
- package/rules/js-lint-ci/docs/index.md +4 -3
- package/rules/js-lint-ci/docs/main.md +27 -0
- package/rules/js-lint-ci/js/docs/index.md +2 -2
- package/rules/js-lint-ci/main.mjs +33 -0
- package/rules/js-mssql/docs/fix.md +5 -5
- package/rules/js-mssql/docs/index.md +4 -3
- package/rules/js-mssql/docs/main.md +30 -0
- package/rules/js-mssql/js/docs/index.md +2 -2
- package/rules/js-mssql/lib/docs/index.md +2 -2
- package/rules/js-mssql/main.mjs +20 -0
- package/rules/js-run/docs/fix.md +8 -8
- package/rules/js-run/docs/index.md +4 -3
- package/rules/js-run/docs/main.md +30 -0
- package/rules/js-run/js/docs/index.md +2 -2
- package/rules/js-run/lib/docs/index.md +7 -7
- package/rules/js-run/main.mjs +20 -0
- package/rules/k8s/docs/fix.md +4 -4
- package/rules/k8s/docs/index.md +4 -3
- 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/fix.md +7 -7
- package/rules/nginx-default-tpl/docs/index.md +4 -3
- package/rules/nginx-default-tpl/docs/main.md +30 -0
- package/rules/nginx-default-tpl/js/docs/index.md +2 -2
- package/rules/nginx-default-tpl/js/docs/template.md +2 -2
- package/rules/nginx-default-tpl/main.mjs +20 -0
- package/rules/npm-module/docs/fix.md +8 -8
- package/rules/npm-module/docs/index.md +4 -3
- package/rules/npm-module/docs/main.md +29 -0
- package/rules/npm-module/js/docs/index.md +5 -5
- package/rules/npm-module/js/docs/rule_meta.md +17 -16
- package/rules/npm-module/js/header_doc_pointer.mjs +1 -3
- package/rules/npm-module/js/rule_meta.mjs +13 -3
- package/rules/npm-module/main.mjs +20 -0
- package/rules/php/docs/fix.md +6 -6
- package/rules/php/docs/index.md +4 -3
- package/rules/php/docs/main.md +33 -0
- package/rules/php/js/docs/index.md +3 -3
- package/rules/php/js/docs/tooling.md +10 -10
- package/rules/php/{lint/lint.mjs → main.mjs} +32 -6
- package/rules/python/docs/fix.md +11 -11
- package/rules/python/docs/index.md +4 -3
- package/rules/python/docs/main.md +31 -0
- package/rules/python/js/docs/index.md +3 -3
- package/rules/python/js/docs/tooling.md +17 -17
- package/rules/python/{lint/lint.mjs → main.mjs} +31 -6
- package/rules/rego/docs/fix.md +5 -5
- package/rules/rego/docs/index.md +4 -3
- package/rules/rego/docs/main.md +37 -0
- package/rules/rego/js/docs/index.md +3 -3
- package/rules/rego/{lint/lint.mjs → main.mjs} +27 -5
- package/rules/release/docs/index.md +5 -4
- package/rules/release/docs/main.md +29 -0
- package/rules/release/docs/release.md +0 -3
- package/rules/release/lib/docs/index.md +4 -4
- package/rules/release/release.mdc +10 -0
- package/rules/rust/docs/fix.md +4 -4
- package/rules/rust/docs/index.md +4 -3
- package/rules/rust/docs/main.md +27 -0
- package/rules/rust/js/docs/index.md +3 -3
- package/rules/rust/lib/docs/index.md +2 -2
- package/rules/rust/{js/lint.mjs → main.mjs} +27 -4
- package/rules/security/docs/fix.md +6 -6
- package/rules/security/docs/index.md +4 -3
- package/rules/security/docs/main.md +28 -0
- package/rules/security/js/docs/index.md +4 -4
- package/rules/security/main.mjs +45 -0
- package/rules/style-lint/docs/fix.md +3 -3
- package/rules/style-lint/docs/index.md +4 -3
- package/rules/style-lint/docs/main.md +29 -0
- package/rules/style-lint/js/docs/index.md +3 -3
- package/rules/style-lint/{js/lint.mjs → main.mjs} +19 -1
- package/rules/tauri/docs/fix.md +11 -11
- package/rules/tauri/docs/index.md +4 -3
- package/rules/tauri/docs/main.md +29 -0
- package/rules/tauri/js/docs/index.md +3 -3
- package/rules/tauri/main.mjs +20 -0
- package/rules/test/docs/fix.md +5 -5
- package/rules/test/docs/index.md +4 -3
- package/rules/test/docs/main.md +30 -0
- package/rules/test/js/data/stryker_config/docs/index.md +4 -4
- package/rules/test/js/data/vitest_config/docs/index.md +2 -2
- package/rules/test/js/docs/index.md +7 -7
- package/rules/test/main.mjs +20 -0
- package/rules/text/docs/fix.md +11 -11
- package/rules/text/docs/index.md +4 -3
- package/rules/text/docs/main.md +29 -0
- package/rules/text/{lint → js}/cspell-fix.mjs +7 -2
- 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 +8 -4
- 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} +41 -10
- package/rules/tool-surface/docs/index.md +4 -3
- package/rules/tool-surface/docs/main.md +29 -0
- package/rules/tool-surface/main.mjs +20 -0
- package/rules/tool-surface/meta.json +6 -1
- package/rules/vue/docs/fix.md +6 -6
- package/rules/vue/docs/index.md +4 -3
- package/rules/vue/docs/main.md +29 -0
- package/rules/vue/js/docs/index.md +2 -2
- package/rules/vue/lib/docs/index.md +2 -2
- package/rules/vue/main.mjs +20 -0
- package/rules/worktree/docs/fix.md +11 -11
- package/rules/worktree/docs/index.md +4 -3
- package/rules/worktree/docs/main.md +28 -0
- package/rules/worktree/main.mjs +20 -0
- package/scripts/coverage-classify/docs/index.md +6 -6
- package/scripts/dispatcher/docs/index.md +2 -2
- package/scripts/docs/index.md +16 -15
- 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 +36 -35
- 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 +29 -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/analyze-escalation.mjs +4 -1
- package/scripts/lib/fix/docs/index.md +11 -10
- package/scripts/lib/fix/docs/orchestrator.md +23 -18
- package/scripts/lib/fix/docs/run-conformance-check.md +33 -0
- package/scripts/lib/fix/docs/run-fix-check.md +3 -3
- package/scripts/lib/fix/docs/t0.md +10 -9
- package/scripts/lib/fix/orchestrator.mjs +31 -8
- package/scripts/lib/fix/{run-fix-check.mjs → run-conformance-check.mjs} +13 -13
- package/scripts/lib/fix/t0.mjs +6 -3
- 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/{rules/lint/js/orchestrate.mjs → scripts/lib/run-lint.mjs} +42 -22
- 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/scripts/utils/docs/index.md +14 -14
- package/skills/doc-aggregate/js/docs/index.md +3 -3
- package/skills/doc-files/.changes/260612-0002.md +1 -0
- package/skills/doc-files/.changes/260612-0006.md +1 -0
- package/skills/doc-files/.changes/260612-0008.md +1 -0
- package/skills/doc-files/.changes/260612-0012.md +1 -0
- package/skills/doc-files/.changes/260612-0031.md +1 -0
- package/skills/doc-files/.changes/260612-0036.md +1 -0
- package/skills/doc-files/.changes/260612-0114.md +1 -0
- package/skills/start-check/js/docs/index.md +2 -2
- package/skills/taze/js/docs/index.md +2 -2
- package/types/bin/n-cursor.d.ts +1 -1
- 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}/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,219 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/php/lint/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: cafd914f
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
Модуль `lint.mjs` реалізує крок `lint-php` згідно з правилом `php.mdc`. Він виконує статичний та безпековий аналіз PHP-проєкту, який лежить у поточному робочому каталозі (`process.cwd()`), послідовно прогоняючи такі інструменти:
|
|
10
|
-
|
|
11
|
-
1. `composer audit --no-interaction` — обовʼязковий аудит залежностей через Composer.
|
|
12
|
-
2. `vendor/bin/php-cs-fixer fix --dry-run --diff` — перевірка стилю без модифікації файлів.
|
|
13
|
-
3. `vendor/bin/phpcs --standard=Security ...` — перевірка зі стандартом Security для типових директорій коду.
|
|
14
|
-
4. `vendor/bin/phpstan analyse --no-progress` — статичний аналіз.
|
|
15
|
-
5. `vendor/bin/psalm --no-cache` — додатковий статичний аналіз.
|
|
16
|
-
|
|
17
|
-
Ключові властивості модуля:
|
|
18
|
-
|
|
19
|
-
- Якщо в корені репозиторію **немає** `composer.json` — скрипт нічого не запускає й завершується успіхом (`pass` + код виходу 0).
|
|
20
|
-
- Якщо `composer.json` є, але `composer` недоступний у `PATH` — це фатальна помилка (`fail`).
|
|
21
|
-
- Інструменти з `vendor/bin/*` запускаються лише за наявності відповідного бінарника; відсутній інструмент **не** є помилкою, лише пропускається з відповідним `pass`-повідомленням.
|
|
22
|
-
- Помилка будь-якого запущеного інструмента (ненульовий exit code) призводить до негайного завершення з кодом помилки — наступні кроки **не** виконуються (fail-fast).
|
|
23
|
-
- Результат акумулюється через `createCheckReporter()`, а підсумковий код виходу дає `reporter.getExitCode()`.
|
|
24
|
-
|
|
25
|
-
Файл одночасно є модулем (з експортами для повторного використання й тестування) та CLI-точкою входу (через `isRunAsCli(import.meta.url)`).
|
|
26
|
-
|
|
27
|
-
## Експорти / API
|
|
28
|
-
|
|
29
|
-
Модуль експортує дві функції:
|
|
30
|
-
|
|
31
|
-
- `getPhpcsCodePaths(root: string): string[]` — обчислює список директорій для PHPCS.
|
|
32
|
-
- `run(): number` — основна точка входу; повертає код виходу (0 — OK, 1 — є помилки).
|
|
33
|
-
|
|
34
|
-
Функції `vendorBin`, `runTool` і вкладена `runOptionalVendorTool` є приватними (не експортуються) і використовуються тільки всередині модуля.
|
|
35
|
-
|
|
36
|
-
Коли модуль виконується безпосередньо як CLI (через `node` чи `bun`), у блоці `if (isRunAsCli(import.meta.url))` викликається `run()`, а результат присвоюється `process.exitCode`.
|
|
37
|
-
|
|
38
|
-
## Функції
|
|
39
|
-
|
|
40
|
-
### `getPhpcsCodePaths(root)`
|
|
41
|
-
|
|
42
|
-
Сигнатура: `getPhpcsCodePaths(root: string): string[]`
|
|
43
|
-
|
|
44
|
-
Параметри:
|
|
45
|
-
|
|
46
|
-
- `root` — абсолютний шлях до кореня репозиторію.
|
|
47
|
-
|
|
48
|
-
Повертає: масив відносних шляхів (рядків) до директорій, які варто передати у `phpcs`.
|
|
49
|
-
|
|
50
|
-
Алгоритм:
|
|
51
|
-
|
|
52
|
-
1. Перебирає константу `PHPCS_CODE_DIR_CANDIDATES = ['app', 'src', 'lib', 'public', 'www']`.
|
|
53
|
-
2. Для кожного імені `d` будує абсолютний шлях `join(root, d)` і перевіряє, що шлях існує **і** є директорією (`existsSync` + `statSync(...).isDirectory()`).
|
|
54
|
-
3. Якщо знайдено хоча б одну директорію — повертає масив усіх знайдених імен (як **відносні** імена, не абсолютні шляхи).
|
|
55
|
-
4. Якщо жодної не знайдено — повертає `['.']` (тобто PHPCS буде запущений по всьому кореню).
|
|
56
|
-
|
|
57
|
-
Side effects: лише читання файлової системи через `existsSync`/`statSync`. Файлів не модифікує.
|
|
58
|
-
|
|
59
|
-
### `vendorBin(root, name)` (private)
|
|
60
|
-
|
|
61
|
-
Сигнатура: `vendorBin(root: string, name: string): string | null`
|
|
62
|
-
|
|
63
|
-
Параметри:
|
|
64
|
-
|
|
65
|
-
- `root` — корінь репозиторію.
|
|
66
|
-
- `name` — імʼя файла у `vendor/bin` (наприклад, `phpstan`).
|
|
67
|
-
|
|
68
|
-
Повертає: абсолютний шлях `<root>/vendor/bin/<name>`, якщо файл існує; інакше `null`.
|
|
69
|
-
|
|
70
|
-
Side effects: `existsSync` (лише читання).
|
|
71
|
-
|
|
72
|
-
### `runTool(label, abs, args, pass, fail)` (private)
|
|
73
|
-
|
|
74
|
-
Сигнатура: `runTool(label: string, abs: string, args: string[], pass: (msg: string) => void, fail: (msg: string) => void): boolean`
|
|
75
|
-
|
|
76
|
-
Параметри:
|
|
77
|
-
|
|
78
|
-
- `label` — людиночитна назва кроку (наприклад, `"PHPStan"`), використовується в повідомленнях.
|
|
79
|
-
- `abs` — абсолютний шлях до CLI-бінарника.
|
|
80
|
-
- `args` — аргументи командного рядка.
|
|
81
|
-
- `pass` — callback для запису успіху в репортер.
|
|
82
|
-
- `fail` — callback для запису помилки в репортер.
|
|
83
|
-
|
|
84
|
-
Повертає: `true`, якщо процес завершився з кодом 0; `false` — інакше.
|
|
85
|
-
|
|
86
|
-
Алгоритм:
|
|
87
|
-
|
|
88
|
-
1. Запускає `spawnSync(abs, args, { stdio: 'inherit', shell: false })`. `stdio: 'inherit'` означає, що stdout/stderr дитячого процесу пробрасуються користувачу напряму.
|
|
89
|
-
2. Якщо `r.status === 0` — викликає `pass(\`lint-php: ${label} — OK\`)`і повертає`true`.
|
|
90
|
-
3. Інакше визначає код: якщо `r.status` — число, то воно; інакше `1` (захист від `null`, який трапляється, наприклад, при сигналі або провалі запуску).
|
|
91
|
-
4. Викликає `fail(\`lint-php: ${label} — помилка (код ${code}, php.mdc)\`)`і повертає`false`.
|
|
92
|
-
|
|
93
|
-
Side effects: запускає дочірній процес, успадковує stdio батьківського процесу.
|
|
94
|
-
|
|
95
|
-
### `run()`
|
|
96
|
-
|
|
97
|
-
Сигнатура: `run(): number`
|
|
98
|
-
|
|
99
|
-
Параметри: немає.
|
|
100
|
-
|
|
101
|
-
Повертає: код виходу — `0` (успіх) або `1` (хоча б одна помилка). Реальний код визначає `reporter.getExitCode()`.
|
|
102
|
-
|
|
103
|
-
Алгоритм (по кроках):
|
|
104
|
-
|
|
105
|
-
1. Створює репортер: `const reporter = createCheckReporter()`; деструктуризує `pass` і `fail` з нього.
|
|
106
|
-
2. Бере поточний робочий каталог: `const root = process.cwd()`.
|
|
107
|
-
3. Якщо `composer.json` у корені **відсутній** — викликає `pass('lint-php: немає composer.json у корені — кроки PHP пропущено')` і повертає `reporter.getExitCode()` (фактично 0).
|
|
108
|
-
4. Резолвить бінарник `composer` через `resolveCmd('composer')`. Якщо не знайдено — викликає `fail` з повідомленням про відсутність у `PATH` і виходить.
|
|
109
|
-
5. Запускає `composer audit --no-interaction` через `runTool`. Якщо крок провалився — негайно повертає поточний код виходу (далі нічого не виконується).
|
|
110
|
-
6. Оголошує вкладену функцію `runOptionalVendorTool(binName, label, args): boolean` (див. нижче).
|
|
111
|
-
7. Послідовно викликає `runOptionalVendorTool` для:
|
|
112
|
-
- `php-cs-fixer` → label `"PHP-CS-Fixer (dry-run)"`, args `['fix', '--dry-run', '--diff']`.
|
|
113
|
-
- `phpcs` → label `"phpcs (Security)"`, args `['--standard=Security', '--ignore=*/vendor/*,*/node_modules/*,*/.git/*', ...getPhpcsCodePaths(root)]`.
|
|
114
|
-
- `phpstan` → label `"PHPStan"`, args `['analyse', '--no-progress']`.
|
|
115
|
-
- `psalm` → label `"Psalm"`, args `['--no-cache']`.
|
|
116
|
-
8. Після кожного кроку, якщо він повернув `false` (тобто `runTool` зафейлився; пропуск через відсутність бінарника `false` **не** дає), функція негайно повертає `reporter.getExitCode()`.
|
|
117
|
-
9. Якщо всі кроки успішні — повертає `reporter.getExitCode()`.
|
|
118
|
-
|
|
119
|
-
Порядок кроків зафіксований: PHP-CS-Fixer → PHPCS → PHPStan → Psalm. Перший провал зупиняє конвеєр.
|
|
120
|
-
|
|
121
|
-
Side effects:
|
|
122
|
-
|
|
123
|
-
- Читає `process.cwd()` і файли в ньому.
|
|
124
|
-
- Резолвить `composer` через `PATH`.
|
|
125
|
-
- Спавнить дочірні процеси з успадкованим stdio.
|
|
126
|
-
- Не модифікує жодних файлів (PHP-CS-Fixer запускається в `--dry-run --diff`).
|
|
127
|
-
- Підсумково повертає число; не викликає `process.exit` самостійно (це робить CLI-обгортка через `process.exitCode`).
|
|
128
|
-
|
|
129
|
-
### `runOptionalVendorTool(binName, label, args)` (вкладена в `run`)
|
|
130
|
-
|
|
131
|
-
Сигнатура: `runOptionalVendorTool(binName: string, label: string, args: string[]): boolean`
|
|
132
|
-
|
|
133
|
-
Параметри:
|
|
134
|
-
|
|
135
|
-
- `binName` — імʼя файла у `vendor/bin`.
|
|
136
|
-
- `label` — назва кроку для повідомлень.
|
|
137
|
-
- `args` — аргументи CLI.
|
|
138
|
-
|
|
139
|
-
Повертає: `true`, якщо крок успішний **або** пропущений (бінарника немає); `false`, якщо крок виконано й він зафейлився.
|
|
140
|
-
|
|
141
|
-
Алгоритм:
|
|
142
|
-
|
|
143
|
-
1. Резолвить абсолютний шлях через `vendorBin(root, binName)`.
|
|
144
|
-
2. Якщо `null` — викликає `pass(\`lint-php: vendor/bin/${binName} — відсутній, крок пропущено\`)`і повертає`true`.
|
|
145
|
-
3. Інакше делегує `runTool(label, abs, args, pass, fail)` і повертає його результат.
|
|
146
|
-
|
|
147
|
-
Side effects: ті самі, що в `vendorBin` + `runTool` для виконуваного кроку.
|
|
148
|
-
|
|
149
|
-
## Залежності
|
|
150
|
-
|
|
151
|
-
### Стандартна бібліотека Node.js
|
|
152
|
-
|
|
153
|
-
- `node:child_process` → `spawnSync` — синхронний запуск дочірніх процесів.
|
|
154
|
-
- `node:fs` → `existsSync`, `statSync` — перевірка існування файлів і визначення, чи це директорія.
|
|
155
|
-
- `node:path` → `join`, `resolve` — побудова шляхів (`join` — для відносних, `resolve` — для абсолютних).
|
|
156
|
-
|
|
157
|
-
### Внутрішні модулі репозиторію (відносні шляхи)
|
|
158
|
-
|
|
159
|
-
- `../../../scripts/cli-entry.mjs` → `isRunAsCli` — детектор того, що поточний модуль запущений як CLI (порівнює `import.meta.url` зі стартовим файлом).
|
|
160
|
-
- `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера з полями `pass`, `fail`, `getExitCode()`. Усі повідомлення формату `lint-php: <label> — ...` йдуть саме через нього.
|
|
161
|
-
- `../../../scripts/utils/resolve-cmd.mjs` → `resolveCmd` — пошук бінарника в `PATH` (повертає шлях або `null`/`undefined`).
|
|
162
|
-
|
|
163
|
-
### Зовнішні CLI-залежності (виконувані файли)
|
|
164
|
-
|
|
165
|
-
- `composer` — має бути у `PATH`, якщо в проєкті є `composer.json`.
|
|
166
|
-
- `vendor/bin/php-cs-fixer`, `vendor/bin/phpcs`, `vendor/bin/phpstan`, `vendor/bin/psalm` — опційні; відсутній бінарник пропускає відповідний крок.
|
|
167
|
-
|
|
168
|
-
### Правило / контекст
|
|
169
|
-
|
|
170
|
-
- `php.mdc` — правило з `.cursor/rules/`, на яке посилається модуль (тексти повідомлень містять `php.mdc`).
|
|
171
|
-
|
|
172
|
-
## Потік виконання / Використання
|
|
173
|
-
|
|
174
|
-
### Запуск як CLI
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
node npm/rules/php/lint/lint.mjs
|
|
178
|
-
# або через bun
|
|
179
|
-
bun npm/rules/php/lint/lint.mjs
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
При CLI-запуску виконується блок:
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
if (isRunAsCli(import.meta.url)) {
|
|
186
|
-
process.exitCode = run()
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Це означає, що процес завершиться з кодом, що повернула `run()` (0 або 1). Викид `throw` не очікується — усі помилки інструментів повідомляються через `fail`, а не через виключення.
|
|
191
|
-
|
|
192
|
-
### Імпорт як модуля
|
|
193
|
-
|
|
194
|
-
```js
|
|
195
|
-
import { run, getPhpcsCodePaths } from './lint.mjs'
|
|
196
|
-
|
|
197
|
-
const exitCode = run()
|
|
198
|
-
if (exitCode !== 0) {
|
|
199
|
-
// обробка помилки
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
`getPhpcsCodePaths` корисна для тестування або для повторного використання логіки вибору директорій.
|
|
204
|
-
|
|
205
|
-
### Сценарії
|
|
206
|
-
|
|
207
|
-
1. **Немає `composer.json`** — повертає 0, нічого не запускає, пише в репортер `pass`-повідомлення.
|
|
208
|
-
2. **Є `composer.json`, але немає `composer`** — повертає 1, у репортері є `fail`.
|
|
209
|
-
3. **Є `composer.json` і `composer`, немає жодного `vendor/bin/*`** — запускається лише `composer audit`; якщо він пройде, повертає 0, інші кроки відмічаються як пропущені.
|
|
210
|
-
4. **Усі інструменти встановлені** — послідовний прогін: `composer audit` → `php-cs-fixer` → `phpcs` (за директоріями з `getPhpcsCodePaths`) → `phpstan` → `psalm`. Будь-який ненульовий exit-code дочірнього процесу перериває ланцюг і повертає 1.
|
|
211
|
-
5. **`composer.json` є, директорій `app`/`src`/`lib`/`public`/`www` немає** — PHPCS отримує єдиний шлях `.`.
|
|
212
|
-
|
|
213
|
-
### Особливості
|
|
214
|
-
|
|
215
|
-
- `spawnSync` запускається з `shell: false` — параметри передаються як масив, shell-інʼєкції неможливі.
|
|
216
|
-
- `stdio: 'inherit'` — повний вивід інструментів іде в термінал користувача; репортер додає лише підсумкові `pass/fail`-рядки.
|
|
217
|
-
- Fail-fast: модуль не агрегує помилки кількох інструментів; на першій помилці виходить.
|
|
218
|
-
- Усі повідомлення українською, із префіксом `lint-php:` для легкої грепабельності.
|
|
219
|
-
- Функція `run` не приймає аргументів — корінь визначається через `process.cwd()`, що дозволяє запускати її з будь-якого workspace без передавання шляху.
|
package/rules/python/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
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/python/js/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: a0d17a44
|
|
7
|
-
score: 100
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Оркестраторний адаптер правила `python` для `n-cursor lint`. Делегує перевірку наявній CLI-формі (`runLintPython` із `../lint/lint.mjs`). Режиму на рівні окремих файлів немає — `uv`/`ruff`/`mypy` працюють по всьому проєкту, тож параметр `files` ігнорується. За відсутності `pyproject.toml` у корені крок завершується успіхом без запуску інструментів.
|
|
11
|
-
|
|
12
|
-
## Поведінка
|
|
13
|
-
|
|
14
|
-
1. Викликає CLI-форму python-лінтера для всього проєкту.
|
|
15
|
-
2. У `readOnly` пробрасує прапорець далі: `ruff` без `--fix`, `ruff format --check` (нуль мутацій для CI).
|
|
16
|
-
3. Повертає код виходу інструменту.
|
|
17
|
-
|
|
18
|
-
## Гарантії поведінки
|
|
19
|
-
|
|
20
|
-
- Read-only за наявності `readOnly`: інструменти не мутують робоче дерево.
|
|
21
|
-
- Не звертається до мережі (uv-кроки можуть, але це поведінка делегата, не цього модуля).
|
package/rules/python/js/lint.mjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** @see ./docs/lint.md */
|
|
2
|
-
import { runLintPython } from '../lint/lint.mjs'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Ci-крок python: делегує у наявний CLI правила (per-file режиму немає — `files` ігнорується;
|
|
6
|
-
* uv/ruff/mypy працюють по всьому проєкту). Без `pyproject.toml` крок — no-op (exit 0).
|
|
7
|
-
* @param {string[] | undefined} _files ігнорується (whole-project аналіз)
|
|
8
|
-
* @param {string} [_cwd] корінь (CLI бере process.cwd())
|
|
9
|
-
* @param {{ readOnly?: boolean }} [opts] readOnly → ruff без `--fix`, format `--check` (нуль мутацій)
|
|
10
|
-
* @returns {Promise<number>} exit code
|
|
11
|
-
*/
|
|
12
|
-
export function lint(_files, _cwd, opts = {}) {
|
|
13
|
-
return runLintPython({ readOnly: opts.readOnly === true })
|
|
14
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/python/lint/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 61a1e3c3
|
|
7
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
-
score: 90
|
|
9
|
-
issues: internal-name:runStandardLint,judge:inaccurate:0.99
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
Забезпечує виконання обов'язкових кроків для валідації Python-коду відповідно до правил, визначених у `python.mdc`, використовуючи інструменти з [uv](https://docs.astral.sh/uv/). Якщо `pyproject.toml` відсутній у корені, процес завершується з кодом 0. Якщо файл присутній, але `uv` не знайдено в PATH, це розглядається як помилка. Обов'язкові кроки включають перевірку актуальності lock-файлу (`uv lock --check`) та збірку середовища (`uv sync --frozen`). Опціональні лінтери (`ruff`, `mypy`) запускаються лише за умови їх доступності через `uv run`. Цей процес реалізує канон патерну `lint-*` (серіалізація через `runStandardLint`).
|
|
16
|
-
|
|
17
|
-
## Поведінка
|
|
18
|
-
|
|
19
|
-
runLintPythonSteps виконує обов'язкові кроки для Python-лінтування за правилом python.mdc на базі [uv](https://docs.astral.sh/uv/). Якщо `pyproject.toml` відсутній, кроки пропускаються. Якщо `uv` не знайдено, виникає помилка. Виконує перевірку актуальності lock-файлу (`uv lock --check`) та збірку середовища (`uv sync --frozen`). Опціонально запускає лінтери (`ruff`, `mypy`) через `uv run`, якщо вони доступні.
|
|
20
|
-
runLintPython серіалізує запуск кроків лінтування Python через механізм `runStandardLint` та повертає код виходу.
|
|
21
|
-
|
|
22
|
-
## Публічний API
|
|
23
|
-
|
|
24
|
-
runLintPythonSteps — Виконує внутрішні етапи перевірки коду Python без блокування.
|
|
25
|
-
runLintPython — Виконує публічну команду перевірки коду Python, забезпечуючи унікальність виконання на основі стану Git-дерева та використовуючи механізм блокування.
|
|
26
|
-
|
|
27
|
-
## Гарантії поведінки
|
|
28
|
-
|
|
29
|
-
- Read-only: не виконує операцій запису (ФС/БД).
|
package/rules/rego/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
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/rego/js/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 8c033173
|
|
7
|
-
score: 100
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Файл виконує передачу перевірок у наявні CLI правила. Функція повертає Promise з кодом виходу.
|
|
11
|
-
|
|
12
|
-
## Поведінка
|
|
13
|
-
|
|
14
|
-
1. lint приймає масив рядків або undefined
|
|
15
|
-
2. lint делегує виконання у CLI правила
|
|
16
|
-
3. lint повертає Promise з кодом виходу
|
|
17
|
-
|
|
18
|
-
## Гарантії поведінки
|
|
19
|
-
|
|
20
|
-
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
21
|
-
- Не звертається до мережі.
|
package/rules/rego/js/lint.mjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ci-крок rego: делегує у наявний CLI правила (per-file режиму немає — `files` ігнорується).
|
|
3
|
-
*/
|
|
4
|
-
import { runLintRego } from '../lint/lint.mjs'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {string[] | undefined} _files ігнорується (whole-repo аналіз)
|
|
8
|
-
* @returns {Promise<number>} exit code
|
|
9
|
-
*/
|
|
10
|
-
export function lint(_files) {
|
|
11
|
-
return runLintRego()
|
|
12
|
-
}
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/rego/lint/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 1059537a
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
Модуль реалізує лінт-крок для Rego-полісі пакета `@nitra/cursor`, який живуть у каталозі
|
|
10
|
-
`npm/rules/<id>/policy/<concern>/`. Він послідовно запускає три інструменти й повертає код
|
|
11
|
-
виходу першого, що впав:
|
|
12
|
-
|
|
13
|
-
1. `opa check --strict` — компіляція Rego з типами та строгим режимом (ловить мертвий код,
|
|
14
|
-
неоднозначні правила, незадекларовані змінні).
|
|
15
|
-
2. `regal lint` — статичний лінтер стилю/ідіоматичності Rego (v0-синтаксис, неявні set-rules,
|
|
16
|
-
відхилення від `rego.v1`, плюс правила категорій bugs/idiomatic/performance — див.
|
|
17
|
-
`https://docs.styra.com/regal`).
|
|
18
|
-
3. `conftest verify` — опційно: виконує `test_*` правила у `*_test.rego` (юніт-тести
|
|
19
|
-
полісі). Якщо `conftest` відсутній у `PATH`, крок пропускається без помилки (з
|
|
20
|
-
повідомленням, як його встановити).
|
|
21
|
-
|
|
22
|
-
Бінарники `opa` й `regal` резолвляться через `ensureTool` (`PATH` → локальний кеш → автоматичне
|
|
23
|
-
встановлення через `brew`/`scoop`/GitHub Release → hard-fail). `conftest` шукається лише в
|
|
24
|
-
`PATH` через `resolveCmd` без авто-install.
|
|
25
|
-
|
|
26
|
-
Канон патерну `lint-*` (серіалізація через `runStandardLint`, без прямого `withLock`) описаний
|
|
27
|
-
у `.cursor/rules/scripts.mdc`, секція «Серіалізація важких CLI-команд». Публічна CLI-форма
|
|
28
|
-
обгорнута в `withLock('lint-rego')` з дедуплікацією за станом git-дерева.
|
|
29
|
-
|
|
30
|
-
Файл одночасно є ESM-модулем (експортує функції) і CLI-точкою входу: якщо запущений напряму
|
|
31
|
-
(`isRunAsCli`), виконує `await runLintRego()` і виставляє `process.exitCode`.
|
|
32
|
-
|
|
33
|
-
## Експорти / API
|
|
34
|
-
|
|
35
|
-
Модуль експортує два символи:
|
|
36
|
-
|
|
37
|
-
| Експорт | Тип | Призначення |
|
|
38
|
-
| ------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
-
| `runLintRegoSteps` | named function | Внутрішня форма без локу: запускає три кроки в заданому `cwd`. Призначена для тестів у тимчасових каталогах, де потрібен fresh-прогон без дедуплікації. |
|
|
40
|
-
| `runLintRego` | named const (arrow function) | Публічна CLI-форма: серіалізує виконання через `withLock('lint-rego')` + дедуп за станом git-дерева (через `runStandardLint`). |
|
|
41
|
-
|
|
42
|
-
Також модуль має side-effect при прямому запуску: якщо `isRunAsCli(import.meta.url)` повертає
|
|
43
|
-
`true`, виконується `await runLintRego()` із записом результату в `process.exitCode`.
|
|
44
|
-
|
|
45
|
-
## Функції
|
|
46
|
-
|
|
47
|
-
### `runStep(bin, args, cwd)`
|
|
48
|
-
|
|
49
|
-
Внутрішня (не експортована) допоміжна функція. Запускає процес із успадкованим `stdio`, щоб
|
|
50
|
-
вивід виглядав як прямий виклик у shell, і пре-логує команду користувачу.
|
|
51
|
-
|
|
52
|
-
- **Сигнатура:** `runStep(bin: string, args: string[], cwd: string) => number`
|
|
53
|
-
- **Параметри:**
|
|
54
|
-
- `bin` — абсолютний шлях до бінарника (`opa`, `regal`, `conftest`).
|
|
55
|
-
- `args` — масив аргументів командного рядка.
|
|
56
|
-
- `cwd` — робочий каталог для дочірнього процесу.
|
|
57
|
-
- **Повертає:** код виходу (`0` — OK). Якщо `spawnSync` не зміг запустити бінарник
|
|
58
|
-
(`result.error`), повертає `1`.
|
|
59
|
-
- **Side effects:**
|
|
60
|
-
- Друкує рядок `▶ <bin> <args...>` у `stdout` (логування команди).
|
|
61
|
-
- У випадку помилки запуску пише `❌ Не вдалося запустити <bin>: <message>\n` у `stderr`.
|
|
62
|
-
- Породжує дочірній процес через `spawnSync` з `stdio: 'inherit'` і `env: process.env`
|
|
63
|
-
(наслідування поточного середовища).
|
|
64
|
-
|
|
65
|
-
### `runLintRegoSteps(cwd?)`
|
|
66
|
-
|
|
67
|
-
Експортована функція, що виконує послідовність кроків лінту без локу.
|
|
68
|
-
|
|
69
|
-
- **Сигнатура:** `runLintRegoSteps(cwd?: string) => number`
|
|
70
|
-
- **Параметри:**
|
|
71
|
-
- `cwd` — робочий каталог (за замовчуванням `process.cwd()`).
|
|
72
|
-
- **Повертає:** число — код виходу.
|
|
73
|
-
- `0` — усі кроки OK або жодної цілі не знайдено (skip).
|
|
74
|
-
- Ненульове — код виходу першого кроку, що впав (раннє повернення).
|
|
75
|
-
- **Алгоритм:**
|
|
76
|
-
1. Резолвить `root = resolve(cwd)`.
|
|
77
|
-
2. `opa = ensureTool('opa')` — гарантує наявність `opa` (інакше `ensureTool` hard-fail).
|
|
78
|
-
3. `regal = ensureTool('regal')` — те саме для `regal`.
|
|
79
|
-
4. Фільтрує `LINT_TARGETS` за наявністю на диску (через `existsSync`). Якщо порожньо —
|
|
80
|
-
повертає `0` (skip).
|
|
81
|
-
5. `runStep(opa, ['check', '--strict', ...targets], root)` — якщо `!== 0`, повертає цей код.
|
|
82
|
-
6. `runStep(regal, ['lint', ...targets], root)` — якщо `!== 0`, повертає цей код.
|
|
83
|
-
7. `conftest = resolveCmd('conftest')` — якщо `null`, друкує інформативне повідомлення про
|
|
84
|
-
пропуск кроку й рекомендацію зі встановлення, повертає `0`.
|
|
85
|
-
8. Інакше `runStep(conftest, ['verify', ...targets.flatMap(t => ['-p', t])], root)` —
|
|
86
|
-
повертає його код виходу.
|
|
87
|
-
- **Side effects:** виконує `ensureTool` (може встановити бінарник або hard-fail), породжує
|
|
88
|
-
дочірні процеси з успадкованим `stdio`, пише в `stdout`/`stderr`.
|
|
89
|
-
|
|
90
|
-
### `runLintRego()`
|
|
91
|
-
|
|
92
|
-
Експортована публічна CLI-форма (arrow-const).
|
|
93
|
-
|
|
94
|
-
- **Сигнатура:** `runLintRego() => Promise<number>`
|
|
95
|
-
- **Параметри:** немає.
|
|
96
|
-
- **Повертає:** `Promise<number>` — код виходу.
|
|
97
|
-
- **Поведінка:** делегує в `runStandardLint(import.meta.dirname, () => runLintRegoSteps())`.
|
|
98
|
-
`runStandardLint` забезпечує:
|
|
99
|
-
- Серіалізацію через `withLock('lint-rego')` (іменем серіалізатора виступає назва каталогу
|
|
100
|
-
`lint`, отримана з `import.meta.dirname` — конвенція `runStandardLint`).
|
|
101
|
-
- Дедуплікацію проти попереднього прогону за станом git-дерева.
|
|
102
|
-
- **Side effects:** через делегування — ті самі, що в `runLintRegoSteps`, плюс файлові
|
|
103
|
-
side-effects лок-файлу й кешу станів від `runStandardLint`.
|
|
104
|
-
|
|
105
|
-
### CLI-вхід (на верхньому рівні модуля)
|
|
106
|
-
|
|
107
|
-
```js
|
|
108
|
-
if (isRunAsCli(import.meta.url)) {
|
|
109
|
-
process.exitCode = await runLintRego()
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
- Виконується лише при прямому запуску модуля як скрипта (а не при імпорті).
|
|
114
|
-
- Очікує проміс `runLintRego()` і записує отриманий код у `process.exitCode` (не викликає
|
|
115
|
-
`process.exit` явно, щоб лог-флаш не обрізався).
|
|
116
|
-
|
|
117
|
-
## Залежності
|
|
118
|
-
|
|
119
|
-
### Стандартна бібліотека Node.js
|
|
120
|
-
|
|
121
|
-
- `node:child_process` → `spawnSync` — синхронний запуск дочірніх процесів із `stdio: 'inherit'`.
|
|
122
|
-
- `node:fs` → `existsSync` — перевірка наявності каталогів-цілей.
|
|
123
|
-
- `node:path` → `resolve` — нормалізація абсолютних шляхів.
|
|
124
|
-
|
|
125
|
-
### Внутрішні модулі (відносні шляхи від `npm/rules/rego/lint/lint.mjs`)
|
|
126
|
-
|
|
127
|
-
- `../../../scripts/cli-entry.mjs` → `isRunAsCli` — детектор «запущений напряму як CLI».
|
|
128
|
-
- `../../../scripts/lib/ensure-tool.mjs` → `ensureTool` — резолв бінарників (`PATH` → кеш →
|
|
129
|
-
авто-install brew/scoop/GitHub Release → hard-fail).
|
|
130
|
-
- `../../../scripts/utils/resolve-cmd.mjs` → `resolveCmd` — м'який пошук команди в `PATH`
|
|
131
|
-
(повертає шлях або `null`, без авто-install і без hard-fail).
|
|
132
|
-
- `../../../scripts/lib/run-standard-lint.mjs` → `runStandardLint` — обгортка з локом і
|
|
133
|
-
дедуплікацією для лінт-кроків.
|
|
134
|
-
|
|
135
|
-
### Зовнішні бінарники (системні)
|
|
136
|
-
|
|
137
|
-
- `opa` — обов'язковий, авто-install через `ensureTool` (Open Policy Agent CLI).
|
|
138
|
-
- `regal` — обов'язковий, авто-install через `ensureTool` (Styra Regal lint CLI).
|
|
139
|
-
- `conftest` — опційний, лише з `PATH` (без авто-install). За відсутності — `verify`
|
|
140
|
-
пропускається.
|
|
141
|
-
|
|
142
|
-
### Константи модуля
|
|
143
|
-
|
|
144
|
-
- `LINT_TARGETS = ['npm/rules']` — список відносних шляхів-цілей, що передаються в усі три
|
|
145
|
-
інструменти. Перед запуском фільтрується за `existsSync`.
|
|
146
|
-
|
|
147
|
-
## Потік виконання / Використання
|
|
148
|
-
|
|
149
|
-
### Як модуль (програмний імпорт)
|
|
150
|
-
|
|
151
|
-
```js
|
|
152
|
-
import { runLintRego, runLintRegoSteps } from './npm/rules/rego/lint/lint.mjs'
|
|
153
|
-
|
|
154
|
-
// CLI-форма (з локом і дедуплікацією) — рекомендована для оркестрації
|
|
155
|
-
const code = await runLintRego()
|
|
156
|
-
|
|
157
|
-
// Внутрішня форма (без локу) — для тестів у тимчасових каталогах
|
|
158
|
-
const codeFresh = runLintRegoSteps('/tmp/fixture-cwd')
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Як CLI (прямий запуск)
|
|
162
|
-
|
|
163
|
-
```sh
|
|
164
|
-
node npm/rules/rego/lint/lint.mjs
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
При прямому запуску модуль викликає `runLintRego()` і виставляє `process.exitCode` відповідно
|
|
168
|
-
до результату. Це дозволяє оркестратору лінту (наприклад, кореневому `bun run lint`)
|
|
169
|
-
підхопити цей файл як один із кроків і отримати правильний код виходу процесу.
|
|
170
|
-
|
|
171
|
-
### Логічний потік (один прогон `runLintRegoSteps`)
|
|
172
|
-
|
|
173
|
-
1. Резолв `cwd → root`.
|
|
174
|
-
2. `ensureTool('opa')` — повертає шлях до бінарника або hard-fail (з повідомленням
|
|
175
|
-
`ensureTool`).
|
|
176
|
-
3. `ensureTool('regal')` — те саме.
|
|
177
|
-
4. Перевірка цілей: `LINT_TARGETS.filter(existsSync)`. Порожньо → `return 0` (skip).
|
|
178
|
-
5. `opa check --strict <targets...>` → `runStep`. `!== 0` → early-return з цим кодом.
|
|
179
|
-
6. `regal lint <targets...>` → `runStep`. `!== 0` → early-return з цим кодом.
|
|
180
|
-
7. `resolveCmd('conftest')`:
|
|
181
|
-
- `null` → інформативний `console.log` із рекомендацією встановлення, `return 0`.
|
|
182
|
-
- інакше → `conftest verify -p <t1> -p <t2> ...` через `runStep`; повертається його код.
|
|
183
|
-
8. Повернутий код піднімається до `runLintRego` → у `runStandardLint` → у `process.exitCode`
|
|
184
|
-
(для CLI-режиму).
|
|
185
|
-
|
|
186
|
-
### Семантика помилок і пропусків
|
|
187
|
-
|
|
188
|
-
- **Усі цілі відсутні** → skip із кодом `0` (немає чого лінтити на ранніх стадіях/у мінімальних
|
|
189
|
-
фікстурах).
|
|
190
|
-
- **`opa`/`regal` відсутні** → hard-fail усередині `ensureTool` (без авто-install або з
|
|
191
|
-
невдалим авто-install).
|
|
192
|
-
- **`opa check` або `regal lint` повернули `!== 0`** → раннє повернення з цим кодом; наступні
|
|
193
|
-
кроки не виконуються.
|
|
194
|
-
- **`conftest` відсутній у `PATH`** → лог-нотатка про пропуск, фінальний код `0` (вважається
|
|
195
|
-
не помилкою — юніт-тести полісі опційні в локальному середовищі; у CI рекомендовано
|
|
196
|
-
встановлювати `conftest`).
|
|
197
|
-
- **`spawnSync` не зміг запустити бінарник** (`result.error`) → лог `❌ Не вдалося запустити
|
|
198
|
-
...` у `stderr`, `runStep` повертає `1`.
|
|
199
|
-
|
|
200
|
-
### Контекст у проєкті
|
|
201
|
-
|
|
202
|
-
- Цілі лінту — каталог `npm/rules` пакета `@nitra/cursor`, де живуть Rego-полісі у
|
|
203
|
-
`npm/rules/<id>/policy/<concern>/`. Усі три інструменти приймають один шлях і рекурсивно
|
|
204
|
-
знаходять `.rego`, ігноруючи інші розширення (наприклад, `target.json` чи template-фіх).
|
|
205
|
-
- `opa` додатково потрібен VS Code-розширенню `tsandall.opa` (LSP, format-on-save через
|
|
206
|
-
`opa fmt`) — деталі в `mdc/rego.mdc`.
|
|
207
|
-
- Канон патерну `lint-*` із серіалізацією через `runStandardLint` (а не прямий `withLock`) —
|
|
208
|
-
див. `.cursor/rules/scripts.mdc`, секція «Серіалізація важких CLI-команд».
|
package/rules/rust/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
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: lint.mjs
|
|
4
|
-
resource: npm/rules/rust/js/lint.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 5d7c4123
|
|
7
|
-
score: 100
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Оркестраторний адаптер правила `rust` для `n-cursor lint`: rustfmt + clippy через `cargo`. Запускається на `n-cursor lint rust`. За відсутності `Cargo.toml` у корені — no-op (вихід 0). `cargo`/`rustfmt`/`clippy` резолвляться з PATH (Rust toolchain через rustup), не з npm-залежностей; якщо `cargo` відсутній за наявного `Cargo.toml` — помилка.
|
|
11
|
-
|
|
12
|
-
## Поведінка
|
|
13
|
-
|
|
14
|
-
1. `readOnly` (CI): `cargo fmt --all -- --check` + `cargo clippy --all-targets --all-features -- -D warnings` — детект без мутацій.
|
|
15
|
-
2. fix-режим: `cargo fmt --all` + `cargo clippy --fix` + фінальний `cargo clippy … -D warnings`.
|
|
16
|
-
3. Перший ненульовий cargo-крок спиняє ланцюг і повертає його код.
|
|
17
|
-
|
|
18
|
-
## Гарантії поведінки
|
|
19
|
-
|
|
20
|
-
- Read-only за наявності `readOnly`: cargo не мутує робоче дерево (`--check`, без `--fix`).
|
|
21
|
-
- Не звертається до мережі напряму (cargo-кроки можуть тягнути crates, але це поведінка тулчейну).
|