@nitra/cursor 5.3.4 → 6.0.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 +2 -2
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +13 -24
- package/CHANGELOG.md +21 -0
- package/bin/n-cursor.js +47 -24
- package/lib/docs/models.md +29 -18
- package/lib/docs/omlx-trace.md +51 -0
- package/lib/docs/omlx.md +31 -15
- package/lib/omlx.mjs +2 -5
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +17 -11
- package/rules/adr/docs/fix.md +25 -140
- package/rules/bun/docs/fix.md +18 -151
- package/rules/capacitor/docs/fix.md +16 -13
- package/rules/capacitor/js/docs/platforms.md +31 -43
- package/rules/changelog/docs/fix.md +25 -169
- package/rules/ci4/docs/fix.md +11 -14
- package/rules/doc-files/doc-files.mdc +60 -0
- package/rules/doc-files/docs/fix.md +31 -0
- package/rules/doc-files/fix.mjs +19 -0
- package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
- package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +18 -5
- package/{skills → rules}/doc-files/js/docgen-gen.mjs +46 -5
- package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
- package/{skills → rules}/doc-files/js/docgen-scan.mjs +11 -3
- package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-extract-anchors.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-extract.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-files-batch.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-gen.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-ignore.md +4 -4
- package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
- package/rules/doc-files/js/docs/docgen-scan.md +54 -0
- package/rules/doc-files/js/docs/lint.md +36 -0
- package/rules/doc-files/js/docs/units-js.md +31 -0
- package/rules/doc-files/js/docs/units-rs.md +35 -0
- package/rules/doc-files/js/docs/units.md +30 -0
- package/rules/doc-files/js/lint.mjs +96 -0
- package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
- package/rules/doc-files/lint/docs/lint.md +37 -0
- package/rules/doc-files/lint/lint.mjs +105 -0
- package/rules/doc-files/meta.json +1 -0
- package/rules/docker/docs/fix.md +21 -161
- package/rules/efes/docs/fix.md +23 -194
- package/rules/feedback/docs/fix.md +10 -8
- package/rules/ga/docs/fix.md +10 -5
- package/rules/ga/meta.json +1 -1
- package/rules/graphql/docs/fix.md +23 -119
- package/rules/hasura/docs/fix.md +19 -5
- package/rules/hasura/js/docs/internal_urls.md +34 -307
- package/rules/image-avif/docs/fix.md +16 -127
- package/rules/image-compress/docs/fix.md +20 -141
- package/rules/image-compress/js/docs/package_setup.md +22 -182
- package/rules/js-bun-db/docs/fix.md +23 -139
- package/rules/js-bun-db/js/docs/safety.md +33 -221
- package/rules/js-bun-redis/docs/fix.md +25 -114
- package/rules/js-bun-redis/js/docs/imports.md +18 -166
- package/rules/js-lint/docs/fix.md +30 -108
- package/rules/js-lint/js/docs/lint-findings.md +37 -17
- package/rules/js-lint/js/docs/lint.md +22 -238
- package/rules/js-lint/js/docs/tooling.md +34 -331
- package/rules/js-lint/js/lint.mjs +19 -12
- package/rules/js-lint/js-lint.mdc +1 -1
- package/rules/js-lint/meta.json +1 -1
- package/rules/js-lint-ci/docs/fix.md +16 -149
- package/rules/js-lint-ci/js/docs/lint.md +16 -136
- package/rules/js-lint-ci/js-lint-ci.mdc +1 -1
- package/rules/js-lint-ci/meta.json +1 -1
- package/rules/js-mssql/docs/fix.md +18 -123
- package/rules/js-mssql/js/docs/deps.md +28 -251
- package/rules/js-run/docs/fix.md +23 -138
- package/rules/js-run/js/docs/runtime.md +24 -378
- package/rules/k8s/docs/fix.md +18 -123
- package/rules/nginx-default-tpl/docs/fix.md +22 -118
- package/rules/nginx-default-tpl/js/docs/template.md +38 -360
- package/rules/npm-module/docs/fix.md +27 -89
- package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
- package/rules/npm-module/js/docs/package_structure.md +36 -258
- package/rules/npm-module/js/docs/rule_meta.md +25 -127
- package/rules/npm-module/js/docs/skill_meta.md +18 -180
- package/rules/npm-module/js/rule_meta.mjs +3 -3
- package/rules/php/docs/fix.md +21 -98
- package/rules/php/js/docs/tooling.md +20 -143
- package/rules/python/docs/fix.md +25 -157
- package/rules/python/js/docs/applies.md +20 -98
- package/rules/python/js/docs/tooling.md +27 -144
- package/rules/rego/docs/fix.md +24 -112
- package/rules/rego/js/docs/applies.md +20 -164
- package/rules/rego/js/docs/lint.md +15 -110
- package/rules/rego/meta.json +1 -1
- package/rules/release/docs/fix.md +16 -114
- package/rules/rust/docs/fix.md +24 -119
- package/rules/rust/js/docs/applies.md +20 -129
- package/rules/security/docs/fix.md +21 -78
- package/rules/security/js/docs/sample_secret.md +23 -182
- package/rules/security/js/docs/trufflehog.md +19 -128
- package/rules/security/meta.json +1 -1
- package/rules/style-lint/docs/fix.md +16 -150
- package/rules/style-lint/js/docs/lint.md +21 -172
- package/rules/style-lint/js/docs/tooling.md +19 -184
- package/rules/style-lint/js/lint.mjs +4 -3
- package/rules/style-lint/meta.json +1 -1
- package/rules/tauri/docs/fix.md +26 -152
- package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
- package/rules/tauri/js/docs/tooling.md +20 -217
- package/rules/test/docs/fix.md +19 -127
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
- package/rules/test/js/docs/cargo_mutants_config.md +24 -164
- package/rules/test/js/docs/location.md +24 -126
- package/rules/test/js/docs/no-process-chdir.md +20 -151
- package/rules/test/js/docs/no-relative-fs-path.md +24 -261
- package/rules/test/js/docs/stryker_config.md +48 -148
- package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
- package/rules/text/docs/fix.md +25 -113
- package/rules/text/js/docs/forbidden-prettier.md +21 -132
- package/rules/text/js/docs/formatting.md +60 -251
- package/rules/text/js/docs/lint.md +17 -114
- package/rules/text/js/lint.mjs +5 -3
- package/rules/text/lint/docs/lint.md +1 -1
- package/rules/text/lint/docs/run-dotenv-linter.md +1 -1
- package/rules/text/lint/docs/run-shellcheck.md +1 -1
- package/rules/text/lint/lint.mjs +13 -9
- package/rules/text/lint/run-dotenv-linter.mjs +13 -10
- package/rules/text/lint/run-shellcheck.mjs +10 -6
- package/rules/text/meta.json +1 -1
- package/rules/vue/docs/fix.md +25 -118
- package/rules/vue/js/docs/packages.md +25 -323
- package/rules/worktree/docs/fix.md +31 -150
- package/scripts/coverage-classify/docs/index.md +23 -209
- package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
- package/scripts/dispatcher/docs/trace.md +35 -0
- package/scripts/docs/auto-rules.md +37 -361
- package/scripts/docs/lint-cli.md +12 -13
- package/scripts/docs/post-tool-use-fix.md +16 -15
- package/scripts/docs/skills-cli.md +26 -23
- package/scripts/docs/sync-claude-config.md +94 -34
- package/scripts/docs/worktree-cli.md +11 -34
- package/scripts/lib/docs/assert-project-root.md +14 -16
- package/scripts/lib/docs/changed-files.md +24 -139
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
- package/scripts/lib/docs/rule-meta.md +1 -1
- package/scripts/lib/docs/rule-predicates.md +20 -17
- package/scripts/lib/docs/run-rule-cli.md +14 -18
- package/scripts/lib/docs/run-rule.md +13 -20
- package/scripts/lib/docs/run-standard-rule.md +12 -15
- package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
- package/scripts/lib/rule-meta.mjs +10 -6
- package/scripts/lib/rule-predicates.mjs +1 -1
- package/scripts/lint-cli.mjs +28 -20
- package/scripts/sync-claude-config.mjs +4 -1
- package/scripts/utils/docs/with-lock.md +19 -12
- package/scripts/utils/with-lock.mjs +4 -2
- package/skills/doc-aggregate/SKILL.md +2 -2
- package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
- package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
- package/skills/doc-files/.changes/260612-0031.md +5 -0
- package/skills/doc-files/.changes/260612-0036.md +5 -0
- package/skills/doc-files/.changes/260612-0114.md +5 -0
- package/skills/doc-files/SKILL.md +6 -6
- package/skills/fix/js/docs/llm-worker.md +17 -15
- package/skills/fix/js/docs/orchestrator.md +30 -23
- package/skills/fix/js/docs/t0.md +26 -16
- package/skills/start-check/js/docs/check.md +26 -22
- package/skills/taze/js/docs/diff.md +44 -20
- package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
- package/skills/doc-files/js/docs/docgen-scan.md +0 -25
- package/skills/doc-files/js/docs/units-rs.md +0 -35
- /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
- /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
- /package/{skills → rules}/doc-files/js/units.mjs +0 -0
|
@@ -1,137 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/npm-module/js/rule_meta.mjs
|
|
4
|
+
crc: 8262678c
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# rule_meta.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Логіка перевірки покриває такі інваріанти для кожного підкаталогу `npm/rules/<id>/`:
|
|
8
|
-
|
|
9
|
-
- наявність валідного `meta.json`;
|
|
10
|
-
- коректність поля `auto`, якщо воно присутнє (розпізнаваність специфікації через `parseRuleAutoSpec`: значення `"завжди"`, масив, `{glob}` або `{predicate}`);
|
|
11
|
-
- для специфікації `{predicate}` — наявність відповідного імені у реєстрі `RULE_PREDICATES`;
|
|
12
|
-
- коректність поля `lint`, якщо воно присутнє (`"quick"` чи `"ci"`), з обовʼязковою наявністю файлу `js/lint.mjs` у каталозі правила;
|
|
13
|
-
- відсутність застарілого `auto.md` поряд із `meta.json` (міграція метаданих у `meta.json` вже завершена).
|
|
14
|
-
|
|
15
|
-
Перевірка застосовна виключно у репо самого пакета `@nitra/cursor`, де існує каталог `npm/rules/`. У споживацьких репо такого каталогу немає, тож модуль м’яко рапортує `pass` і завершується кодом виходу `0`.
|
|
16
|
-
|
|
17
|
-
Модуль експортує єдину функцію `check`, яка повертає `Promise<number>` із POSIX-кодом виходу: `0` — порушень немає, `1` — є хоча б одне порушення. Звітування реалізоване через інстанс репортера, отриманий від `createCheckReporter`.
|
|
18
|
-
|
|
19
|
-
## Експорти / API
|
|
20
|
-
|
|
21
|
-
| Експорт | Тип | Призначення |
|
|
22
|
-
| -------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
23
|
-
| `check(cwd?: string): Promise<number>` | іменований експорт (функція) | Валідує всі `npm/rules/<id>/meta.json` у переданому корені репозиторію та повертає підсумковий код виходу. |
|
|
24
|
-
|
|
25
|
-
Інших експортів (default, типи, константи) модуль не має.
|
|
26
|
-
|
|
27
|
-
## Функції
|
|
28
|
-
|
|
29
|
-
### `check(cwd = process.cwd())`
|
|
30
|
-
|
|
31
|
-
Валідує всі `meta.json` у `<cwd>/npm/rules/<id>/`.
|
|
32
|
-
|
|
33
|
-
- **Сигнатура:** `export function check(cwd?: string): Promise<number>`
|
|
34
|
-
- **Параметри:**
|
|
35
|
-
- `cwd` — рядок із абсолютним або відносним шляхом до кореня репозиторію. Необовʼязковий. Якщо не вказано, використовується `process.cwd()` (поточний робочий каталог процесу Node).
|
|
36
|
-
- **Повертає:** `Promise<number>`, що резолвиться у код виходу від репортера (`reporter.getExitCode()`). Конвенція:
|
|
37
|
-
- `0` — усі знайдені правила пройшли валідацію, або каталог `npm/rules/` відсутній (у такому випадку додатково логиться `pass`-повідомлення `"npm/rules/ відсутній — немає правил для валідації"`);
|
|
38
|
-
- `1` — зафіксовано принаймні одне порушення (зокрема: залишковий `auto.md`, відсутній/невалідний `meta.json`, нерозпізнаний `auto`, невідомий `predicate`, нерозпізнаний `lint`, або `lint` без `js/lint.mjs`).
|
|
39
|
-
- **Side effects:**
|
|
40
|
-
- Виконує синхронне читання файлової системи: `existsSync` для перевірки наявності `npm/rules/`, `npm/rules/<id>/auto.md`, `npm/rules/<id>/js/lint.mjs`; `readdirSync` зі списком підкаталогів `npm/rules/`.
|
|
41
|
-
- Делегує читання та парсинг `meta.json` у `readRuleMetaRaw` (також синхронне читання файла).
|
|
42
|
-
- Викликає методи репортера (`reporter.pass`, `reporter.fail`), які за домовленістю виводять статусні повідомлення (зазвичай у stdout/stderr — залежно від реалізації `createCheckReporter`).
|
|
43
|
-
- Не змінює файли на диску, не запускає дочірніх процесів, не звертається до мережі.
|
|
44
|
-
- **Алгоритм:**
|
|
45
|
-
1. Створює репортер: `reporter = createCheckReporter()`.
|
|
46
|
-
2. Обчислює `rulesDir = join(cwd, 'npm', 'rules')`.
|
|
47
|
-
3. Якщо `rulesDir` не існує — рапортує `pass` і резолвить `Promise.resolve(reporter.getExitCode())` (зазвичай `0`).
|
|
48
|
-
4. Інакше перебирає вміст `rulesDir` через `readdirSync(rulesDir, { withFileTypes: true })` і для кожного запису:
|
|
49
|
-
- пропускає, якщо це не каталог (`!entry.isDirectory()`) або імʼя починається з крапки (`entry.name.startsWith('.')`);
|
|
50
|
-
- встановлює локальний прапор `ruleOk = true`;
|
|
51
|
-
- якщо знайдено залишковий `auto.md` у каталозі правила — `reporter.fail(...)`, `ruleOk = false`;
|
|
52
|
-
- читає сирий обʼєкт метаданих через `readRuleMetaRaw(ruleDir)`. Якщо повернуто falsy — `reporter.fail("rules/<id>: відсутній або невалідний meta.json")` і `continue` (наступне правило);
|
|
53
|
-
- якщо `raw.auto !== undefined` — парсить через `parseRuleAutoSpec(raw.auto)`:
|
|
54
|
-
- якщо повернуто `null` — `reporter.fail(...)`, `ruleOk = false`;
|
|
55
|
-
- інакше якщо в `spec` є ключ `'predicate'` і його значення немає у `RULE_PREDICATES` — `reporter.fail(...)`, `ruleOk = false`;
|
|
56
|
-
- якщо `raw.lint !== undefined` — валідує через `parseRuleLintPhase(raw.lint)`:
|
|
57
|
-
- якщо повернуто `null` — `reporter.fail(...)`, `ruleOk = false`;
|
|
58
|
-
- інакше якщо немає файла `<ruleDir>/js/lint.mjs` — `reporter.fail(...)`, `ruleOk = false`;
|
|
59
|
-
- наприкінці ітерації, якщо `ruleOk` усе ще `true` — `reporter.pass("rules/<id>: meta.json валідний")`.
|
|
60
|
-
5. Резолвить `Promise.resolve(reporter.getExitCode())` із підсумковим кодом виходу.
|
|
61
|
-
- **Особливості реалізації:**
|
|
62
|
-
- Усі гілки порушень для одного правила фіксуються незалежно одна від одної (наприклад, у тому ж проході може бути зафіксовано і нерозпізнаний `auto`, і нерозпізнаний `lint`). Виняток — повністю відсутній/невалідний `meta.json`: тоді решта перевірок для цього правила пропускається через `continue`.
|
|
63
|
-
- Функція синхронно виконує всю роботу, але повертає `Promise<number>` через `Promise.resolve(...)` — для уніфікованої сигнатури з іншими `check`-модулями.
|
|
64
|
-
- Перевірка `'predicate' in spec` дозволяє валідувати лише гілку `{predicate}`-специфікації; інші форми (`"завжди"`, масив, `{glob}`) уже визнані валідними самим `parseRuleAutoSpec`.
|
|
65
|
-
|
|
66
|
-
## Залежності
|
|
67
|
-
|
|
68
|
-
### Зовнішні (Node.js standard library)
|
|
69
|
-
|
|
70
|
-
- `node:fs` — `existsSync` (перевірка існування файлів і каталогів), `readdirSync` (читання вмісту каталогу `npm/rules/`).
|
|
71
|
-
- `node:path` — `join` (формування шляхів до каталогів і файлів).
|
|
72
|
-
|
|
73
|
-
### Внутрішні (репо-локальні)
|
|
74
|
-
|
|
75
|
-
- `../../../scripts/lib/check-reporter.mjs` — `createCheckReporter()`. Створює репортер з методами `pass(msg)`, `fail(msg)`, `getExitCode()`; останній використовується для отримання підсумкового коду виходу.
|
|
76
|
-
- `../../../scripts/lib/rule-meta.mjs`:
|
|
77
|
-
- `readRuleMetaRaw(ruleDir)` — читає та парсить сирий `meta.json` із каталогу правила; повертає обʼєкт або falsy (за відсутності/невалідності файла).
|
|
78
|
-
- `parseRuleAutoSpec(value)` — парсить значення поля `auto`; повертає валідовану специфікацію або `null` за нерозпізнаним вводом.
|
|
79
|
-
- `parseRuleLintPhase(value)` — парсить значення поля `lint`; повертає валідовану фазу (`"quick"`/`"ci"`) або `null`.
|
|
80
|
-
- `../../../scripts/lib/rule-predicates.mjs` — `RULE_PREDICATES`: обʼєкт-реєстр відомих імен предикатів; ключі використовуються для перевірки наявності предиката через `Object.hasOwn`.
|
|
81
|
-
|
|
82
|
-
### Глобальні
|
|
83
|
-
|
|
84
|
-
- `process.cwd()` — використовується як дефолтний `cwd`.
|
|
85
|
-
|
|
86
|
-
## Потік виконання / Використання
|
|
87
|
-
|
|
88
|
-
Модуль є check-функцією конкретного правила і підпорядкований конвенції `check-{id}` (тут — `rule_meta`). Очікуваний сценарій використання:
|
|
89
|
-
|
|
90
|
-
1. Виклик з вищерівневого скрипта (наприклад, агрегованої перевірки правил пакета):
|
|
91
|
-
|
|
92
|
-
```js
|
|
93
|
-
import { check } from './npm/rules/npm-module/js/rule_meta.mjs'
|
|
94
|
-
|
|
95
|
-
const exit = await check(process.cwd())
|
|
96
|
-
process.exit(exit)
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
У такому сценарії функцію викликають із кореня репозиторію пакета `@nitra/cursor`.
|
|
100
|
-
|
|
101
|
-
2. Запуск у репо-споживачі (де `npm/rules/` відсутній) — функція тихо рапортує `pass` і повертає `0`, не блокуючи pipeline.
|
|
102
|
-
3. Сценарій порушення: будь-який із описаних інваріантів спричиняє `fail`-звіт і код виходу `1`, що сигналізує CI зупинку.
|
|
12
|
+
Перевіряє наявність директорії npm/rules у вказаному шляху. Ітерує по всіх директоріях у директорії npm/rules. Для кожної директорії виконує перевірку наявності файлу auto.md та валідність полів auto та lint у конфігурації meta.json. Перевіряє наявність файлу js/lint.mjs у каталозі правила. Збирає результати валідації та повертає код виходу репортера.
|
|
103
13
|
|
|
104
|
-
|
|
14
|
+
## Поведінка
|
|
105
15
|
|
|
106
|
-
|
|
107
|
-
|
|
16
|
+
1. Перевірка наявності директорії npm/rules у вказаному шляху.
|
|
17
|
+
2. Ітерація по всіх директоріях у директорії npm/rules.
|
|
18
|
+
3. Для кожної директорії виконується перевірка правила.
|
|
19
|
+
4. Перевірка наявності файлу auto.md у директорії правила.
|
|
20
|
+
5. Перевірка валідності поля auto у meta.json правила.
|
|
21
|
+
6. Перевірка наявності поля lint у meta.json правила.
|
|
22
|
+
7. Перевірка валідності поля lint у meta.json правила.
|
|
23
|
+
8. Перевірка наявності файлу js/lint.mjs у каталозі правила.
|
|
24
|
+
9. Збір результатів валідації.
|
|
25
|
+
10. Повернення коду виходу репортера.
|
|
108
26
|
|
|
109
|
-
|
|
27
|
+
## Публічний API
|
|
110
28
|
|
|
111
|
-
|
|
29
|
+
check — Валідує всі `npm/rules/<id>/meta.json`.
|
|
112
30
|
|
|
113
|
-
|
|
31
|
+
## Гарантії поведінки
|
|
114
32
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
- Рапортується `pass("npm/rules/ відсутній — немає правил для валідації")`, повертається `0`.
|
|
119
|
-
3. Які записи в `npm/rules/` пропускаються?
|
|
120
|
-
- Не-каталоги та елементи, чиє імʼя починається з `.`.
|
|
121
|
-
4. За наявності якого файла поряд із `meta.json` фіксується порушення?
|
|
122
|
-
- `auto.md` (повідомлення `"rules/<id>: залишковий auto.md — видали (метадані тепер у meta.json)"`).
|
|
123
|
-
5. Що відбувається, якщо `meta.json` відсутній або невалідний?
|
|
124
|
-
- `reporter.fail("rules/<id>: відсутній або невалідний meta.json")` і `continue` до наступного правила.
|
|
125
|
-
6. Які гілки валідації поля `auto`?
|
|
126
|
-
- Якщо `parseRuleAutoSpec` повертає `null` — fail (нерозпізнане).
|
|
127
|
-
- Якщо специфікація містить ключ `predicate`, але його значення відсутнє в `RULE_PREDICATES` — fail (`невідомий predicate`).
|
|
128
|
-
7. Які гілки валідації поля `lint`?
|
|
129
|
-
- Якщо `parseRuleLintPhase` повертає `null` — fail (`нерозпізнане, очікується "quick"|"ci"`).
|
|
130
|
-
- Якщо валідне, але немає `js/lint.mjs` — fail (`lint:"..." але немає js/lint.mjs`).
|
|
131
|
-
8. Як формується підсумковий код виходу?
|
|
132
|
-
- Через `reporter.getExitCode()`, обгорнутий у `Promise.resolve(...)`.
|
|
133
|
-
9. Чи синхронна реалізація?
|
|
134
|
-
- Так: усі IO операції — синхронні (`existsSync`, `readdirSync`, `readRuleMetaRaw`); проміс використано лише для уніфікації сигнатури.
|
|
135
|
-
10. Які `pass`-повідомлення можливі?
|
|
136
|
-
- `"npm/rules/ відсутній — немає правил для валідації"` (за відсутності каталогу).
|
|
137
|
-
- `"rules/<id>: meta.json валідний"` (за успішної валідації окремого правила).
|
|
33
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
34
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
35
|
+
- Не звертається до мережі.
|
|
@@ -1,190 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/npm-module/js/skill_meta.mjs
|
|
4
|
+
crc: a069397b
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# skill_meta.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Перевірка застосовується **виключно в репозиторії пакета**, де є каталог `npm/skills/`. Якщо каталог відсутній (наприклад, у проєктах-споживачах залежності), перевірка пропускається без помилки (повертає `pass`).
|
|
8
|
-
|
|
9
|
-
Для кожного підкаталогу `npm/skills/<id>/` модуль виконує контракт:
|
|
10
|
-
|
|
11
|
-
- забороняється залишковий файл `auto.md` (метадані мігровані на `meta.json`);
|
|
12
|
-
- файл `meta.json` має бути присутнім і валідним JSON-об'єктом з очікуваною структурою;
|
|
13
|
-
- поле `worktree` обов'язкове і має бути `boolean`;
|
|
14
|
-
- поле `auto` опціональне, але якщо є — має бути або рядком `"завжди"`, або непорожнім масивом рядків.
|
|
15
|
-
|
|
16
|
-
Результат акумулюється через `check-reporter` і повертається кодом виходу `0` (OK) або `1` (порушення).
|
|
17
|
-
|
|
18
|
-
## Експорти / API
|
|
19
|
-
|
|
20
|
-
| Експорт | Тип | Призначення |
|
|
21
|
-
| ------- | ---------- | -------------------------------------------------------------------------- |
|
|
22
|
-
| `check` | `function` | Іменований експорт; функція-перевірка метаданих скілів у вказаному корені. |
|
|
23
|
-
|
|
24
|
-
Модуль є ESM (`.mjs`), без `default` експорту.
|
|
25
|
-
|
|
26
|
-
## Функції
|
|
27
|
-
|
|
28
|
-
### `check(cwd?)`
|
|
29
|
-
|
|
30
|
-
**Сигнатура:**
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
export function check(cwd = process.cwd()): Promise<number>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
**Параметри:**
|
|
37
|
-
|
|
38
|
-
| Параметр | Тип | Обов'язковий | За замовчуванням | Опис |
|
|
39
|
-
| -------- | -------- | ------------ | ---------------- | ---------------------------------------------------------------- |
|
|
40
|
-
| `cwd` | `string` | ні | `process.cwd()` | Корінь репозиторію; від нього резолвиться шлях до `npm/skills/`. |
|
|
41
|
-
|
|
42
|
-
**Повертає:**
|
|
43
|
-
|
|
44
|
-
`Promise<number>` — код виходу від `reporter.getExitCode()`:
|
|
45
|
-
|
|
46
|
-
- `0` — усі перевірені скіли валідні (або каталог `npm/skills/` відсутній);
|
|
47
|
-
- `1` — щонайменше одне порушення зафіксовано через `reporter.fail(...)`.
|
|
48
|
-
|
|
49
|
-
Хоча всередині немає `async`/`await`, функція обертає результат у `Promise.resolve(...)` для однорідного API з іншими `check`-функціями в цьому проєкті.
|
|
50
|
-
|
|
51
|
-
**Алгоритм:**
|
|
52
|
-
|
|
53
|
-
1. Створюється локальний звітник: `reporter = createCheckReporter()`.
|
|
54
|
-
2. Будується шлях `skillsDir = join(cwd, 'npm', 'skills')`.
|
|
55
|
-
3. Якщо `skillsDir` не існує (`existsSync(...) === false`):
|
|
56
|
-
- викликається `reporter.pass('npm/skills/ відсутній — немає скілів для валідації')`;
|
|
57
|
-
- повертається `Promise.resolve(reporter.getExitCode())` (рання гілка).
|
|
58
|
-
4. Інакше — ітерація `readdirSync(skillsDir, { withFileTypes: true })`:
|
|
59
|
-
- пропускаються не-директорії та назви, що починаються з крапки (`.` префікс);
|
|
60
|
-
- для кожного скіла `id = entry.name` будується `skillDir = join(skillsDir, id)` і прапор `skillOk = true`.
|
|
61
|
-
5. Для кожного скіла послідовно перевіряється:
|
|
62
|
-
- **Залишковий `auto.md`**: якщо `existsSync(join(skillDir, 'auto.md'))`, фіксується
|
|
63
|
-
`fail("skills/<id>: залишковий auto.md — видали (метадані тепер у meta.json)")` і `skillOk = false`.
|
|
64
|
-
- **`meta.json` присутній/валідний**: викликається `raw = readSkillMetaRaw(skillDir)`.
|
|
65
|
-
Якщо `raw` falsy — фіксується `fail("skills/<id>: відсутній або невалідний meta.json ...")` і виконується `continue` (решта перевірок для цього скіла пропускається).
|
|
66
|
-
- **Тип `worktree`**: якщо `typeof raw.worktree !== 'boolean'` — `fail("skills/<id>: meta.json.worktree має бути boolean")` і `skillOk = false`.
|
|
67
|
-
- **Розпізнаваність `auto`**: якщо `raw.auto !== undefined` і `parseSkillAutoSpec(raw.auto) === null` — `fail("skills/<id>: meta.json.auto нерозпізнане — очікується \"завжди\" або непорожній масив правил")` і `skillOk = false`.
|
|
68
|
-
6. Якщо після всіх перевірок цього скіла `skillOk === true`, фіксується `pass("skills/<id>: meta.json валідний")`.
|
|
69
|
-
7. Після проходу всіх скілів повертається `Promise.resolve(reporter.getExitCode())`.
|
|
70
|
-
|
|
71
|
-
**Side effects:**
|
|
72
|
-
|
|
73
|
-
- читання файлової системи (`existsSync`, `readdirSync`) — синхронне;
|
|
74
|
-
- мутація стану внутрішнього звітника (`createCheckReporter()`) через `pass(...)` / `fail(...)`;
|
|
75
|
-
- запис у `stdout`/`stderr` залежить від реалізації `check-reporter` (зазвичай агрегує повідомлення для подальшого виводу викликачем);
|
|
76
|
-
- **не змінює** жодних файлів і **не** створює директорій.
|
|
77
|
-
|
|
78
|
-
**Поведінкові інваріанти:**
|
|
79
|
-
|
|
80
|
-
- Відсутність `npm/skills/` — не помилка, а явний `pass` (модуль працює і в репо-споживачі).
|
|
81
|
-
- Невалідний `meta.json` зупиняє подальші перевірки конкретного скіла (`continue`), але **не зупиняє** обхід інших скілів.
|
|
82
|
-
- Прихований запис (назва починається з `.`) ігнорується, тож `.DS_Store` чи `.tmp` не плутають перевірку.
|
|
83
|
-
- Перевірка детермінована: результат залежить тільки від вмісту `npm/skills/` у `cwd`.
|
|
84
|
-
|
|
85
|
-
## Залежності
|
|
86
|
-
|
|
87
|
-
### Стандартна бібліотека Node.js
|
|
88
|
-
|
|
89
|
-
| Модуль | Імпортовані символи | Використання |
|
|
90
|
-
| ----------- | --------------------------- | -------------------------------------------------------------------- |
|
|
91
|
-
| `node:fs` | `existsSync`, `readdirSync` | перевірка наявності `npm/skills/`, `auto.md`; читання списку скілів. |
|
|
92
|
-
| `node:path` | `join` | побудова крос-платформних шляхів до каталогів і файлів. |
|
|
93
|
-
|
|
94
|
-
### Внутрішні модулі проєкту
|
|
95
|
-
|
|
96
|
-
| Модуль | Імпортовані символи | Використання |
|
|
97
|
-
| ----------------------------------------- | ---------------------------------------- | --------------------------------------------------------------------------- |
|
|
98
|
-
| `../../../scripts/lib/check-reporter.mjs` | `createCheckReporter` | створення звітника з API `pass(msg)` / `fail(msg)` / `getExitCode()`. |
|
|
99
|
-
| `../../../scripts/lib/skill-meta.mjs` | `readSkillMetaRaw`, `parseSkillAutoSpec` | читання сирого `meta.json` зі скіла; парсинг/валідація специфікації `auto`. |
|
|
100
|
-
|
|
101
|
-
### Контракти зовнішніх модулів (як використовуються в коді)
|
|
102
|
-
|
|
103
|
-
- `createCheckReporter()` → об'єкт із методами `pass(message: string)`, `fail(message: string)`, `getExitCode(): number` (`0` якщо не було `fail`, `1` якщо хоч раз був).
|
|
104
|
-
- `readSkillMetaRaw(skillDir: string)` → розпарсений об'єкт `meta.json` або falsy (наприклад, `null`) якщо файл відсутній/невалідний.
|
|
105
|
-
- `parseSkillAutoSpec(value)` → нормалізована специфікація `auto` або `null`, якщо значення нерозпізнане. Прийнятні форми: рядок `"завжди"` або непорожній масив рядків.
|
|
106
|
-
|
|
107
|
-
## Потік виконання / Використання
|
|
108
|
-
|
|
109
|
-
### Контекст
|
|
110
|
-
|
|
111
|
-
Модуль викликається з раннера правил концерну `npm-module` (точка входу `npm/rules/npm-module/js/index.mjs` або аналог). У типовому пайплайні `bun run lint` / `n-cursor check` всі `check`-функції правил зібрані в реєстр і виконуються послідовно; результат об'єднується в загальний код виходу процесу.
|
|
112
|
-
|
|
113
|
-
### Типовий виклик
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
import { check } from './skill_meta.mjs'
|
|
117
|
-
|
|
118
|
-
const exitCode = await check() // використає process.cwd()
|
|
119
|
-
process.exit(exitCode)
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Або з явним коренем (тести/інтеграція):
|
|
123
|
-
|
|
124
|
-
```js
|
|
125
|
-
const exitCode = await check('/abs/path/to/repo-root')
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Сценарій 1: репо самого пакета `@nitra/cursor`
|
|
129
|
-
|
|
130
|
-
- `npm/skills/` існує, містить кілька скілів (наприклад, `n-docgen/`, `n-fix/`, `mdc-check/`).
|
|
131
|
-
- Для кожного скіла читається `meta.json`, перевіряються `worktree` (boolean) і `auto` (опціонально).
|
|
132
|
-
- Якщо хоч один скіл має `auto.md`, або відсутній/невалідний `meta.json`, або `worktree` не boolean, або `auto` нерозпізнане — функція повертає `1`.
|
|
133
|
-
- Інакше — `0`.
|
|
134
|
-
|
|
135
|
-
### Сценарій 2: проєкт-споживач `@nitra/cursor`
|
|
136
|
-
|
|
137
|
-
- `npm/skills/` відсутній (інша файлова структура).
|
|
138
|
-
- Функція фіксує `pass(...)`, повертає `0` і не виконує жодної ітерації.
|
|
139
|
-
- Це дозволяє правилам пакета транзитивно застосовуватися в чужих проєктах без false-negative.
|
|
140
|
-
|
|
141
|
-
### Сценарій 3: переходова міграція на `meta.json`
|
|
142
|
-
|
|
143
|
-
- У скілі лишилася стара пам'ятка-метадані `auto.md` поряд з новим `meta.json`.
|
|
144
|
-
- Перевірка явно фейлить такий скіл повідомленням `залишковий auto.md — видали (метадані тепер у meta.json)`.
|
|
145
|
-
- Це примушує закрити технічний борг міграції.
|
|
146
|
-
|
|
147
|
-
### Очікуваний формат `meta.json`
|
|
148
|
-
|
|
149
|
-
```json
|
|
150
|
-
{
|
|
151
|
-
"worktree": true,
|
|
152
|
-
"auto": "завжди"
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
або
|
|
157
|
-
|
|
158
|
-
```json
|
|
159
|
-
{
|
|
160
|
-
"worktree": false,
|
|
161
|
-
"auto": ["n-bun", "n-flow"]
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
або (мінімально):
|
|
12
|
+
Перевірка стану конфігурації. Файл перевіряє відповідність між полями worktree та requireRoot. Перевірка спирається на конфіги meta.json.
|
|
166
13
|
|
|
167
|
-
|
|
168
|
-
{
|
|
169
|
-
"worktree": false
|
|
170
|
-
}
|
|
171
|
-
```
|
|
14
|
+
## Поведінка
|
|
172
15
|
|
|
173
|
-
|
|
16
|
+
1. Перевірка поля worktree
|
|
17
|
+
2. Перевірка поля auto
|
|
18
|
+
3. Перевірка поля requireRoot
|
|
19
|
+
4. Перевірка суперечності between worktree та requireRoot
|
|
174
20
|
|
|
175
|
-
|
|
176
|
-
- `{"worktree": "yes"}` → `meta.json.worktree має бути boolean`;
|
|
177
|
-
- `{"worktree": true, "auto": []}` або `{"worktree": true, "auto": "always"}` → `meta.json.auto нерозпізнане ...`;
|
|
178
|
-
- наявний `auto.md` поряд → `залишковий auto.md — видали`.
|
|
21
|
+
## Публічний API
|
|
179
22
|
|
|
180
|
-
|
|
23
|
+
check — Валідує всі `npm/skills/<id>/meta.json`.
|
|
181
24
|
|
|
182
|
-
|
|
25
|
+
## Гарантії поведінки
|
|
183
26
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
3. Замінити `worktree` на рядок (`"true"`) → `check(tmp)` має повернути `1` з повідомленням про boolean.
|
|
187
|
-
4. Додати `npm/skills/foo/auto.md` → `check(tmp)` має повернути `1` з повідомленням про залишковий `auto.md`.
|
|
188
|
-
5. Видалити `meta.json` → `check(tmp)` має повернути `1` з повідомленням про відсутній/невалідний `meta.json`.
|
|
189
|
-
6. Створити `npm/skills/.hidden/` — перевірка має ігнорувати її (повернути `0`, якщо інших скілів немає).
|
|
190
|
-
7. Додати `npm/skills/bar/meta.json` з `{"worktree": false, "auto": "завжди"}` → `pass`; замінити `auto` на `"always"` → `fail` про нерозпізнане `auto`.
|
|
27
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
28
|
+
- Не звертається до мережі.
|
|
@@ -3,7 +3,7 @@ import { existsSync, readdirSync } from 'node:fs'
|
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
|
|
5
5
|
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|
|
6
|
-
import { parseRuleAutoSpec,
|
|
6
|
+
import { parseRuleAutoSpec, parseRuleLintSpec, readRuleMetaRaw } from '../../../scripts/lib/rule-meta.mjs'
|
|
7
7
|
import { RULE_PREDICATES } from '../../../scripts/lib/rule-predicates.mjs'
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -37,8 +37,8 @@ function checkAutoField(id, raw, reporter) {
|
|
|
37
37
|
*/
|
|
38
38
|
function checkLintField(id, ruleDir, raw, reporter) {
|
|
39
39
|
if (raw.lint === undefined) return true
|
|
40
|
-
if (
|
|
41
|
-
reporter.fail(`rules/${id}: meta.json.lint нерозпізнане (очікується "
|
|
40
|
+
if (parseRuleLintSpec(raw.lint) === null) {
|
|
41
|
+
reporter.fail(`rules/${id}: meta.json.lint нерозпізнане (очікується "per-file"|"full")`)
|
|
42
42
|
return false
|
|
43
43
|
}
|
|
44
44
|
if (!existsSync(join(ruleDir, 'js', 'lint.mjs'))) {
|
package/rules/php/docs/fix.md
CHANGED
|
@@ -1,114 +1,37 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/rules/php/fix.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 38cf876b
|
|
5
|
+
score: 100
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
# fix.mjs
|
|
8
|
+
# fix.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Виконує застосування політики JS-занепокоєних до mdc-refs на вхідному контексті прогону та повертає результат.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. **Standalone mode** — коли файл запускається напряму через `bun rules/php/fix.mjs`, він діє як самостійний CLI-скрипт, що є повним еквівалентом команди `npx @nitra/cursor fix php` (з підтягуванням конфігурації, whitelist і фінальним summary).
|
|
14
|
+
Виконується при запуску через командний рядок, виконуючи повний еквівалент команди `npx @nitra/cursor fix <id>` та повертає код виходу.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Поведінка
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
1. Запуск правила.
|
|
19
|
+
* Приймає контекст прогону.
|
|
20
|
+
* Виконує застосування JS-занепокоєних до політики до mdc-refs.
|
|
21
|
+
* Повертає результат прогону.
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
2. Запуск у режимі CLI.
|
|
24
|
+
* Виконується при запуску через CLI.
|
|
25
|
+
* Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
|
|
26
|
+
* Повертає код виходу.
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
## Публічний API
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
31
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
## Гарантії поведінки
|
|
29
34
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- **Параметри:**
|
|
35
|
-
- `ctx` _(опціональний)_ — об'єкт типу `RuleContext`, імпортований з `../../scripts/lib/run-standard-rule.mjs`. Передається оркестратором і містить кеш обходу файлової системи (`walkCache`) та інші розшаровані між правилами дані. Якщо не передано — `runStandardRule` створює власний локальний контекст.
|
|
36
|
-
- **Повертає:** `Promise<number>` — exit-code прогону:
|
|
37
|
-
- `0` — правило пройшло без порушень;
|
|
38
|
-
- `1` — виявлено порушення (або правило завершилось помилкою, яку оркестратор мапить на ненульовий код).
|
|
39
|
-
- **Side effects:**
|
|
40
|
-
- Делегує всю реальну роботу `runStandardRule`: читання файлів, виконання чекерів, друк summary до `stdout`/`stderr`.
|
|
41
|
-
- Сам `run` не має власних побічних ефектів — це тонкий wrapper.
|
|
42
|
-
- **Як визначається корінь правила:** через `import.meta.dirname` — абсолютний шлях до директорії, в якій лежить `fix.mjs`. Це дозволяє `runStandardRule` знайти сусідні файли правила (`applies.mjs`, `policy.mjs`, `checks/*.mjs`, `*.mdc` тощо) без додаткових параметрів.
|
|
43
|
-
|
|
44
|
-
## Залежності
|
|
45
|
-
|
|
46
|
-
Файл імпортує дві утиліти з внутрішньої бібліотеки `npm/scripts/lib/`:
|
|
47
|
-
|
|
48
|
-
| Імпорт | Звідки | Призначення |
|
|
49
|
-
| ----------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
50
|
-
| `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Детектор «чи модуль запущений напряму як CLI». Порівнює `import.meta.url` із `process.argv[1]`. Використовується для гілки standalone. |
|
|
51
|
-
| `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Повноцінний CLI-runner правила: парсить аргументи, підтягує config, застосовує whitelist, друкує summary. Повертає `Promise<number>` із exit-кодом. |
|
|
52
|
-
| `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Стандартний pipeline правила: послідовно виконує стадії `applies → JS-concerns → policy → mdc-refs`. Приймає шлях до директорії правила та опційний `RuleContext`. |
|
|
53
|
-
|
|
54
|
-
Зовнішніх npm-залежностей файл не має — лише внутрішні модулі монорепо.
|
|
55
|
-
|
|
56
|
-
## Потік виконання / Використання
|
|
57
|
-
|
|
58
|
-
### Сценарій A — виклик з оркестратора (library mode)
|
|
59
|
-
|
|
60
|
-
1. CLI `@nitra/cursor fix` (або агрегатор) знаходить правило `php` за його директорією.
|
|
61
|
-
2. Динамічно імпортує `fix.mjs` і викликає `await run(ctx)`, передаючи спільний `RuleContext` (зокрема `walkCache`, щоб уникнути повторного обходу ФС між правилами).
|
|
62
|
-
3. `run` делегує виклик `runStandardRule(import.meta.dirname, ctx)`.
|
|
63
|
-
4. `runStandardRule` повертає exit-code; оркестратор агрегує коди всіх правил.
|
|
64
|
-
|
|
65
|
-
```js
|
|
66
|
-
import { run } from '@nitra/cursor/rules/php/fix.mjs'
|
|
67
|
-
|
|
68
|
-
const code = await run(sharedCtx)
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Сценарій B — прямий запуск файлу (standalone mode)
|
|
72
|
-
|
|
73
|
-
1. Користувач (або IDE/CI) виконує:
|
|
74
|
-
```bash
|
|
75
|
-
bun npm/rules/php/fix.mjs
|
|
76
|
-
```
|
|
77
|
-
2. Top-level `if (isRunAsCli(import.meta.url))` повертає `true` (бо `import.meta.url` збігається з шляхом запущеного скрипта).
|
|
78
|
-
3. Викликається `await runRuleCli(import.meta.dirname)` — повноцінний CLI-режим: підвантажує конфігурацію, застосовує whitelist, друкує підсумок.
|
|
79
|
-
4. `process.exit(...)` завершує процес із отриманим exit-кодом, аби CI/IDE могли коректно інтерпретувати результат.
|
|
80
|
-
|
|
81
|
-
### Семантика exit-кодів
|
|
82
|
-
|
|
83
|
-
- `0` — правило застосовне та порушень не виявлено (або правило незастосовне для цього проєкту — `applies` повернув `false`).
|
|
84
|
-
- `1` — є порушення, які треба виправити.
|
|
85
|
-
|
|
86
|
-
### Коментарі та лінт-винятки
|
|
87
|
-
|
|
88
|
-
У standalone-гілці явно вимкнено два правила лінтера:
|
|
89
|
-
|
|
90
|
-
```js
|
|
91
|
-
// eslint-disable-next-line n/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
|
|
92
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Це свідомий виняток: `process.exit` тут потрібний, щоб CLI/CI отримали ненульовий код у разі порушень — без нього процес міг би завершитись із кодом `0` навіть за наявності знайдених проблем.
|
|
96
|
-
|
|
97
|
-
## Архітектурний контекст
|
|
98
|
-
|
|
99
|
-
- **Конвенція файлу `fix.mjs`** — у директорії кожного правила (`npm/rules/<id>/fix.mjs`) лежить однотипний тонкий wrapper із двома ролями (library + standalone). Це гарантує:
|
|
100
|
-
- єдиний інтерфейс для оркестратора (`run(ctx)`);
|
|
101
|
-
- можливість запускати окреме правило ізольовано (для дебагу/CI per-rule).
|
|
102
|
-
- **Чому через `import.meta.dirname`** — `runStandardRule` за директорією правила автоматично знаходить усі сусідні артефакти (`applies.mjs`, `policy.mjs`, `checks/*.mjs`, `*.mdc`). Це уникає дублювання id-правила як рядка.
|
|
103
|
-
- **Patch-free wrapper** — у самому `fix.mjs` не повинно з'являтися PHP-специфічної логіки; будь-які зміни поведінки правила робляться у сусідніх файлах правила, а не в цьому entry-point'і.
|
|
104
|
-
|
|
105
|
-
## Rebuild Test
|
|
106
|
-
|
|
107
|
-
Файл можна повністю відтворити з опису вище за такими інваріантами:
|
|
108
|
-
|
|
109
|
-
1. Два імпорти: `{ isRunAsCli, runRuleCli }` з `../../scripts/lib/run-rule-cli.mjs` і `{ runStandardRule }` з `../../scripts/lib/run-standard-rule.mjs`.
|
|
110
|
-
2. Іменований експорт `function run(ctx)` — однорядкове тіло `return runStandardRule(import.meta.dirname, ctx)`.
|
|
111
|
-
3. JSDoc над `run`: опис стадій (applies → JS-concerns → policy → mdc-refs), згадка library mode, тип параметра `ctx` через `import('...').RuleContext`, тип повернення `Promise<number>` із семантикою 0/1.
|
|
112
|
-
4. Блок `if (isRunAsCli(import.meta.url)) { ... }` із викликом `process.exit(await runRuleCli(import.meta.dirname))` і коментарем-поясненням про дві ролі fix.mjs.
|
|
113
|
-
5. Лінт-disable перед `process.exit`: `n/no-process-exit, unicorn/no-process-exit` із обґрунтуванням «standalone entry-point має повертати exit-code для CI/IDE».
|
|
114
|
-
6. Жодних інших top-level операцій, жодного `default`-експорту.
|
|
35
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
36
|
+
- Кешує результати в межах одного прогону.
|
|
37
|
+
- Не звертається до мережі.
|