@nitra/cursor 5.3.4 → 5.4.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 +11 -0
- package/bin/n-cursor.js +43 -22
- 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-ignore.mjs +2 -1
- package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
- 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 +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-gen.md +1 -1
- 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/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-ci/docs/fix.md +16 -149
- package/rules/js-lint-ci/js/docs/lint.md +16 -136
- 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/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/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/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/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/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-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-predicates.mjs +1 -1
- 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-files-batch.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-gen.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,152 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/test/js/stryker_config.mjs
|
|
4
|
+
crc: 7ea109c6
|
|
5
|
+
score: 95
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# stryker_config.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
- `reporter` (`ReturnType<typeof createCheckReporter>`) — check-reporter для логування статусів pass/fail.
|
|
47
|
-
- `cwd` (`string`) — корінь проєкту, використовується для побудови relative-шляхів у повідомленнях.
|
|
48
|
-
- `baselinePath` (`string`) — абсолютний шлях до canonical baseline-файла у пакеті.
|
|
49
|
-
- `target` (`string`) — абсолютний шлях, куди копіювати baseline.
|
|
50
|
-
- `label` (`string`) — людиночитна мітка для логу (наприклад, `"stryker.config.mjs"` чи `"vitest.config.js"`).
|
|
51
|
-
- **Повертає:** `Promise<void>`.
|
|
52
|
-
- **Поведінка:** якщо `target` вже існує (`existsSync`) — логує `reporter.pass` із позначкою "існує" і виходить. Якщо ні — копіює `baselinePath` у `target` через `copyFile` і логує `reporter.pass` із поміткою "створено з canonical baseline ... (test.mdc)".
|
|
53
|
-
- **Side effects:** запис файлу через `copyFile` (тільки якщо target був відсутній); запис у reporter.
|
|
54
|
-
- **Idempotent:** так — повторний виклик на існуючому target не перезаписує файл.
|
|
55
|
-
|
|
56
|
-
### `check(cwd = process.cwd())`
|
|
57
|
-
|
|
58
|
-
```js
|
|
59
|
-
export async function check(cwd = process.cwd())
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
- **Параметри:**
|
|
63
|
-
- `cwd` (`string`, опціональний) — корінь проєкту. За замовчуванням `process.cwd()` для CLI-сумісності.
|
|
64
|
-
- **Повертає:** `Promise<number>` — exit code (`0` — OK або silently skipped, `1` — порушення).
|
|
65
|
-
- **Side effects:**
|
|
66
|
-
- Читає `.n-cursor.json` через `readNCursorConfigLite`.
|
|
67
|
-
- Викликає `resolveAllJsRoots` для отримання списку JS-roots.
|
|
68
|
-
- Перевіряє існування canonical baseline-файлів у самому пакеті.
|
|
69
|
-
- Копіює `stryker.config.mjs` (canonical або vue-варіант), `vitest.config.js`, а для Vue-roots — `stryker-vue-macros-ignorer.mjs` у кожен JS-root, де відповідний файл відсутній.
|
|
70
|
-
- Додає у кореневий `.gitignore` патерни `**/reports/stryker/` і `**/coverage/`, якщо їх там немає, через `ensureGitignoreEntries` із коментарем-секцією `"Test artifacts: Stryker + coverage (test.mdc)"`.
|
|
71
|
-
- Накопичує статуси у reporter і повертає його exit code.
|
|
72
|
-
|
|
73
|
-
## Залежності
|
|
74
|
-
|
|
75
|
-
Стандартні модулі Node.js:
|
|
76
|
-
|
|
77
|
-
- `node:fs` — `existsSync` (синхронна перевірка наявності файла).
|
|
78
|
-
- `node:fs/promises` — `copyFile` (копіювання baseline у target), `glob` (пошук `.vue` файлів).
|
|
79
|
-
- `node:path` — `dirname`, `join`, `relative` (побудова абсолютних і relative шляхів).
|
|
80
|
-
- `node:url` — `fileURLToPath` (конвертація `import.meta.url` у POSIX-шлях для `dirname`).
|
|
81
|
-
|
|
82
|
-
Внутрішні залежності пакета:
|
|
83
|
-
|
|
84
|
-
- `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика reporter-а з API `pass(msg)`, `fail(msg)`, `getExitCode()`.
|
|
85
|
-
- `../../../scripts/lib/read-n-cursor-config-lite.mjs` → `readNCursorConfigLite` — читання `.n-cursor.json`, повертає об'єкт із полями `rules: string[]`, `disableRules: string[]`.
|
|
86
|
-
- `../../../scripts/utils/ensure-gitignore-entries.mjs` → `ensureGitignoreEntries(cwd, entries, sectionLabel)` — idempotent додавання патернів у кореневий `.gitignore`. Повертає `{ added: string[] }`.
|
|
87
|
-
- `../../../scripts/utils/resolve-js-root.mjs` → `resolveAllJsRoots(cwd)` — повертає масив абсолютних шляхів до всіх JS-roots: усі workspaces із `package.json` у monorepo, або `[cwd]` у single-package.
|
|
88
|
-
|
|
89
|
-
Зовнішні дані-файли (canonical baseline у пакеті `@nitra/cursor`):
|
|
90
|
-
|
|
91
|
-
- `data/stryker_config/stryker.config.baseline.mjs` — стандартний baseline Stryker (vitest-runner + perTest, mutate-патерни на Stryker defaults `src/**/*.{js,mjs,ts,jsx,tsx,cjs}`).
|
|
92
|
-
- `data/stryker_config/stryker.config.vue.baseline.mjs` — vue-варіант baseline; реєструє локальний Ignore-плагін `vue-macros`, щоб Stryker не загортав `defineProps`/`defineEmits`/... у coverage-тернарник (інакше `@vue/compiler-sfc` падає при компіляції SFC).
|
|
93
|
-
- `data/stryker_config/stryker-vue-macros-ignorer.mjs` — сам Stryker-плагін, який копіюється поруч із vue-варіантом baseline і реєструється з нього.
|
|
94
|
-
- `data/vitest_config/vitest.config.baseline.js` — мінімальний baseline Vitest для runner-а.
|
|
95
|
-
|
|
96
|
-
## Константи модуля
|
|
97
|
-
|
|
98
|
-
- `HERE` — каталог самого `stryker_config.mjs` (`dirname(fileURLToPath(import.meta.url))`).
|
|
99
|
-
- `STRYKER_BASELINE_PATH` — абсолютний шлях до стандартного `stryker.config.baseline.mjs`.
|
|
100
|
-
- `STRYKER_VUE_BASELINE_PATH` — абсолютний шлях до vue-варіанта baseline.
|
|
101
|
-
- `STRYKER_VUE_PLUGIN_PATH` — абсолютний шлях до `stryker-vue-macros-ignorer.mjs` у пакеті.
|
|
102
|
-
- `STRYKER_VUE_PLUGIN_FILENAME = 'stryker-vue-macros-ignorer.mjs'` — ім'я файлу, під яким плагін копіюється у jsRoot.
|
|
103
|
-
- `VITEST_BASELINE_PATH` — абсолютний шлях до canonical `vitest.config.baseline.js`.
|
|
104
|
-
- `TEST_GITIGNORE_ENTRIES = ['**/reports/stryker/', '**/coverage/']` — патерни, які додаються в корений `.gitignore`. Подвійний-зірочка-префікс `**/` забезпечує покриття всіх workspaces у monorepo (єдиний root `.gitignore`).
|
|
105
|
-
- `VUE_GLOB_PATTERN = 'src/**/*.vue'` — scope пошуку `.vue` файлів (відповідає Stryker mutate defaults для `src/`).
|
|
106
|
-
- `VUE_GLOB_IGNORE = ['**/node_modules/**', '**/dist/**', '**/reports/**']` — пропускаються build-артефакти і чужі `node_modules`, щоб не активувати vue-варіант через transitive-deps.
|
|
107
|
-
|
|
108
|
-
## Потік виконання / Використання
|
|
109
|
-
|
|
110
|
-
Концерн запускається або через CLI пакета `@nitra/cursor` (як один із checks правила `test`), або імпортно з іншого скрипта.
|
|
111
|
-
|
|
112
|
-
Алгоритм `check(cwd)` крок за кроком:
|
|
113
|
-
|
|
114
|
-
1. Створює `reporter` через `createCheckReporter()`.
|
|
115
|
-
2. Читає конфіг `.n-cursor.json` через `readNCursorConfigLite(cwd)`.
|
|
116
|
-
3. **Self-gate:** якщо `js-lint` відсутнє в `config.rules`, або присутнє в `config.disableRules` — повертає `reporter.getExitCode()` без жодних повідомлень (silently skipped). Це навмисна поведінка, щоб не шуміти у проєктах без JS coverage tooling.
|
|
117
|
-
4. Викликає `resolveAllJsRoots(cwd)`. Якщо повернувся порожній масив — це аномалія (`js-lint` enabled, але немає `package.json`); `reporter.fail` із повідомленням `'test: js-lint enabled, але кореневий package.json не знайдено (test.mdc)'` і повернення exit code.
|
|
118
|
-
5. Перевіряє існування всіх чотирьох canonical baseline-файлів у пакеті (`STRYKER_BASELINE_PATH`, `STRYKER_VUE_BASELINE_PATH`, `STRYKER_VUE_PLUGIN_PATH`, `VITEST_BASELINE_PATH`). Якщо будь-якого з них немає — `reporter.fail` із вимогою перевстановити `@nitra/cursor` і early-return.
|
|
119
|
-
6. Для кожного `jsRoot` із `jsRoots`:
|
|
120
|
-
- Визначає `isVueRoot = await hasVueFiles(jsRoot)`.
|
|
121
|
-
- Обирає `strykerBaseline = isVueRoot ? STRYKER_VUE_BASELINE_PATH : STRYKER_BASELINE_PATH`.
|
|
122
|
-
- Через `ensureBaselineFile` копіює `strykerBaseline` у `<jsRoot>/stryker.config.mjs` (якщо відсутній).
|
|
123
|
-
- Якщо `isVueRoot` — додатково через `ensureBaselineFile` копіює `STRYKER_VUE_PLUGIN_PATH` у `<jsRoot>/stryker-vue-macros-ignorer.mjs`.
|
|
124
|
-
- Через `ensureBaselineFile` копіює `VITEST_BASELINE_PATH` у `<jsRoot>/vitest.config.js`.
|
|
125
|
-
7. Викликає `ensureGitignoreEntries(cwd, TEST_GITIGNORE_ENTRIES, 'Test artifacts: Stryker + coverage (test.mdc)')` — додає в кореневий `.gitignore` патерни `**/reports/stryker/` і `**/coverage/` (якщо їх там немає). Якщо щось дійсно було додане (`added.length > 0`) — `reporter.pass` із перелічуванням доданих патернів.
|
|
126
|
-
8. Повертає `reporter.getExitCode()` — `0`, якщо жодного `fail` не було, інакше `1`.
|
|
127
|
-
|
|
128
|
-
### Приклад використання
|
|
129
|
-
|
|
130
|
-
```js
|
|
131
|
-
import { check } from '@nitra/cursor/rules/test/js/stryker_config.mjs'
|
|
132
|
-
|
|
133
|
-
const exitCode = await check(process.cwd())
|
|
134
|
-
process.exit(exitCode)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Зазвичай безпосередній виклик не потрібен — концерн запускається диспетчером правила `test` (`test.mdc`) у складі команди `n-cursor fix` / `n-cursor check`.
|
|
138
|
-
|
|
139
|
-
### Спостережувані ефекти у файловій системі
|
|
140
|
-
|
|
141
|
-
Після успішного прогону в кожному JS-root з'являються:
|
|
142
|
-
|
|
143
|
-
- `stryker.config.mjs` (стандартний або vue-варіант, залежно від наявності `.vue` у `src/`).
|
|
144
|
-
- `vitest.config.js`.
|
|
145
|
-
- `stryker-vue-macros-ignorer.mjs` — тільки для Vue-roots.
|
|
146
|
-
|
|
147
|
-
У кореневому `.gitignore` гарантовано присутні:
|
|
148
|
-
|
|
149
|
-
- `**/reports/stryker/`
|
|
150
|
-
- `**/coverage/`
|
|
151
|
-
|
|
152
|
-
Якщо файл уже існував — він не перезаписується, що дозволяє користувачу безпечно кастомізувати baseline під специфіку проєкту.
|
|
12
|
+
Цей файл виконує перевірку наявності певних файлів та конфігурацій у кореневих пакетах. Код працює з конфігами, визначеними у `mutation.json` та `package.json`, для забезпечення певних станів у системі.
|
|
13
|
+
|
|
14
|
+
## Поведінка
|
|
15
|
+
|
|
16
|
+
1. Перевірити наявність `js-lint` у конфігурації.
|
|
17
|
+
2. Зібрати кореневі пакети.
|
|
18
|
+
3. Перевірити наявність базових конфігурацій.
|
|
19
|
+
4. Перевірити наявність базлайн-файлів.
|
|
20
|
+
5. Для кожного кореневого пакета перевірити наявність `.vue` файлів.
|
|
21
|
+
6. Для кожного кореневого пакета згенерувати ім'я конфігурації.
|
|
22
|
+
7. Для кожного кореневого пакета перевірити наявність необхідних базлайн-файлів.
|
|
23
|
+
8. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
24
|
+
9. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
25
|
+
10. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
26
|
+
11. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
27
|
+
12. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
28
|
+
13. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
29
|
+
14. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
30
|
+
15. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
31
|
+
16. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
32
|
+
17. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
33
|
+
18. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
34
|
+
19. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
35
|
+
20. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
36
|
+
21. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
37
|
+
22. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
38
|
+
23. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
39
|
+
24. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
40
|
+
25. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
41
|
+
26. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
42
|
+
27. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
43
|
+
28. Для кожного кореневого пакета перевірити наявність базових базлайн-файлів.
|
|
44
|
+
29. Для кожного кореневого пакета перевірити наявність `stryker.config.mjs`.
|
|
45
|
+
30. Для кожного кореневого пакета перевірити наявність `vitest.config.mjs` або `vitest.config.js`.
|
|
46
|
+
|
|
47
|
+
## Гарантії поведінки
|
|
48
|
+
|
|
49
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
50
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
51
|
+
- Свідомо пропускає шляхи: `node_modules`.
|
|
52
|
+
- Не звертається до мережі.
|
|
@@ -1,174 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/test/js/vitest-config-pool-forks.mjs
|
|
4
|
+
crc: bb04a54b
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# vitest-config-pool-forks.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Контекст і мотивація:
|
|
8
|
-
|
|
9
|
-
- У `vitest` за замовчуванням використовується `pool: 'threads'`, де всі workers ділять один процес (Node.js worker_threads). Усі такі workers мають **спільний** `process.cwd()`. Якщо хоч один тест (або стороння залежність всередині нього) викликає `process.chdir(...)`, це впливає на всі інші тести, що виконуються паралельно — типовий race-bug.
|
|
10
|
-
- Простої заборони `process.chdir(` у тестах недостатньо: third-party код у залежностях може робити `chdir` всередині vitest worker'а непомітно.
|
|
11
|
-
- `pool: 'forks'` ізолює кожен test-файл у власному child-процесі, тож `process.cwd()` стає локальним для тесту.
|
|
12
|
-
|
|
13
|
-
Алгоритм перевірки — навмисно простий: substring/regex-пошук у сирому тексті `vitest.config.js`. AST-парсинг свідомо не використовується, бо конфіг може бути в довільному форматі експорту (ESM default, named export, CommonJS, factory-функція тощо), а сам ключ `pool: 'forks'` достатньо унікальний, щоб ідентифікувати його без парсера.
|
|
14
|
-
|
|
15
|
-
Скіп-семантика: якщо `vitest.config.js` відсутній — це означає, що в репозиторії немає налаштованого vitest, і правило **пропускається** (pass, не fail). Якщо файл є — `pool: 'forks'` обов'язковий.
|
|
16
|
-
|
|
17
|
-
## Експорти / API
|
|
18
|
-
|
|
19
|
-
| Експорт | Тип | Призначення |
|
|
20
|
-
| ------- | ------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
21
|
-
| `check` | `async function` (named export) | Точка входу для виконання перевірки конфігу. Повертає exit-code сумісний з CI-runner'ом. |
|
|
22
|
-
|
|
23
|
-
Модуль не має default export. Регулярний вираз `POOL_FORKS_RE` оголошений на рівні модуля, але **не** експортується — це внутрішня деталь реалізації.
|
|
24
|
-
|
|
25
|
-
## Функції
|
|
26
|
-
|
|
27
|
-
### `check(cwdParam?)`
|
|
28
|
-
|
|
29
|
-
Асинхронна перевірка наявності `pool: 'forks'` у `vitest.config.js`.
|
|
30
|
-
|
|
31
|
-
**Сигнатура:**
|
|
32
|
-
|
|
33
|
-
```js
|
|
34
|
-
export async function check(cwdParam = process.cwd()): Promise<number>
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**Параметри:**
|
|
38
|
-
|
|
39
|
-
| Ім'я | Тип | За замовчуванням | Опис |
|
|
40
|
-
| ---------- | -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
-
| `cwdParam` | `string` | `process.cwd()` | Абсолютний шлях до кореня репозиторію, в якому шукається `vitest.config.js`. Призначений насамперед для тестів (можна підставити фікстурну директорію). |
|
|
42
|
-
|
|
43
|
-
**Повертає:** `Promise<number>` — exit-code з `reporter.getExitCode()`:
|
|
44
|
-
|
|
45
|
-
- `0` — успіх (`pool: 'forks'` знайдено) **або** skip (`vitest.config.js` відсутній);
|
|
46
|
-
- `1` — помилка (файл є, але не містить `pool: 'forks'`).
|
|
47
|
-
|
|
48
|
-
**Side effects:**
|
|
49
|
-
|
|
50
|
-
- Створює локальний reporter через `createCheckReporter()`. Reporter виводить повідомлення `pass(...)` / `fail(...)` у консоль (формат залежить від реалізації reporter'а).
|
|
51
|
-
- Синхронно перевіряє існування файлу через `existsSync` (звернення до файлової системи).
|
|
52
|
-
- Якщо файл існує — асинхронно читає його повністю в пам'ять через `readFile(..., 'utf8')`.
|
|
53
|
-
- **Не** модифікує файлову систему та **не** мутує глобальний стан.
|
|
54
|
-
|
|
55
|
-
**Сценарії виконання:**
|
|
56
|
-
|
|
57
|
-
1. **`vitest.config.js` не існує** → `pass('vitest.config.js відсутній — pool-перевірку пропущено')` → повертає `0`.
|
|
58
|
-
2. **Файл існує, regex `/pool\s*:\s*['"]forks['"]/u` матчить** → `pass("vitest.config.js містить pool: 'forks' (test.mdc)")` → повертає `0`.
|
|
59
|
-
3. **Файл існує, але regex не матчить** → `fail("vitest.config.js має містити pool: 'forks' — defense-in-depth для race у process.cwd() між паралельними test files (test.mdc)")` → повертає `1`.
|
|
60
|
-
|
|
61
|
-
**Деталі регексу `POOL_FORKS_RE`:**
|
|
62
|
-
|
|
63
|
-
```js
|
|
64
|
-
const POOL_FORKS_RE = /pool\s*:\s*['"]forks['"]/u
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Регекс:
|
|
68
|
-
|
|
69
|
-
- `pool` — буквальний ключ;
|
|
70
|
-
- `\s*:\s*` — двокрапка з довільним whitespace навколо;
|
|
71
|
-
- `['"]forks['"]` — значення `forks` у одинарних або подвійних лапках;
|
|
72
|
-
- Прапор `u` — Unicode-мода для коректної семантики escape-послідовностей.
|
|
73
|
-
|
|
74
|
-
Регекс свідомо **не** перевіряє, що лапки парні (`'forks"` теоретично матчить). На практиці це не проблема, бо у валідному JS такі змішані лапки не зустрінуться (parse-error до того). Whitespace між токенами дозволений, але переноси рядка між `pool` і двокрапкою — лише ті, що покриваються `\s*`.
|
|
75
|
-
|
|
76
|
-
## Залежності
|
|
77
|
-
|
|
78
|
-
**Стандартна бібліотека Node.js:**
|
|
79
|
-
|
|
80
|
-
| Модуль | Імпортовані символи | Використання |
|
|
81
|
-
| ------------------ | ------------------- | --------------------------------------------------------------- |
|
|
82
|
-
| `node:fs` | `existsSync` | Синхронна перевірка існування `vitest.config.js`. |
|
|
83
|
-
| `node:fs/promises` | `readFile` | Асинхронне читання вмісту конфігу у utf-8. |
|
|
84
|
-
| `node:path` | `join` | Побудова шляху `${cwdParam}/vitest.config.js` крос-платформово. |
|
|
85
|
-
|
|
86
|
-
**Внутрішні модулі проєкту:**
|
|
87
|
-
|
|
88
|
-
| Шлях | Імпортовані символи | Використання |
|
|
89
|
-
| ----------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
90
|
-
| `../../../scripts/lib/check-reporter.mjs` | `createCheckReporter` | Фабрика репортера з методами `pass(msg)`, `fail(msg)` та `getExitCode()`. Уніфікує вивід для всіх `check-*.mjs` правил у репозиторії. |
|
|
91
|
-
|
|
92
|
-
**Зовнішніх npm-залежностей не має.**
|
|
93
|
-
|
|
94
|
-
## Потік виконання / Використання
|
|
95
|
-
|
|
96
|
-
### Типовий потік виконання `check()`
|
|
97
|
-
|
|
98
|
-
1. Створюється reporter: `const reporter = createCheckReporter()`.
|
|
99
|
-
2. Деструктуризація методів: `const { pass, fail } = reporter`.
|
|
100
|
-
3. Будується шлях до конфігу: `configPath = join(cwdParam, 'vitest.config.js')`.
|
|
101
|
-
4. Перевіряється існування файлу через `existsSync(configPath)`:
|
|
102
|
-
- Якщо файла **немає** — викликається `pass(...)` з повідомленням про skip, і функція негайно повертає `reporter.getExitCode()`.
|
|
103
|
-
5. Якщо файл є — він читається повністю: `body = await readFile(configPath, 'utf8')`.
|
|
104
|
-
6. Виконується `POOL_FORKS_RE.test(body)`:
|
|
105
|
-
- `true` → `pass(...)` з підтвердженням;
|
|
106
|
-
- `false` → `fail(...)` з поясненням і покликанням на `test.mdc`.
|
|
107
|
-
7. Повертається `reporter.getExitCode()` — `0` або `1` залежно від того, чи був хоч один `fail`.
|
|
108
|
-
|
|
109
|
-
### Використання як npm/CI-перевірки
|
|
110
|
-
|
|
111
|
-
Модуль слідує конвенції rule-checker'ів проєкту (правила в `npm/rules/<group>/<lang>/check-*.mjs` або тематичних файлах). Запускається або:
|
|
112
|
-
|
|
113
|
-
- безпосередньо `node` як CLI-входу (якщо обгорнуто скриптом-раннером);
|
|
114
|
-
- з агрегованого runner'а, який послідовно викликає `check()` для кожного правила і збирає exit-коди.
|
|
115
|
-
|
|
116
|
-
Приклад прямого виклику з іншого модуля:
|
|
117
|
-
|
|
118
|
-
```js
|
|
119
|
-
import { check } from './vitest-config-pool-forks.mjs'
|
|
120
|
-
|
|
121
|
-
const exitCode = await check(process.cwd())
|
|
122
|
-
process.exit(exitCode)
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Приклад виклику для нестандартного кореня (наприклад, у тесті):
|
|
126
|
-
|
|
127
|
-
```js
|
|
128
|
-
import { check } from './vitest-config-pool-forks.mjs'
|
|
129
|
-
|
|
130
|
-
const exitCode = await check('/tmp/fixture-repo-with-vitest')
|
|
131
|
-
// exitCode === 0 якщо у фікстурі є vitest.config.js з pool: 'forks',
|
|
132
|
-
// 1 якщо файл є без потрібного pool, 0 якщо файла нема взагалі
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Приклад валідного `vitest.config.js`
|
|
136
|
-
|
|
137
|
-
```js
|
|
138
|
-
import { defineConfig } from 'vitest/config'
|
|
139
|
-
|
|
140
|
-
export default defineConfig({
|
|
141
|
-
test: {
|
|
142
|
-
pool: 'forks'
|
|
143
|
-
// ... інші опції
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Приклад невалідного `vitest.config.js`
|
|
149
|
-
|
|
150
|
-
```js
|
|
151
|
-
import { defineConfig } from 'vitest/config'
|
|
12
|
+
Огляд
|
|
13
|
+
Файл виконує перевірку конфігураційного файлу для підтвердження наявності певного параметра. Це робиться для запобігання гонці у process.cwd між паралельними тестовими файлами (test.mdc).
|
|
152
14
|
|
|
153
|
-
|
|
154
|
-
test: {
|
|
155
|
-
// pool не вказано → effective pool: 'threads' (default vitest) → race на process.cwd()
|
|
156
|
-
}
|
|
157
|
-
})
|
|
158
|
-
```
|
|
15
|
+
## Поведінка
|
|
159
16
|
|
|
160
|
-
або
|
|
17
|
+
1. Знайти файл конфігурації з назвою vitest.config.mjs або vitest.config.js у вказаному шляху.
|
|
18
|
+
2. Якщо файл знайдено, прочитати його вміст.
|
|
19
|
+
3. Перевірити вміст файлу на наявність патерну pool: 'forks'.
|
|
20
|
+
4. Якщо патерн знайдено, повідомити про успішне виконання перевірки.
|
|
21
|
+
5. Якщо патерн відсутній, повідомити про невдачу, вказуючи, що конфігурація повинна містити pool: 'forks' для захисту від гонки у process.cwd між паралельними test files (test.mdc).
|
|
22
|
+
6. Якщо файл конфігурації не знайдено, повідомити, що перевірка пропущено.
|
|
161
23
|
|
|
162
|
-
|
|
163
|
-
export default {
|
|
164
|
-
test: { pool: 'threads' } // явно threads — те саме, що default
|
|
165
|
-
}
|
|
166
|
-
```
|
|
24
|
+
## Публічний API
|
|
167
25
|
|
|
168
|
-
|
|
26
|
+
check — перевіряє, чи налаштування `vitest.config.{mjs,js}` використовує `pool: 'forks'`. (test.mdc)
|
|
169
27
|
|
|
170
|
-
|
|
28
|
+
## Гарантії поведінки
|
|
171
29
|
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
- Skip при відсутності файлу — поведінка дизайну: правило не «обов'язково додай vitest», а «якщо ти вже маєш vitest, налаштуй pool правильно».
|
|
30
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
31
|
+
- Не звертається до мережі.
|
package/rules/text/docs/fix.md
CHANGED
|
@@ -1,127 +1,39 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/rules/text/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 та повертає результат. У режимі CLI виконується як автономний скрипт, який імітує команду `npx @nitra/cursor fix <id>`, завантажує конфігурацію, перевіряє дозволені записи, генерує зведену інформацію та визначає код виходу процесу.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. **Standalone mode** — якщо модуль виконується безпосередньо (`bun npm/rules/text/fix.mjs`), він самостійно піднімає повний CLI-оркестратор (`runRuleCli`) із завантаженням конфігурації, whitelist-фільтрацією та підсумковим виводом, повертаючи коректний `exit-code` для CI/IDE.
|
|
14
|
+
## Поведінка
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
1. Запуск правила.
|
|
17
|
+
* Приймає контекст прогону.
|
|
18
|
+
* Виконує застосування JS-занепокоєних.
|
|
19
|
+
* Застосовує політику.
|
|
20
|
+
* Генерує посилання MDC.
|
|
21
|
+
* Повертає результат прогону.
|
|
22
|
+
2. Виконання у режимі CLI.
|
|
23
|
+
* Виконується як автономний скрипт.
|
|
24
|
+
* Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
|
|
25
|
+
* Виконує завантаження конфігурації.
|
|
26
|
+
* Виконує перевірку дозволених записів.
|
|
27
|
+
* Генерує зведену інформацію.
|
|
28
|
+
* Визначає код виходу процесу.
|
|
17
29
|
|
|
18
|
-
|
|
30
|
+
## Публічний API
|
|
19
31
|
|
|
20
|
-
|
|
32
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
33
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
| ------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
-
| `run` | `function (ctx?: RuleContext): Promise<number>` | Іменований експорт для library mode. Викликається зовнішньою оркестрацією, повертає exit-code правила (`0` — OK, `1` — порушення). |
|
|
35
|
+
## Гарантії поведінки
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### `run(ctx)`
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
/**
|
|
34
|
-
*
|
|
35
|
-
*/
|
|
36
|
-
export function run(ctx) {
|
|
37
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
- **Сигнатура**: `function run(ctx?: RuleContext): Promise<number>`
|
|
42
|
-
- **Параметри**:
|
|
43
|
-
- `ctx` _(необов'язковий)_ — об'єкт контексту прогону типу `RuleContext`, описаний у JSDoc-import у `../../scripts/lib/run-standard-rule.mjs`. Передається оркестратором і зазвичай містить кешовані результати walk'у файлової системи (`walkCache`) та інші спільні для пакетного прогону структури, щоб уникнути повторного сканування репозиторію кожним правилом.
|
|
44
|
-
- **Повертає**: `Promise<number>` — exit-code, який повертає `runStandardRule`. За конвенцією репозиторію:
|
|
45
|
-
- `0` — порушень не знайдено (правило пройшло);
|
|
46
|
-
- `1` — знайдено хоча б одне порушення (правило впало).
|
|
47
|
-
- **Side effects**: усі побічні ефекти делеговані в `runStandardRule`. Це включає:
|
|
48
|
-
- читання файлів проєкту (без модифікацій);
|
|
49
|
-
- виконання сабмодулів `applies`, `JS-concerns`, `policy`, `mdc-refs` із сусідніх тек;
|
|
50
|
-
- друк діагностики у stdout/stderr (залежить від реалізації стандартного pipeline та `RuleContext`).
|
|
51
|
-
- **Передача `import.meta.dirname`**: ключова деталь — як перший аргумент передається **директорія цього файлу** (`npm/rules/text/`). Саме за нею `runStandardRule` ідентифікує правило (`id = basename(dirname)`) та знаходить його артефакти (mdc, applies, policy).
|
|
52
|
-
|
|
53
|
-
### Standalone-блок (top-level, не функція)
|
|
54
|
-
|
|
55
|
-
```js
|
|
56
|
-
if (isRunAsCli(import.meta.url)) {
|
|
57
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
- **Призначення**: дозволяє запускати модуль як автономний скрипт — `bun npm/rules/text/fix.mjs`. У такому режимі він має дати **повний еквівалент** виклику `npx @nitra/cursor fix text`, включно з:
|
|
62
|
-
- завантаженням конфігурації проєкту;
|
|
63
|
-
- застосуванням whitelist (відсіюванням файлів, що не підпадають під правило);
|
|
64
|
-
- друком підсумку (summary) виконання.
|
|
65
|
-
- **Параметри**: немає (CLI-аргументи парсяться всередині `runRuleCli`).
|
|
66
|
-
- **Повертає / завершує**: `process.exit(n)` із `n`, який повернув `runRuleCli`. Це необхідно, щоб CI або IDE-інтеграція могли визначати успіх/невдачу за стандартним exit-code'ом.
|
|
67
|
-
- **Side effects**:
|
|
68
|
-
- читання конфігурації пакета та проєкту;
|
|
69
|
-
- читання й аналіз файлів проєкту;
|
|
70
|
-
- вивід summary у stdout/stderr;
|
|
71
|
-
- **завершення процесу** через `process.exit` (це окремо помічено `eslint-disable` коментарем `n/no-process-exit, unicorn/no-process-exit`, оскільки правила лінтера за замовчуванням забороняють `process.exit` поза entry-point файлами).
|
|
72
|
-
- **Перевірка `isRunAsCli`**: функція приймає `import.meta.url` і повертає `true` лише якщо саме цей файл — entry-point Node/Bun-процесу. Це класичний ідіоматичний еквівалент `if __name__ == "__main__"` із Python для ESM.
|
|
73
|
-
|
|
74
|
-
## Залежності
|
|
75
|
-
|
|
76
|
-
### Внутрішні (relative)
|
|
77
|
-
|
|
78
|
-
| Імпорт | Модуль | Що дає |
|
|
79
|
-
| ----------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
-
| `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Предикат: чи запущений модуль як CLI entry-point (порівняння `import.meta.url` з `process.argv[1]`). |
|
|
81
|
-
| `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Повний CLI-оркестратор одного правила: завантаження конфігурації, whitelist, виклик `run`, друк summary, повернення exit-code. |
|
|
82
|
-
| `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Стандартний fix-pipeline правила: послідовно виконує етапи **applies → JS-concerns → policy → mdc-refs**. Знаходить артефакти за `dirname` правила. |
|
|
83
|
-
|
|
84
|
-
Усі три імпорти — це shared-утиліти рівня `scripts/lib/`, спроєктовані саме для подвійного entry-point'у правил. Жодних зовнішніх npm-залежностей файл не імпортує напряму.
|
|
85
|
-
|
|
86
|
-
### Неявні (контекст виконання)
|
|
87
|
-
|
|
88
|
-
- **`import.meta.dirname`** — стандартне поле ESM (Node ≥ 20 / Bun): абсолютний шлях до директорії, що містить модуль. Використовується **двічі** і є ключовим для ідентифікації правила.
|
|
89
|
-
- **`import.meta.url`** — стандартне поле ESM: URL-форма шляху до модуля; передається в `isRunAsCli` для порівняння з `process.argv[1]`.
|
|
90
|
-
- **`process.exit`** — глобальний Node/Bun API; викликається лише у standalone-режимі.
|
|
91
|
-
- **Сусідні теки правила** (`./lint`, `./policy`, `./js`, `./text.mdc`, `./meta.json`) — фактичні артефакти, які `runStandardRule` знаходить через переданий `import.meta.dirname`. Файл `fix.mjs` сам їх не імпортує, але pipeline без них не запрацює.
|
|
92
|
-
|
|
93
|
-
## Потік виконання / Використання
|
|
94
|
-
|
|
95
|
-
### Сценарій 1 — Library mode (typical)
|
|
96
|
-
|
|
97
|
-
1. Зовнішній код (наприклад, агрегатор `npx @nitra/cursor fix`) робить `await import('npm/rules/text/fix.mjs')`.
|
|
98
|
-
2. Перевірка `isRunAsCli(import.meta.url)` повертає `false` (бо entry-point процесу — інший файл), standalone-блок **не виконується**.
|
|
99
|
-
3. Агрегатор викликає експортовану `run(ctx)`, передаючи спільний `ctx` (наприклад, з прогрітим `walkCache`).
|
|
100
|
-
4. `run` делегує виклик у `runStandardRule(import.meta.dirname, ctx)`.
|
|
101
|
-
5. `runStandardRule` ідентифікує правило за `basename(dirname)` = `text`, послідовно виконує етапи pipeline (applies → JS-concerns → policy → mdc-refs), читає сусідні артефакти, повертає exit-code.
|
|
102
|
-
6. Агрегатор отримує `Promise<number>` і інтегрує його в загальний підсумок (наприклад, агрегує максимум по всіх правилах).
|
|
103
|
-
|
|
104
|
-
### Сценарій 2 — Standalone mode
|
|
105
|
-
|
|
106
|
-
1. Розробник або CI виконує `bun npm/rules/text/fix.mjs` (або через npm-script).
|
|
107
|
-
2. Імпорти `isRunAsCli`, `runRuleCli`, `runStandardRule` зчитуються.
|
|
108
|
-
3. Експорт `run` стає доступним, але **ніким не використовується** в цьому сценарії.
|
|
109
|
-
4. `isRunAsCli(import.meta.url)` повертає `true`.
|
|
110
|
-
5. Виконується `await runRuleCli(import.meta.dirname)` — повний CLI-цикл: парсинг аргументів, завантаження конфігурації, whitelist, виклик внутрішнього еквівалента `run`, друк summary.
|
|
111
|
-
6. Результат передається в `process.exit(...)` — процес завершується із належним exit-code'ом для CI.
|
|
112
|
-
|
|
113
|
-
### Чому саме така архітектура
|
|
114
|
-
|
|
115
|
-
- **Однаковий код для всіх правил** — `fix.mjs` кожного правила в `npm/rules/<id>/` ідентичний; диференціація — виключно через директорію (`import.meta.dirname`) та артефакти в ній. Це усуває дублювання логіки entry-point'у та робить додавання нового правила механічним (скопіювати теку, поправити mdc/policy).
|
|
116
|
-
- **Подвійна роль (library + standalone)** — дозволяє з одного файлу і дебажити правило локально (швидкий feedback `bun rules/text/fix.mjs`), і інтегрувати його у пакетний прогон агрегатора без зміни вихідного коду.
|
|
117
|
-
- **`process.exit` лише в standalone-гілці** — у library-режимі повернення exit-code'у через `Promise<number>` дає агрегатору можливість зібрати всі результати й завершитися одним викликом, не давши окремому правилу обірвати процес передчасно.
|
|
118
|
-
|
|
119
|
-
### Rebuild Test (інваріанти, які має зберегти будь-яка перебудова файлу)
|
|
120
|
-
|
|
121
|
-
- Файл **має експортувати** функцію `run(ctx)`, що повертає `Promise<number>`.
|
|
122
|
-
- `run` **має** передавати `import.meta.dirname` як перший аргумент у `runStandardRule` (без хардкоду шляху або `id`).
|
|
123
|
-
- `run` **не повинна** викликати `process.exit` — лише повертати exit-code.
|
|
124
|
-
- Standalone-гілка **має** бути захищена `isRunAsCli(import.meta.url)`, щоб не спрацьовувати при `import` із зовнішнього коду.
|
|
125
|
-
- Standalone-гілка **має** використовувати `runRuleCli` (а не `runStandardRule` напряму), бо саме `runRuleCli` додає config-loading, whitelist та summary.
|
|
126
|
-
- Standalone-гілка **має** завершуватися `process.exit(await runRuleCli(import.meta.dirname))` із поверненням коректного exit-code'у — інакше CI не зможе зловити порушення.
|
|
127
|
-
- Файл **не повинен** містити власної логіки правила: вся специфіка `text` живе в сусідніх теках (`lint/`, `policy/`, `js/`) та `text.mdc`.
|
|
37
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
38
|
+
- Кешує результати в межах одного прогону.
|
|
39
|
+
- Не звертається до мережі.
|