@nitra/cursor 5.1.0 → 5.2.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 +22 -0
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +15 -9
- package/CHANGELOG.md +12 -1
- package/bin/n-cursor.js +73 -16
- package/docs/stryker.config.md +6 -0
- package/docs/vitest.config.md +6 -0
- package/lib/docs/llm.md +29 -0
- package/lib/docs/omlx.md +32 -0
- package/lib/llm.mjs +137 -0
- package/lib/omlx.mjs +49 -4
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +6 -0
- package/rules/abie/js/docs/applies.md +6 -0
- package/rules/abie/js/docs/env_dns.md +25 -22
- package/rules/abie/js/docs/firebase_hosting.md +6 -0
- package/rules/abie/js/docs/hc_pairing.md +21 -25
- package/rules/abie/js/docs/ua_http_route.md +27 -19
- package/rules/abie/js/docs/ua_node_selector.md +24 -19
- package/rules/abie/lib/docs/enabled.md +13 -7
- package/rules/abie/lib/docs/env-dns.md +9 -3
- package/rules/abie/lib/docs/hc-yaml.md +6 -0
- package/rules/abie/lib/docs/http-route.md +6 -0
- package/rules/abie/lib/docs/k8s-tree.md +6 -0
- package/rules/abie/lib/docs/kustomization-patches.md +6 -0
- package/rules/abie/lib/docs/overlay-paths.md +6 -0
- package/rules/abie/lib/docs/yaml.md +6 -0
- package/rules/adr/docs/fix.md +6 -0
- package/rules/adr/js/docs/hooks.md +29 -244
- package/rules/bun/docs/fix.md +6 -0
- package/rules/bun/js/docs/layout.md +37 -375
- package/rules/capacitor/docs/fix.md +22 -108
- package/rules/capacitor/js/docs/platforms.md +62 -268
- package/rules/changelog/docs/fix.md +6 -0
- package/rules/changelog/lib/docs/package-manifest.md +6 -0
- package/rules/ci4/docs/fix.md +23 -165
- package/rules/ci4/js/docs/marksman_config.md +9 -1
- package/rules/docker/docs/fix.md +6 -0
- package/rules/docker/js/docs/lint.md +55 -239
- package/rules/docker/lib/docs/docker-hadolint.md +6 -0
- package/rules/docker/lib/docs/docker-mirror.md +6 -0
- package/rules/docker/lib/docs/docker-native-addon.md +6 -0
- package/rules/docker/lib/docs/docker-nginx-user.md +6 -0
- package/rules/docker/lint/docs/lint.md +9 -1
- package/rules/efes/docs/fix.md +6 -0
- package/rules/ga/lint/docs/lint.md +6 -0
- package/rules/graphql/docs/fix.md +6 -0
- package/rules/graphql/lib/docs/graphql-gql-scan.md +6 -0
- package/rules/image-avif/docs/fix.md +6 -0
- package/rules/image-avif/js/docs/avif_generation.md +6 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +9 -3
- package/rules/js-bun-redis/lib/docs/redis-imports.md +6 -0
- package/rules/js-lint/js/docs/utils_imports.md +6 -0
- package/rules/js-lint-ci/docs/fix.md +7 -1
- package/rules/js-mssql/docs/fix.md +6 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +6 -0
- package/rules/js-run/docs/fix.md +6 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +6 -0
- package/rules/js-run/lib/docs/check-env-scan.md +6 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +6 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +6 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +6 -0
- package/rules/js-run/lib/docs/temporal-scan.md +6 -0
- package/rules/k8s/docs/fix.md +6 -0
- package/rules/k8s/lint/docs/lint.md +6 -0
- package/rules/nginx-default-tpl/docs/fix.md +6 -0
- package/rules/npm-module/js/docs/header_doc_pointer.md +7 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +2 -8
- package/rules/php/docs/fix.md +6 -0
- package/rules/php/lint/docs/lint.md +6 -0
- package/rules/python/docs/fix.md +6 -0
- package/rules/python/lint/docs/lint.md +6 -0
- package/rules/rego/lint/docs/lint.md +6 -0
- package/rules/release/docs/change.md +6 -0
- package/rules/release/docs/fix.md +6 -0
- package/rules/release/docs/release.md +6 -0
- package/rules/release/lib/docs/aggregate.md +6 -0
- package/rules/release/lib/docs/change-file.md +6 -0
- package/rules/release/lib/docs/fallback.md +6 -0
- package/rules/rust/lib/docs/has-cargo-toml.md +6 -0
- package/rules/security/docs/fix.md +7 -1
- package/rules/security/js/docs/lint.md +6 -0
- package/rules/style-lint/docs/fix.md +6 -0
- package/rules/tauri/docs/fix.md +6 -0
- package/rules/test/docs/fix.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +6 -0
- package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +6 -0
- package/rules/text/docs/fix.md +6 -0
- package/rules/text/lint/docs/lint.md +6 -0
- package/rules/text/lint/docs/run-dotenv-linter.md +6 -0
- package/rules/text/lint/docs/run-shellcheck.md +6 -0
- package/rules/text/lint/docs/run-v8r.md +6 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +6 -0
- package/scripts/coverage-classify/cache.mjs +1 -1
- package/scripts/coverage-classify/docs/apply.md +6 -0
- package/scripts/coverage-classify/docs/cache.md +6 -0
- package/scripts/coverage-classify/docs/prompt.md +6 -0
- package/scripts/coverage-classify/docs/verdict-schema.md +6 -0
- package/scripts/coverage-classify/prompt.mjs +1 -1
- package/scripts/coverage-fix-extract.mjs +1 -1
- package/scripts/coverage-fix.mjs +2 -1
- package/scripts/docs/auto-skills.md +6 -0
- package/scripts/docs/build-agents-commands.md +7 -1
- package/scripts/docs/cli-entry.md +6 -0
- package/scripts/docs/coverage-fix-extract.md +6 -0
- package/scripts/docs/coverage-fix.md +6 -0
- package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +6 -0
- package/scripts/docs/lint-cli.md +6 -0
- package/scripts/docs/post-tool-use-fix.md +6 -0
- package/scripts/docs/rename-yaml-extensions.md +6 -0
- package/scripts/docs/skills-cli.md +6 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +6 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +6 -0
- package/scripts/docs/worktree-cli.md +6 -0
- package/scripts/lib/docs/assert-project-root.md +6 -0
- package/scripts/lib/docs/check-mdc-template-refs.md +6 -0
- package/scripts/lib/docs/check-reporter.md +6 -0
- package/scripts/lib/docs/diff-added-lines.md +6 -0
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +6 -0
- package/scripts/lib/docs/discover-checkable-rules.md +6 -0
- package/scripts/lib/docs/ensure-tool.md +6 -0
- package/scripts/lib/docs/generated-markdown.md +6 -0
- package/scripts/lib/docs/gha-workflow.md +6 -0
- package/scripts/lib/docs/inline-template-links.md +6 -0
- package/scripts/lib/docs/list-rule-ids.md +6 -0
- package/scripts/lib/docs/load-cursor-config.md +6 -0
- package/scripts/lib/docs/mirror-parity.md +6 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +6 -0
- package/scripts/lib/docs/resolve-target-files.md +6 -0
- package/scripts/lib/docs/root-notice.md +6 -0
- package/scripts/lib/docs/rule-meta-helpers.md +6 -0
- package/scripts/lib/docs/rule-meta.md +6 -0
- package/scripts/lib/docs/run-conftest-batch.md +6 -0
- package/scripts/lib/docs/run-lint-step.md +6 -0
- package/scripts/lib/docs/run-rule-cli.md +6 -0
- package/scripts/lib/docs/run-rule.md +6 -0
- package/scripts/lib/docs/run-standard-lint.md +6 -0
- package/scripts/lib/docs/run-standard-rule.md +6 -0
- package/scripts/lib/docs/skill-meta.md +6 -0
- package/scripts/lib/docs/template.md +6 -0
- package/scripts/lib/docs/timing-summary.md +6 -0
- package/scripts/lib/docs/workspaces.md +6 -0
- package/scripts/lib/docs/worktree-notice.md +6 -0
- package/scripts/lib/docs/worktree.md +6 -0
- package/scripts/lib/mirror-parity.mjs +1 -1
- package/scripts/lib/root-notice.mjs +1 -1
- package/scripts/lib/worktree-notice.mjs +5 -5
- package/scripts/lib/worktree.mjs +1 -1
- package/scripts/sync-claude-config.mjs +3 -0
- package/scripts/utils/docs/ast-scan-utils.md +6 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +6 -0
- package/scripts/utils/docs/find-package-json-paths.md +6 -0
- package/scripts/utils/docs/lock-cache-dir.md +6 -0
- package/scripts/utils/docs/pass.md +6 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +6 -0
- package/scripts/utils/docs/resolve-cmd.md +6 -0
- package/scripts/utils/docs/resolve-js-root.md +6 -0
- package/scripts/utils/docs/test-helpers.md +6 -0
- package/scripts/utils/docs/walk-cache.md +6 -0
- package/scripts/utils/docs/walkDir.md +6 -0
- package/scripts/utils/docs/worktree-fingerprint.md +6 -0
- package/scripts/utils/resolve-js-root.mjs +1 -1
- package/skills/doc-aggregate/SKILL.md +129 -0
- package/skills/doc-aggregate/js/docgen-ignore.mjs +9 -0
- package/skills/{docgen → doc-aggregate}/js/docgen-scan.mjs +22 -67
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +21 -0
- package/skills/doc-files/SKILL.md +100 -0
- package/skills/doc-files/js/docgen-crc.mjs +164 -0
- package/skills/{docgen → doc-files}/js/docgen-extract-anchors.mjs +20 -11
- package/skills/{docgen → doc-files}/js/docgen-extract.mjs +15 -9
- package/skills/doc-files/js/docgen-files-batch.mjs +181 -0
- package/skills/doc-files/js/docgen-gen.mjs +291 -0
- package/skills/{docgen → doc-files}/js/docgen-prompts.mjs +43 -40
- package/skills/doc-files/js/docgen-scan.mjs +298 -0
- package/skills/doc-files/js/docs/docgen-crc.md +32 -0
- package/skills/doc-files/js/docs/docgen-extract-anchors.md +27 -0
- package/skills/doc-files/js/docs/docgen-extract.md +29 -0
- package/skills/doc-files/js/docs/docgen-files-batch.md +25 -0
- package/skills/doc-files/js/docs/docgen-gen.md +30 -0
- package/skills/doc-files/js/docs/docgen-prompts.md +32 -0
- package/skills/doc-files/js/docs/docgen-scan.md +25 -0
- package/skills/doc-files/meta.json +1 -0
- package/skills/fix/js/docs/llm-worker.md +6 -0
- package/skills/fix/js/docs/orchestrator.md +6 -0
- package/skills/fix/js/llm-worker.mjs +3 -3
- package/skills/fix/js/orchestrator.mjs +1 -1
- package/skills/start-check/js/check.mjs +5 -3
- package/skills/start-check/js/docs/check.md +6 -0
- package/skills/docgen/SKILL.md +0 -224
- package/skills/docgen/bench/etalon/firebase_hosting.md +0 -19
- package/skills/docgen/bench/etalon/k8s-tree.md +0 -24
- package/skills/docgen/bench/etalon/overlay-paths.md +0 -24
- package/skills/docgen/js/docgen-batch-omlx.mjs +0 -82
- package/skills/docgen/js/docgen-batch.mjs +0 -95
- package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +0 -95
- package/skills/docgen/js/docgen-gen.mjs +0 -306
- package/skills/docgen/js/docs/docgen-extract.md +0 -28
- package/skills/docgen/js/docs/docgen-gen.md +0 -41
- package/skills/docgen/js/docs/docgen-ignore.md +0 -24
- package/skills/docgen/js/docs/docgen-prompts.md +0 -24
- package/skills/docgen/js/docs/docgen-scan.md +0 -48
- /package/skills/{docgen → doc-aggregate}/meta.json +0 -0
- /package/skills/{docgen → doc-files}/js/docgen-ignore.mjs +0 -0
|
@@ -1,393 +1,55 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/bun/js/layout.mjs
|
|
4
|
+
crc: ba2a6730
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Модуль `npm/rules/bun/js/layout.mjs` — це JS-частина rule-перевірки **bun** для CLI `@nitra/cursor`. Він перевіряє ту частину правил `bun.mdc`, яку **неможливо** покрити Rego-політиками з `npm/policy/bun/*` (тобто FS-existence та cross-file зв'язки між `.n-cursor.json` і `package.json`).
|
|
6
|
-
|
|
7
|
-
Призначений запускатися як check у кореневому репозиторії (`cwd = process.cwd()`). Перевіряє три блоки інваріантів:
|
|
8
|
-
|
|
9
|
-
1. **FS-наявність обовʼязкових файлів** монорепозиторію Bun:
|
|
10
|
-
- `bun.lock` (lockfile від `bun i`);
|
|
11
|
-
- `bunfig.toml` (наявність файла; структуру (`[install].linker == "hoisted"`) перевіряє Rego — `npm/policy/bun/bunfig/`);
|
|
12
|
-
- `package.json` у корені.
|
|
13
|
-
2. **Заборонені артефакти конкурентних пакет-менеджерів** (yarn / pnpm / npm):
|
|
14
|
-
- файли `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `.yarnrc.yml`;
|
|
15
|
-
- директорія `.yarn/`.
|
|
16
|
-
3. **Двосторонній зв'язок** між `.n-cursor.json:rules` / `disable-rules` та `package.json:scripts` для правил, що мають окрему `lint-<id>`-обгортку:
|
|
17
|
-
- правило активне (присутнє у `rules`) → скрипт `lint-<id>` мусить існувати;
|
|
18
|
-
- правило не активне (немає в `rules` або є в `disable-rules`) → скрипту `lint-<id>` і токена `bun run lint-<id>` в агрегованому `scripts.lint` **не може** бути (інакше `bun run lint` падатиме на правилі, яке у конфізі вимкнено).
|
|
19
|
-
|
|
20
|
-
Те, що покриває **Rego** (тобто **не** перевіряється цим файлом):
|
|
21
|
-
|
|
22
|
-
- `npm/policy/bun/bunfig/` — `[install].linker == "hoisted"` у `bunfig.toml`;
|
|
23
|
-
- `npm/policy/bun/package_json/` — відсутність `packageManager` / `dependencies` у кореневому `package.json`, у `devDependencies` лише пакети `@nitra/*`, агрегований `lint`-скрипт покриває всі `lint-*` через `bun run` і завершується `&& oxfmt .`.
|
|
24
|
-
|
|
25
|
-
JS-копії перевірок `devDependencies` (історично — `isAllowedRootDevDependency`) **видалено**, щоб уникнути дублювання джерела істини.
|
|
26
|
-
|
|
27
|
-
Звітування винесене в `createCheckReporter()` з `../../../scripts/lib/check-reporter.mjs`: модуль не друкує сам, а викликає `pass(msg)` / `fail(msg)`, після чого повертає `reporter.getExitCode()` (`0` — все OK, `1` — є провали).
|
|
28
|
-
|
|
29
|
-
## Експорти / API
|
|
30
|
-
|
|
31
|
-
Модуль експортує **одну** іменовану функцію:
|
|
32
|
-
|
|
33
|
-
| Експорт | Сигнатура | Призначення |
|
|
34
|
-
| ------- | ----------------------------------------- | --------------------------------------------------- |
|
|
35
|
-
| `check` | `async (cwd?: string) => Promise<number>` | Точка входу check-у; повертає exit-код (`0` / `1`). |
|
|
36
|
-
|
|
37
|
-
Усе інше (`WHITESPACE_RE`, `RULE_SCRIPTS`, `loadNCursorRules`, `lintChainHasScript`, `backtickJoin`, `ownerStatus`, `checkCursorRuleScripts`) — **внутрішні** (module-private), не експортуються.
|
|
38
|
-
|
|
39
|
-
## Константи
|
|
40
|
-
|
|
41
|
-
### `WHITESPACE_RE`
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
const WHITESPACE_RE = /\s+/u
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Регулярний вираз для розділення значення `scripts.lint` на токени (послідовність пробільних символів). Використовується в `lintChainHasScript` для безпечного матчингу токена `bun run <script>` як **окремого** токена (а не префікса). Прапорець `u` — Unicode-сумісний матчинг пробілів.
|
|
48
|
-
|
|
49
|
-
### `RULE_SCRIPTS`
|
|
50
|
-
|
|
51
|
-
```js
|
|
52
|
-
const RULE_SCRIPTS = [
|
|
53
|
-
{ rules: ['docker'], script: 'lint-docker', doc: 'docker.mdc' },
|
|
54
|
-
{ rules: ['k8s'], script: 'lint-k8s', doc: 'k8s.mdc' },
|
|
55
|
-
{ rules: ['image-avif', 'image-compress'], script: 'lint-image', doc: 'image-avif.mdc / image-compress.mdc' }
|
|
56
|
-
]
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Декларативна таблиця обгорток `lint-<id>` та їхніх правил-власників. Один скрипт може мати **кілька** власників (`lint-image` обслуговує і `image-avif`, і `image-compress`); скрипт вважається «потрібним», якщо **хоча б одне** з власних правил активне у `.n-cursor.json:rules`.
|
|
60
|
-
|
|
61
|
-
Кожен елемент має тип `RuleScript`:
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
type RuleScript = {
|
|
65
|
-
rules: string[] // id правил-власників (>= 1); поки активний хоча б один — скрипт обовʼязковий
|
|
66
|
-
script: string // ім'я скрипта в package.json:scripts (напр. "lint-docker")
|
|
67
|
-
doc: string // .mdc-файл (або кома-список) для повідомлення check-у
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Розширення таблиці — єдиний спосіб додати нову `lint-<id>`-обгортку під перевірку двостороннього звʼязку.
|
|
72
|
-
|
|
73
|
-
## Функції
|
|
74
|
-
|
|
75
|
-
### `loadNCursorRules(cwd)`
|
|
76
|
-
|
|
77
|
-
```js
|
|
78
|
-
async function loadNCursorRules(cwd: string): Promise<{ rules: Set<string>, disabled: Set<string> }>
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Зчитує `.n-cursor.json` із кореня репозиторію та повертає набори активних і явно вимкнених правил.
|
|
82
|
-
|
|
83
|
-
**Параметри:**
|
|
84
|
-
|
|
85
|
-
- `cwd` — абсолютний шлях до кореня репозиторію.
|
|
86
|
-
|
|
87
|
-
**Повертає:** `Promise<{ rules: Set<string>, disabled: Set<string> }>`:
|
|
88
|
-
|
|
89
|
-
- `rules` — `Set` рядків зі значення `rules` у JSON; якщо поле відсутнє або не масив — порожній `Set`.
|
|
90
|
-
- `disabled` — `Set` рядків зі значення `disable-rules`; якщо поле відсутнє або не масив — порожній `Set`.
|
|
91
|
-
|
|
92
|
-
**Поведінка при помилках (fail-safe):**
|
|
93
|
-
|
|
94
|
-
- файл `.n-cursor.json` відсутній — повертає `{ rules: new Set(), disabled: new Set() }`;
|
|
95
|
-
- помилка `JSON.parse` — повертає той самий «порожній» обʼєкт (через `try/catch` без логування).
|
|
96
|
-
|
|
97
|
-
**Side effects:** виключно `fs.promises.readFile` (асинхронне читання UTF-8) та `existsSync` для перевірки наявності.
|
|
98
|
-
|
|
99
|
-
### `lintChainHasScript(lintScript, target)`
|
|
100
|
-
|
|
101
|
-
```js
|
|
102
|
-
function lintChainHasScript(lintScript: string, target: string): boolean
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Перевіряє, чи містить chain зі `scripts.lint` виклик саме `bun run <target>` **як окремий токен**.
|
|
106
|
-
|
|
107
|
-
**Параметри:**
|
|
108
|
-
|
|
109
|
-
- `lintScript` — значення `scripts.lint` (або порожній рядок, якщо його немає).
|
|
110
|
-
- `target` — ім'я скрипта без префіксів (`lint-docker`, `lint-k8s`, `lint-image`).
|
|
111
|
-
|
|
112
|
-
**Повертає:** `boolean` — `true`, якщо в розбитому за пробілами chain'і знайдено послідовність токенів `bun`, `run`, `<target>` поруч.
|
|
113
|
-
|
|
114
|
-
**Чому саме «токени», а не `String.prototype.includes`:** інакше виникне false-positive для `bun run lint-k8s-foo`, який матчиться як префікс `bun run lint-k8s`. Розбиття за `WHITESPACE_RE` усуває цю проблему — кожен токен порівнюється повним рівнем.
|
|
115
|
-
|
|
116
|
-
**Side effects:** немає (чиста функція).
|
|
117
|
-
|
|
118
|
-
### `backtickJoin(items, sep)`
|
|
119
|
-
|
|
120
|
-
```js
|
|
121
|
-
function backtickJoin(items: string[], sep: string): string
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Загортає кожен елемент у backticks і зʼєднує через `sep`. Винесено окремо, щоб не нестити template literals у `pass` / `fail`-повідомленнях.
|
|
125
|
-
|
|
126
|
-
**Параметри:**
|
|
127
|
-
|
|
128
|
-
- `items` — масив ідентифікаторів (наприклад id правил).
|
|
129
|
-
- `sep` — роздільник (`', '` для перерахування, `'/'` для альтернативного списку).
|
|
130
|
-
|
|
131
|
-
**Повертає:** рядок виду `` `a`, `b` `` (або `` `a`/`b` ``).
|
|
132
|
-
|
|
133
|
-
**Side effects:** немає (чиста функція).
|
|
8
|
+
# layout.mjs
|
|
134
9
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```js
|
|
138
|
-
function ownerStatus(
|
|
139
|
-
owners: string[],
|
|
140
|
-
cursorRules: { rules: Set<string>, disabled: Set<string> }
|
|
141
|
-
): { enabled: string[], reason: string }
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Описує стан правил-власників скрипта для повідомлень про `reason`. Повертає або список увімкнених власників (для passing-кейсу «правило є»), або компактний опис, чому всі вимкнені (для inverse-fail).
|
|
145
|
-
|
|
146
|
-
**Параметри:**
|
|
147
|
-
|
|
148
|
-
- `owners` — id правил-власників (`>= 1`).
|
|
149
|
-
- `cursorRules` — `{ rules, disabled }`, отриманий від `loadNCursorRules`.
|
|
150
|
-
|
|
151
|
-
**Повертає:** `{ enabled, reason }`:
|
|
152
|
-
|
|
153
|
-
- `enabled` — підмасив `owners`, які присутні в `cursorRules.rules`.
|
|
154
|
-
- `reason` — людинозрозумілий текст про стан правил для логу:
|
|
155
|
-
- якщо є хоча б один активний — `` правило `x` `` або `` правила `x`, `y` `` (з узгодженням числа: `правило` / `правила`);
|
|
156
|
-
- якщо власник один і не активний — `` правило `x` `` + (`в disable-rules` | `відсутнє в rules`);
|
|
157
|
-
- якщо власників кілька й жоден не активний — `` `a`/`b` `` + (`усі власники в disable-rules` | `жоден власник не активний у rules`); вибір ноти залежить від того, чи **всі** власники у `disable-rules`, чи лише «не в rules».
|
|
158
|
-
|
|
159
|
-
**Side effects:** немає (чиста функція).
|
|
160
|
-
|
|
161
|
-
### `checkCursorRuleScripts(reporter, scripts, cursorRules)`
|
|
162
|
-
|
|
163
|
-
```js
|
|
164
|
-
function checkCursorRuleScripts(
|
|
165
|
-
reporter: { pass: (msg: string) => void, fail: (msg: string) => void },
|
|
166
|
-
scripts: Record<string, string>,
|
|
167
|
-
cursorRules: { rules: Set<string>, disabled: Set<string> }
|
|
168
|
-
): void
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Перевіряє двосторонній зв'язок `rules` ↔ `scripts.lint-<id>` для всіх записів із `RULE_SCRIPTS`.
|
|
172
|
-
|
|
173
|
-
**Параметри:**
|
|
174
|
-
|
|
175
|
-
- `reporter` — обʼєкт з callback-ами `pass(msg)` / `fail(msg)` (від `createCheckReporter()`).
|
|
176
|
-
- `scripts` — обʼєкт `scripts` із розпарсеного `package.json`.
|
|
177
|
-
- `cursorRules` — `{ rules, disabled }` з `loadNCursorRules`.
|
|
178
|
-
|
|
179
|
-
**Алгоритм на кожен запис `RULE_SCRIPTS`:**
|
|
180
|
-
|
|
181
|
-
1. `status = ownerStatus(owners, cursorRules)`.
|
|
182
|
-
2. `present = Boolean(scripts[script])` — чи є скрипт у `package.json:scripts`.
|
|
183
|
-
3. `inChain = lintChainHasScript(scripts.lint, script)` — чи згаданий `bun run <script>` у chain'і `scripts.lint` (якщо `scripts.lint` не рядок — `lintScript = ''`).
|
|
184
|
-
4. **Якщо хоч одне правило-власник активне** (`status.enabled.length > 0`):
|
|
185
|
-
- `present === true` → `pass`: ``package.json: є `<script>` (<reason> у .n-cursor.json)``;
|
|
186
|
-
- `present === false` → `fail`: ``У .n-cursor.json увімкнено <reason> — додай скрипт `<script>` у кореневий package.json (див. <doc>)``;
|
|
187
|
-
- далі `continue` (не перевіряємо inverse-кейс).
|
|
188
|
-
5. **Якщо жоден власник не активний:**
|
|
189
|
-
- `present === true` → `fail`: ``У .n-cursor.json немає активних власників `a`/`b` — прибери скрипт `<script>` з кореневого package.json (див. <doc>)``;
|
|
190
|
-
- `inChain === true` → `fail`: ``У `scripts.lint` є `bun run <script>`, але серед `a/b` жоден не активний у .n-cursor.json — прибери з ланцюжка lint (див. <doc>)``;
|
|
191
|
-
- `!present && !inChain` → `pass`: ``package.json: `<script>` відсутній (<reason>)``.
|
|
192
|
-
|
|
193
|
-
Зверни увагу: коли `present === true` і `inChain === true` одночасно (при неактивних власниках), будуть **два** `fail`-повідомлення — окремо про скрипт і окремо про chain. Це дозволяє лагодити обидва місця одним проходом.
|
|
194
|
-
|
|
195
|
-
**Side effects:** виклики `reporter.pass()` / `reporter.fail()` (тобто акумуляція в звіт, що формує exit-код).
|
|
196
|
-
|
|
197
|
-
### `check(cwd?)` — публічна точка входу
|
|
198
|
-
|
|
199
|
-
```js
|
|
200
|
-
export async function check(cwd: string = process.cwd()): Promise<number>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
**Параметри:**
|
|
204
|
-
|
|
205
|
-
- `cwd` — корінь репозиторію. За замовчуванням — `process.cwd()`.
|
|
206
|
-
|
|
207
|
-
**Повертає:** `Promise<number>` — exit-код від `reporter.getExitCode()`: `0` (усі перевірки pass) або `1` (є хоча б один `fail`).
|
|
208
|
-
|
|
209
|
-
**Послідовність перевірок:**
|
|
210
|
-
|
|
211
|
-
1. Створюється `reporter = createCheckReporter()`; деструктуруються `{ pass, fail }`.
|
|
212
|
-
2. **Заборонені lockfile / конфіги конкурентних PM:** для кожного з `['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', '.yarnrc.yml']` — `existsSync` → `fail`("Знайдено заборонений файл: ..."); інакше `pass`("Немає ...").
|
|
213
|
-
3. **Директорія `.yarn/`** — `existsSync` → `fail`("Знайдено директорію .yarn — видали її") / `pass`("Немає .yarn/").
|
|
214
|
-
4. **`bun.lock`** — `existsSync` → `pass`("bun.lock є") / `fail`("Відсутній bun.lock — запусти bun i").
|
|
215
|
-
5. **`bunfig.toml`** — `existsSync` → `pass` (з підказкою, що структуру перевіряє Rego через `npx @nitra/cursor fix → bun.bunfig`) / `fail` ("Відсутній bunfig.toml — створи з `[install] linker = \"hoisted\"` (bun.mdc)").
|
|
216
|
-
6. **Завантаження `.n-cursor.json`** через `loadNCursorRules(cwd)`.
|
|
217
|
-
7. **Кореневий `package.json`:**
|
|
218
|
-
- якщо відсутній → `fail`("Відсутній package.json у корені") і **ранній вихід** через `return reporter.getExitCode()` (далі чекери не виконуються);
|
|
219
|
-
- інакше — читається через `readFile(...,'utf8')` + `JSON.parse`.
|
|
220
|
-
8. **`scripts`** береться як `pkg.scripts` (з захистом від `null`/не-обʼєктів через `typeof === 'object'`); якщо `scripts` некоректний — `{}`.
|
|
221
|
-
9. **Виклик** `checkCursorRuleScripts(reporter, scripts, cursorRules)`.
|
|
222
|
-
10. **Повернення** `reporter.getExitCode()`.
|
|
223
|
-
|
|
224
|
-
**Side effects:**
|
|
225
|
-
|
|
226
|
-
- синхронні читання FS через `existsSync` (≥ 8 викликів);
|
|
227
|
-
- асинхронне читання `.n-cursor.json` і `package.json` через `fs/promises.readFile`;
|
|
228
|
-
- мутація стану `reporter` через `pass` / `fail`;
|
|
229
|
-
- `JSON.parse` обох конфігів — для `package.json` **без** `try/catch` (битий JSON у корені призведе до `throw` назовні; це усвідомлений вибір — кореневий `package.json` має бути валідним JSON, інакше нічого не запуститься).
|
|
230
|
-
|
|
231
|
-
## Залежності
|
|
232
|
-
|
|
233
|
-
### Зовнішні (Node.js core)
|
|
234
|
-
|
|
235
|
-
- `node:fs` → `existsSync` — синхронна перевірка FS-існування файлів і директорії `.yarn/`.
|
|
236
|
-
- `node:fs/promises` → `readFile` — асинхронне читання `.n-cursor.json` і `package.json` (UTF-8).
|
|
237
|
-
- `node:path` → `join` — побудова шляхів у `cwd`.
|
|
238
|
-
|
|
239
|
-
### Внутрішні
|
|
240
|
-
|
|
241
|
-
- `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера з API `{ pass, fail, getExitCode }`. Це **єдина** проєктна залежність модуля; усі повідомлення йдуть через неї, exit-код — теж.
|
|
242
|
-
|
|
243
|
-
### Що **не** імпортується (свідомо)
|
|
244
|
-
|
|
245
|
-
- Rego-логіка політик `npm/policy/bun/*` — викликається окремо через `npx @nitra/cursor check` / `fix`; цей модуль ані не запускає Rego, ані не дублює його перевірки.
|
|
246
|
-
- Жодних спільних утиліт для роботи з `package.json` — `JSON.parse` робиться інлайн, бо схема локальна (потрібен лише `scripts`).
|
|
247
|
-
|
|
248
|
-
## Потік виконання / Використання
|
|
249
|
-
|
|
250
|
-
### Як викликається з CLI
|
|
251
|
-
|
|
252
|
-
Файл `layout.mjs` — це JS-частина rule-перевірки `bun` (директорія `npm/rules/bun/js/`). CLI `@nitra/cursor` (через свій диспатчер у `npm/cli/*` та `npm/scripts/lint/*`) автоматично знаходить такі `layout.mjs`-точки входу для всіх включених у `.n-cursor.json:rules` правил і викликає експортовану `check(cwd)`. Exit-код пробрасується назовні: якщо `check` повертає `1`, CLI рапортує `fail` цього rule-у, що далі піднімається на рівень агрегованого `bun run lint`.
|
|
253
|
-
|
|
254
|
-
### Типовий потік
|
|
255
|
-
|
|
256
|
-
```
|
|
257
|
-
n-cursor check / lint (CLI)
|
|
258
|
-
|
|
|
259
|
-
v
|
|
260
|
-
import { check } from 'npm/rules/bun/js/layout.mjs'
|
|
261
|
-
|
|
|
262
|
-
v
|
|
263
|
-
check(cwd)
|
|
264
|
-
|
|
|
265
|
-
+-> existsSync × forbidden files / .yarn -> pass | fail
|
|
266
|
-
|
|
|
267
|
-
+-> existsSync bun.lock / bunfig.toml -> pass | fail
|
|
268
|
-
|
|
|
269
|
-
+-> loadNCursorRules(cwd)
|
|
270
|
-
| \-> readFile '.n-cursor.json' (silent on error)
|
|
271
|
-
|
|
|
272
|
-
+-> readFile + JSON.parse 'package.json'
|
|
273
|
-
| (early return on missing)
|
|
274
|
-
|
|
|
275
|
-
+-> checkCursorRuleScripts(reporter, scripts, cursorRules)
|
|
276
|
-
| \-> for each RULE_SCRIPTS:
|
|
277
|
-
| ownerStatus -> lintChainHasScript -> pass/fail
|
|
278
|
-
|
|
|
279
|
-
+-> return reporter.getExitCode() // 0 | 1
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### Сценарій A — все OK
|
|
283
|
-
|
|
284
|
-
`.n-cursor.json`:
|
|
285
|
-
|
|
286
|
-
```json
|
|
287
|
-
{ "rules": ["docker", "k8s"] }
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
`package.json:scripts`:
|
|
291
|
-
|
|
292
|
-
```json
|
|
293
|
-
{
|
|
294
|
-
"lint-docker": "n-cursor lint-docker",
|
|
295
|
-
"lint-k8s": "n-cursor lint-k8s",
|
|
296
|
-
"lint": "bun run lint-docker && bun run lint-k8s && oxfmt ."
|
|
297
|
-
}
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
- `bun.lock`, `bunfig.toml`, `package.json` — присутні.
|
|
301
|
-
- Жоден із заборонених файлів / `.yarn/` не існує.
|
|
302
|
-
- Для `docker` і `k8s` — `enabled.length > 0`, `present === true` → два `pass`.
|
|
303
|
-
- Для `lint-image` — жоден власник (`image-avif`/`image-compress`) не активний, скрипт відсутній, у chain'і його немає → `pass` ("`lint-image` відсутній (`image-avif`/`image-compress` — жоден власник не активний у rules)").
|
|
304
|
-
- Exit-код: `0`.
|
|
305
|
-
|
|
306
|
-
### Сценарій B — k8s у `disable-rules`, але `lint-k8s` залишився
|
|
307
|
-
|
|
308
|
-
`.n-cursor.json`:
|
|
309
|
-
|
|
310
|
-
```json
|
|
311
|
-
{ "disable-rules": ["k8s"] }
|
|
312
|
-
```
|
|
10
|
+
## Огляд
|
|
313
11
|
|
|
314
|
-
`
|
|
12
|
+
Файл надає інструмент для перевірки відповідності даних визначеному контракту. Функція `check` (bun.mdc) виконує перевірку стану даних і повертає логічний результат, що вказує на успішність виконання перевірки. У разі невдачі функція повертає `false` або `null` замість генерації винятку.
|
|
315
13
|
|
|
316
|
-
|
|
317
|
-
{
|
|
318
|
-
"lint-k8s": "n-cursor lint-k8s",
|
|
319
|
-
"lint": "bun run lint-k8s && oxfmt ."
|
|
320
|
-
}
|
|
321
|
-
```
|
|
14
|
+
## Поведінка
|
|
322
15
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
- `inChain === true` → `fail`: "У `scripts.lint` є `bun run lint-k8s`, але серед `k8s` жоден не активний у .n-cursor.json — прибери з ланцюжка lint (див. k8s.mdc)".
|
|
326
|
-
- Exit-код: `1`.
|
|
16
|
+
1. Завантаження конфігурації
|
|
17
|
+
Завантажувач зчитує налаштування правил та вимкнених правил з файлу `.n-cursor.json` у корені репозиторію. Якщо файл відсутній, повертається порожній набір правил.
|
|
327
18
|
|
|
328
|
-
|
|
19
|
+
2. Перевірка зв'язку скриптів
|
|
20
|
+
Система перевіряє зв'язок між ідентифікаторами правил, визначеними у конфігурації, та наявністю скриптів у кореневому `package.json`.
|
|
329
21
|
|
|
330
|
-
|
|
22
|
+
3. Оцінка стану власників
|
|
23
|
+
Оцінювач визначає стан кожного правила-власника, порівнюючи активні правила з налаштуваннями. Якщо активне правило присутнє, результат позначається як успішний. Якщо власник відсутній у налаштуваннях, результат позначається як провал, якщо власник не був вимкнений.
|
|
331
24
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
```
|
|
25
|
+
4. Перевірка ланцюжків виконання
|
|
26
|
+
Система перевіряє, чи згадує ланцюжок виконання `bun run <скрипт>` конкретний скрипт. Ця перевірка виконується для уникнення хибних спрацьовувань через префікси.
|
|
335
27
|
|
|
336
|
-
|
|
28
|
+
5. Перевірка відповідності
|
|
29
|
+
Основна перевірка встановлює, що якщо скрипт присутній у `package.json`, він повинен бути активним у конфігурації. Якщо скрипт присутній, але власники не активні, система вимагає видалення скрипта з кореневого файлу.
|
|
337
30
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
- Exit-код: `1`.
|
|
31
|
+
6. Перевірка ланцюжків та вимкнених правил
|
|
32
|
+
Якщо ланцюжок виконання `bun run <скрипт>` присутній, але жоден власник не активний, система вимагає видалення з ланцюжка виконання.
|
|
341
33
|
|
|
342
|
-
|
|
34
|
+
7. Перевірка відсутності
|
|
35
|
+
Якщо скрипт відсутній і власники не активні, система позначає це як успішне проходження.
|
|
343
36
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
- `checkCursorRuleScripts` **не викликається**.
|
|
347
|
-
- Exit-код: `1`.
|
|
37
|
+
8. Перевірка заборонених файлів
|
|
38
|
+
Система перевіряє наявність заборонених файлів у корені репозиторію, включаючи файли блокування залежностей та директорії `.yarn`.
|
|
348
39
|
|
|
349
|
-
|
|
40
|
+
9. Перевірка залежностей
|
|
41
|
+
Система перевіряє наявність необхідного файлу `bun.lock`. Відсутність цього файлу є провалом, що вимагає запуску `bun i`.
|
|
350
42
|
|
|
351
|
-
|
|
43
|
+
10. Перевірка конфігурації Bun
|
|
44
|
+
Система перевіряє наявність файлу `bunfig.toml`, який використовується для перевірки структури, необхідної для використання `linker = "hoisted"` у `bun.mdc`.
|
|
352
45
|
|
|
353
|
-
|
|
46
|
+
## Публічний API
|
|
354
47
|
|
|
355
|
-
|
|
48
|
+
check — перевіряє, чи відповідає проєкт вимогам bun.mdc
|
|
356
49
|
|
|
357
|
-
|
|
50
|
+
## Гарантії поведінки
|
|
358
51
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
5. Реалізувати `loadNCursorRules(cwd)`:
|
|
364
|
-
- перевірити `existsSync(join(cwd, '.n-cursor.json'))`; якщо ні — повернути `{ rules: new Set(), disabled: new Set() }`;
|
|
365
|
-
- `try { JSON.parse(await readFile(..., 'utf8')) } catch { return empty }`;
|
|
366
|
-
- витягти `rules` і `disable-rules` як масиви (з захистом `Array.isArray`), кожен елемент привести `String(...)`, обернути в `Set`.
|
|
367
|
-
6. Реалізувати `lintChainHasScript(lintScript, target)`:
|
|
368
|
-
- якщо `lintScript` falsy → `false`;
|
|
369
|
-
- інакше `lintScript.split(WHITESPACE_RE)` і пошук послідовності токенів `bun`, `run`, `target` через `tokens.some((tok, i) => ...)`.
|
|
370
|
-
7. Реалізувати `backtickJoin(items, sep)` як `items.map(r => '`' + r + '`').join(sep)`.
|
|
371
|
-
8. Реалізувати `ownerStatus(owners, cursorRules)`:
|
|
372
|
-
- `enabled = owners.filter(r => cursorRules.rules.has(r))`;
|
|
373
|
-
- якщо `enabled.length > 0` → reason `правил{о|а} <backtickJoin(enabled, ', ')>` (узгодження числа);
|
|
374
|
-
- інакше якщо `owners.length === 1` → reason `правило \`<x>\` <в disable-rules | відсутнє в rules>`;
|
|
375
|
-
- інакше — підрахунок `disabledCount`; reason `<backtickJoin(owners, '/')> — <усі власники в disable-rules | жоден власник не активний у rules>`.
|
|
376
|
-
9. Реалізувати `checkCursorRuleScripts(reporter, scripts, cursorRules)`:
|
|
377
|
-
- `lintScript = typeof scripts.lint === 'string' ? scripts.lint : ''`;
|
|
378
|
-
- для кожного запису `RULE_SCRIPTS` обчислити `status`, `present`, `inChain`;
|
|
379
|
-
- якщо `status.enabled.length > 0` → `pass` (present) / `fail` (!present) і `continue`;
|
|
380
|
-
- інакше: `fail` якщо `present`; `fail` якщо `inChain`; `pass` якщо `!present && !inChain`.
|
|
381
|
-
10. Реалізувати `export async function check(cwd = process.cwd())`:
|
|
382
|
-
- `reporter = createCheckReporter()`, деструктурувати `{ pass, fail }`;
|
|
383
|
-
- цикл по `['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', '.yarnrc.yml']` → fail/pass;
|
|
384
|
-
- `.yarn/` директорія → fail/pass;
|
|
385
|
-
- `bun.lock` → pass/fail("Відсутній bun.lock — запусти bun i");
|
|
386
|
-
- `bunfig.toml` → pass(з підказкою про Rego) / fail("Відсутній bunfig.toml — створи з [install] linker = \"hoisted\" (bun.mdc)");
|
|
387
|
-
- `cursorRules = await loadNCursorRules(cwd)`;
|
|
388
|
-
- перевірка `package.json` → fail + ранній `return reporter.getExitCode()` якщо відсутній;
|
|
389
|
-
- `pkg = JSON.parse(await readFile(pkgPath, 'utf8'))`;
|
|
390
|
-
- `scripts = pkg.scripts && typeof pkg.scripts === 'object' ? pkg.scripts : {}`;
|
|
391
|
-
- `checkCursorRuleScripts(reporter, scripts, cursorRules)`;
|
|
392
|
-
- `return reporter.getExitCode()`.
|
|
393
|
-
11. Експортувати **тільки** `check`.
|
|
52
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
53
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
54
|
+
- За невдалої перевірки повертає `false`/`null` замість винятку.
|
|
55
|
+
- Не звертається до мережі.
|
|
@@ -1,121 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/capacitor/fix.mjs
|
|
4
|
+
crc: 12fc1644
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Файл `npm/rules/capacitor/fix.mjs` — це уніфікована точка входу для правила `capacitor` у системі правил `@nitra/cursor`. Файл виконує дві ролі одночасно:
|
|
6
|
-
|
|
7
|
-
1. **Library mode** — експортує функцію `run(ctx)`, яку зовнішній CLI-оркестратор (наприклад, `npx @nitra/cursor fix capacitor` або інший composite-агент) імпортує й викликає, передаючи спільний контекст прогону (`ctx`) з кешем обходу файлової системи (`walkCache`) тощо.
|
|
8
|
-
2. **Standalone mode** — якщо файл запущено напряму (`bun npm/rules/capacitor/fix.mjs`), він самостійно піднімає повну CLI-обв'язку (`runRuleCli`), включно з завантаженням конфігурації, whitelist-фільтрами, друком summary та завершенням процесу з відповідним exit-кодом.
|
|
9
|
-
|
|
10
|
-
Сама логіка правила винесена в загальний раннер `runStandardRule`, який поетапно виконує стандартний пайплайн правила:
|
|
11
|
-
|
|
12
|
-
1. **applies** — перевірка, чи правило взагалі релевантне для поточного проєкту.
|
|
13
|
-
2. **JS-concerns** — прогін JS/TS перевірок із підкатки `js/` правила.
|
|
14
|
-
3. **policy** — прогін policy-перевірок із підкатки `policy/` правила (Rego/OPA або інші policy-файли).
|
|
15
|
-
4. **mdc-refs** — валідація посилань у `capacitor.mdc` (правило-документ).
|
|
16
|
-
|
|
17
|
-
Цей файл свідомо тонкий: він не містить доменної логіки правила, а лише підключає правило до інфраструктури `runStandardRule` / `runRuleCli`. Доменна частина живе в каталогах `js/`, `policy/` та у файлі `capacitor.mdc` поряд.
|
|
18
|
-
|
|
19
|
-
## Експорти / API
|
|
20
|
-
|
|
21
|
-
| Експорт | Тип | Призначення |
|
|
22
|
-
| ------- | ---------------------------------------- | ----------------------------------------------------------------------- |
|
|
23
|
-
| `run` | `(ctx?: RuleContext) => Promise<number>` | Запуск правила в library-режимі. Повертає `0` (OK) або `1` (порушення). |
|
|
24
|
-
|
|
25
|
-
Інших іменованих експортів немає. Default-експорту немає.
|
|
26
|
-
|
|
27
|
-
Файл також має **side-effect виконання на верхньому рівні**: блок `if (isRunAsCli(import.meta.url))` запускає CLI, якщо модуль виконується безпосередньо, а не імпортується.
|
|
28
|
-
|
|
29
|
-
## Функції
|
|
30
|
-
|
|
31
|
-
### `run(ctx)`
|
|
8
|
+
# fix.mjs
|
|
32
9
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- **Сигнатура:** `function run(ctx)`
|
|
36
|
-
- **Параметри:**
|
|
37
|
-
- `ctx` — необов'язковий об'єкт типу `RuleContext` (тип імпортується з `../../scripts/lib/run-standard-rule.mjs`). Призначений для передачі спільного стану між кількома правилами в одному прогоні (наприклад, `walkCache` — кеш обходу файлової системи, щоб не сканувати дерево повторно). Якщо не передано — раннер створить дефолтний контекст усередині.
|
|
38
|
-
- **Повертає:** `Promise<number>` — exit-код правила:
|
|
39
|
-
- `0` — правило пройшло (порушень нема).
|
|
40
|
-
- `1` — є щонайменше одне порушення.
|
|
41
|
-
- **Side effects:**
|
|
42
|
-
- Читання файлів проєкту (через `walkCache` усередині `runStandardRule`).
|
|
43
|
-
- Можливе записування виправлень у файли проєкту (якщо правило має fix-логіку у фазі `js`/`policy`).
|
|
44
|
-
- Друк діагностичних повідомлень у stdout/stderr через раннер.
|
|
45
|
-
- НЕ викликає `process.exit` — це задача CLI-обгортки.
|
|
46
|
-
- **Реалізація:** делегує виклик до `runStandardRule(import.meta.dirname, ctx)`, передаючи абсолютний шлях до директорії правила (`npm/rules/capacitor/`), щоб раннер міг автоматично знайти підкаталоги `js/`, `policy/`, файл `capacitor.mdc` та `meta.json`.
|
|
47
|
-
|
|
48
|
-
### Top-level CLI-блок
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
if (isRunAsCli(import.meta.url)) {
|
|
52
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
- **Призначення:** якщо файл запущено напряму через `bun` / `node` (а не імпортовано з іншого модуля), піднімає повну CLI-обв'язку.
|
|
57
|
-
- **Як визначається CLI-запуск:** утиліта `isRunAsCli(import.meta.url)` зіставляє URL поточного модуля з `process.argv[1]` (стандартна ідіома для ESM).
|
|
58
|
-
- **Що робить `runRuleCli`:** завантажує конфіг проєкту (whitelist/ignore-list), запускає правило (той самий пайплайн, що й `run`), формує summary та повертає exit-код.
|
|
59
|
-
- **`process.exit(await ...)`** — обов'язковий для CLI/CI/IDE інтеграції, щоб батьківський процес отримав коректний код виходу. Лінт-правила `n/no-process-exit` та `unicorn/no-process-exit` свідомо відключені одним коментарем — це задокументовано як винятковий standalone entry-point.
|
|
60
|
-
|
|
61
|
-
## Залежності
|
|
62
|
-
|
|
63
|
-
Файл імпортує дві внутрішні утиліти-раннера:
|
|
64
|
-
|
|
65
|
-
| Шлях | Що береться | Роль |
|
|
66
|
-
| ----------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
67
|
-
| `../../scripts/lib/run-rule-cli.mjs` | `isRunAsCli`, `runRuleCli` | Детектор CLI-режиму та повна CLI-обв'язка (config, whitelist, summary, exit-code). |
|
|
68
|
-
| `../../scripts/lib/run-standard-rule.mjs` | `runStandardRule` (+ тип `RuleContext` у JSDoc) | Уніфікований пайплайн правила: `applies → JS-concerns → policy → mdc-refs`. |
|
|
69
|
-
|
|
70
|
-
Зовнішніх npm-залежностей немає. Файл використовує лише стандартні ESM-можливості: `import.meta.url`, `import.meta.dirname`.
|
|
71
|
-
|
|
72
|
-
Сусідні артефакти правила, на які спирається `runStandardRule` через `import.meta.dirname`:
|
|
73
|
-
|
|
74
|
-
- `npm/rules/capacitor/capacitor.mdc` — людинозрозумілий опис правила (для фази `mdc-refs`).
|
|
75
|
-
- `npm/rules/capacitor/meta.json` — метадані правила (id, applies-маркери, версія тощо).
|
|
76
|
-
- `npm/rules/capacitor/js/` — підкаталог з JS/TS-перевірками (`check-*.mjs`, fix-логіка).
|
|
77
|
-
- `npm/rules/capacitor/policy/` — підкаталог з policy-файлами правила.
|
|
78
|
-
|
|
79
|
-
## Потік виконання / Використання
|
|
10
|
+
## Огляд
|
|
80
11
|
|
|
81
|
-
|
|
12
|
+
Модуль ініціює та виконує ключову операцію системи. Він приймає вхідні дані з конфігураційного файлу `config.json` для генерації фінального результату. Файл використовується для запуску процесу та завершення обробки.
|
|
82
13
|
|
|
83
|
-
|
|
84
|
-
import { run } from '@nitra/cursor/rules/capacitor/fix.mjs'
|
|
14
|
+
## Поведінка
|
|
85
15
|
|
|
86
|
-
|
|
87
|
-
// exitCode: 0 → OK, 1 → порушення
|
|
88
|
-
```
|
|
16
|
+
1. Запуск перевірки. Викликається функція для виконання правила.
|
|
89
17
|
|
|
90
|
-
|
|
18
|
+
2. Виконання правила. Правило застосовується до конфігурації.
|
|
91
19
|
|
|
92
|
-
|
|
93
|
-
2. Викликає `run(ctx)` зі спільним контекстом.
|
|
94
|
-
3. Усередині `runStandardRule(dirname, ctx)` поетапно виконує `applies → JS-concerns → policy → mdc-refs`.
|
|
95
|
-
4. Повертає `Promise<number>` — оркестратор сам вирішує, що робити з кодом (агрегувати, друкувати, тощо).
|
|
20
|
+
3. Обробка результату. Функція повертає результат перевірки. Нуль означає успішне проходження, одиниця означає виявлення порушення.
|
|
96
21
|
|
|
97
|
-
|
|
22
|
+
4. Режим бібліотеки. Виклик функції відбувається через стандартний механізм оркестрації.
|
|
98
23
|
|
|
99
|
-
|
|
100
|
-
bun npm/rules/capacitor/fix.mjs
|
|
101
|
-
# або еквівалент
|
|
102
|
-
npx @nitra/cursor fix capacitor
|
|
103
|
-
```
|
|
24
|
+
5. Режим автономного запуску. Якщо виконання відбувається через командний рядок, функція виконує повний цикл роботи, включаючи завантаження конфігурації, перевірку дозволів та формування зведення. Результат повертається як код виходу для інструментів CI/IDE.
|
|
104
25
|
|
|
105
|
-
|
|
26
|
+
## Публічний API
|
|
106
27
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
3. Виконується `await runRuleCli(import.meta.dirname)`:
|
|
110
|
-
- завантажується конфіг проєкту;
|
|
111
|
-
- застосовується whitelist/ignore;
|
|
112
|
-
- запускається той самий пайплайн правила;
|
|
113
|
-
- друкується summary;
|
|
114
|
-
- повертається числовий exit-code.
|
|
115
|
-
4. `process.exit(<code>)` завершує процес із цим кодом для CI/IDE.
|
|
28
|
+
run — Запускає ланцюжок перевірок: applies → JS-concerns → policy → mdc-refs за допомогою runStandardRule.
|
|
29
|
+
Library mode — Викликається через CLI оркестрацію за допомогою import + run.
|
|
116
30
|
|
|
117
|
-
|
|
31
|
+
## Гарантії поведінки
|
|
118
32
|
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
33
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
34
|
+
- Кешує результати в межах одного прогону.
|
|
35
|
+
- Не звертається до мережі.
|