@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,122 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/text/js/lint.mjs
|
|
4
|
+
crc: 49aab7ce
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# lint.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Особливості модуля:
|
|
8
|
-
|
|
9
|
-
- Працює в режимі **whole-repo**: незалежно від того, які файли передає викликаюча сторона (наприклад, обгортка `lint-js` чи CI-оркестратор), аналіз виконується по всьому репозиторію цілком.
|
|
10
|
-
- Per-file режиму **немає**: вхідний параметр `files` навмисно ігнорується (підкреслено префіксом `_` у назві аргумента).
|
|
11
|
-
- Повертає числовий exit code (Promise), сумісний з конвенцією Unix-процесів: `0` — успіх, ненульовий — помилки лінту.
|
|
12
|
-
- Модуль не містить власної логіки перевірки тексту: вся реальна робота (запуск пов’язаних інструментів типу `dotenv-linter`, `shellcheck`, `v8r` тощо) — у `../lint/lint.mjs`.
|
|
13
|
-
|
|
14
|
-
Файл написаний у форматі **ES Modules** (`.mjs`) з JSDoc-анотаціями для статичної типізації без TypeScript-компіляції.
|
|
15
|
-
|
|
16
|
-
## Експорти / API
|
|
17
|
-
|
|
18
|
-
| Експорт | Тип | Призначення |
|
|
19
|
-
| ------- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
20
|
-
| `lint` | `async function (files?: string[]) => Promise<number>` | CI-крок-делегат у `runLintTextCli`. Іменований експорт (named export). |
|
|
21
|
-
|
|
22
|
-
Default-експорту немає. Сторонніх ефектів на рівні модуля (top-level side effects) також немає — лише імпорт залежності.
|
|
23
|
-
|
|
24
|
-
### Сигнатура
|
|
25
|
-
|
|
26
|
-
```js
|
|
27
|
-
export async function lint(_files): Promise<number>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### Контракт CI-кроку
|
|
31
|
-
|
|
32
|
-
Модуль реалізує загальний інтерфейс CI-крока правил n-cursor:
|
|
33
|
-
|
|
34
|
-
- Назва експорту: `lint`.
|
|
35
|
-
- Сигнатура приймає опціональний `files: string[] | undefined`.
|
|
36
|
-
- Повертає `Promise<number>` — exit code.
|
|
37
|
-
- Не кидає винятків у нормальному сценарії; помилки сигналізуються через ненульовий exit code, який повертає делегат `runLintTextCli`.
|
|
38
|
-
|
|
39
|
-
## Функції
|
|
40
|
-
|
|
41
|
-
### `lint(_files)`
|
|
42
|
-
|
|
43
|
-
**Сигнатура:** `async function lint(_files: string[] | undefined): Promise<number>`
|
|
44
|
-
|
|
45
|
-
**Параметри:**
|
|
46
|
-
|
|
47
|
-
| Ім’я | Тип | Опис |
|
|
48
|
-
| -------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
-
| `_files` | `string[] \| undefined` | Список файлів, які теоретично потрібно перевірити. **Ігнорується** — правило `text` працює у whole-repo режимі. Префікс `_` у назві аргументу — конвенція, що позначає невикористаний параметр (зокрема, щоб ESLint/lint-правила не лаялись на unused arg). |
|
|
50
|
-
|
|
51
|
-
**Повертає:** `Promise<number>` — exit code, отриманий від виклику `runLintTextCli()`. Зазвичай `0` означає, що всі перевірки пройшли успішно, а будь-яке інше число — що знайдено порушення або сталася помилка інструмента.
|
|
52
|
-
|
|
53
|
-
**Side effects:** Сам по собі `lint` додаткових ефектів не вносить. Усі побічні ефекти (запис у stdout/stderr, читання файлів, запуск зовнішніх процесів) виконуються всередині `runLintTextCli()`, на який делегується виклик.
|
|
54
|
-
|
|
55
|
-
**Поведінка:**
|
|
56
|
-
|
|
57
|
-
1. Викликає `runLintTextCli()` без аргументів.
|
|
58
|
-
2. Повертає результат як є (через `await` неявно через `return await`-форму — `async`-функція автоматично «розгортає» Promise з тіла).
|
|
59
|
-
|
|
60
|
-
Логіки трансформації параметрів, фільтрації, перевірки прапорців тощо — немає. Це навмисно мінімалістична функція-адаптер.
|
|
61
|
-
|
|
62
|
-
## Залежності
|
|
63
|
-
|
|
64
|
-
### Імпорти
|
|
65
|
-
|
|
66
|
-
| Що | Звідки | Призначення |
|
|
67
|
-
| ---------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
68
|
-
| `runLintTextCli` | `../lint/lint.mjs` | Запускає реальний CLI-обробник правила `text`. Саме він агрегує запуски під-інструментів (наприклад, `run-dotenv-linter.mjs`, `run-shellcheck.mjs`, `run-v8r.mjs`, які лежать у тій самій директорії `../lint/`). |
|
|
69
|
-
|
|
70
|
-
### Зовнішні (npm) залежності
|
|
71
|
-
|
|
72
|
-
Прямих імпортів з npm у файлі немає. Усі npm-залежності (якщо такі є) приховані у транзитивній залежності — `../lint/lint.mjs`.
|
|
73
|
-
|
|
74
|
-
### Структурний контекст
|
|
75
|
-
|
|
76
|
-
Файл лежить у `npm/rules/text/js/lint.mjs`. У тій самій директорії розташовані інші CI-крокові модулі правила `text` (наприклад, `formatting.mjs`, `forbidden-prettier.mjs`). Усі вони — однотипні делегати, що реалізують контракт CI-крока.
|
|
77
|
-
|
|
78
|
-
Бенефіціар:
|
|
79
|
-
|
|
80
|
-
- `../lint/lint.mjs` — справжній CLI правила `text`, що містить runner-логіку (parsing аргументів, оркестрація під-інструментів, формування звіту, exit code).
|
|
81
|
-
|
|
82
|
-
## Потік виконання / Використання
|
|
83
|
-
|
|
84
|
-
### Сценарій 1: виклик через CI-оркестратор правил
|
|
85
|
-
|
|
86
|
-
1. Оркестратор правил (наприклад, агрегований раннер у `lint-js` чи кореневий `bun run lint`) виявляє правило `text` і знаходить його CI-кроки в `npm/rules/text/js/*.mjs`.
|
|
87
|
-
2. Для кожного CI-крока (зокрема `lint.mjs`) оркестратор імпортує named export `lint`.
|
|
88
|
-
3. Викликає `await lint(filesArrayOrUndefined)`.
|
|
89
|
-
4. Адаптер ігнорує `files`, делегує виклик у `runLintTextCli()`.
|
|
90
|
-
5. Реальний CLI робить whole-repo аналіз: запускає `dotenv-linter`, `shellcheck`, `v8r` тощо (відповідно до того, що оголошено в `../lint/lint.mjs`).
|
|
91
|
-
6. Повертає exit code.
|
|
92
|
-
7. Оркестратор агрегує exit code-и всіх CI-кроків і приймає рішення про загальний успіх/невдачу.
|
|
93
|
-
|
|
94
|
-
### Сценарій 2: пряме виконання з коду
|
|
95
|
-
|
|
96
|
-
```js
|
|
97
|
-
import { lint } from 'npm/rules/text/js/lint.mjs'
|
|
98
|
-
|
|
99
|
-
const code = await lint()
|
|
100
|
-
process.exit(code)
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Передача аргументу `files` нічого не змінює (буде проігнорована):
|
|
104
|
-
|
|
105
|
-
```js
|
|
106
|
-
const code = await lint(['some/file.txt']) // _files ігнорується
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Чому per-file немає
|
|
110
|
-
|
|
111
|
-
Правило `text` за своєю природою сканує весь репозиторій (наприклад, перевіряє `.env`-файли, shell-скрипти, JSON Schema-файли через v8r). Для нього передача обмеженого списку файлів від CI не має сенсу — обробляти треба весь робочий простір. Звідси й whole-repo режим, явно зафіксований у JSDoc-коментарі та підкреслений підкресленням у назві параметра.
|
|
12
|
+
Файл надає функцію lint, яка делегує завдання CLI правилам. Функція не підтримує режим per-file, і параметр files ігнорується. Функція повертає Promise з кодом виходу.
|
|
112
13
|
|
|
113
|
-
|
|
14
|
+
## Поведінка
|
|
114
15
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
16
|
+
1. Викликається функція lint з аргументом files.
|
|
17
|
+
2. Функція lint делегує виконання у CLI правила.
|
|
18
|
+
3. Режим per-file не підтримується.
|
|
19
|
+
4. Параметр files ігнорується.
|
|
20
|
+
5. Функція повертає Promise з кодом виходу.
|
|
119
21
|
|
|
120
|
-
|
|
22
|
+
## Гарантії поведінки
|
|
121
23
|
|
|
122
|
-
|
|
24
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
25
|
+
- Не звертається до мережі.
|
package/rules/text/js/lint.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Крок text: делегує у наявний CLI правила (per-file режиму немає — `files` ігнорується).
|
|
3
3
|
*/
|
|
4
4
|
import { runLintTextCli } from '../lint/lint.mjs'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {string[] | undefined} _files ігнорується (whole-repo аналіз)
|
|
8
|
+
* @param {string} [_cwd] корінь (ігнорується — CLI працює від process.cwd())
|
|
9
|
+
* @param {{ readOnly?: boolean }} [opts] readOnly → детект без авто-фіксу (нуль мутацій)
|
|
8
10
|
* @returns {Promise<number>} exit code
|
|
9
11
|
*/
|
|
10
|
-
export function lint(_files) {
|
|
11
|
-
return runLintTextCli()
|
|
12
|
+
export function lint(_files, _cwd, opts = {}) {
|
|
13
|
+
return runLintTextCli({ readOnly: opts.readOnly === true })
|
|
12
14
|
}
|
package/rules/text/lint/lint.mjs
CHANGED
|
@@ -95,28 +95,30 @@ function preflight(dep) {
|
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* Внутрішні кроки `lint-text` без локу.
|
|
98
|
+
* @param {boolean} [readOnly] true → лише детект без авто-фіксу (нуль мутацій — CI/pre-commit)
|
|
98
99
|
* @returns {number} 0 — все OK, інакше — код першого кроку, що впав
|
|
99
100
|
*/
|
|
100
|
-
function runLintTextSteps() {
|
|
101
|
+
function runLintTextSteps(readOnly = false) {
|
|
101
102
|
// Auto-install: throws on failure → propagates as exit 1 from runStandardLint
|
|
102
103
|
ensureTool('shellcheck')
|
|
103
104
|
ensureTool('dotenv-linter')
|
|
104
105
|
|
|
105
|
-
// patch
|
|
106
|
-
if (!preflight(PATCH_PREFLIGHT)) return 1
|
|
106
|
+
// patch потрібен лише для авто-фіксу shellcheck; у read-only пропускаємо preflight.
|
|
107
|
+
if (!readOnly && !preflight(PATCH_PREFLIGHT)) return 1
|
|
107
108
|
|
|
108
109
|
const cspellCode = runLintStep('cspell', 'npx', ['cspell', '.'])
|
|
109
110
|
if (cspellCode !== 0) return cspellCode
|
|
110
111
|
|
|
111
|
-
console.log(
|
|
112
|
-
const shellcheckCode = runShellcheckText()
|
|
112
|
+
console.log(`\n▶ shellcheck (${readOnly ? 'перевірка' : 'авто-фікс + фінальна перевірка'} *.sh)`)
|
|
113
|
+
const shellcheckCode = runShellcheckText(process.cwd(), readOnly)
|
|
113
114
|
if (shellcheckCode !== 0) return shellcheckCode
|
|
114
115
|
|
|
115
|
-
console.log(
|
|
116
|
-
const dotenvCode = runDotenvLinter()
|
|
116
|
+
console.log(`\n▶ dotenv-linter (${readOnly ? 'перевірка' : 'авто-фікс + фінальна перевірка'} .env*)`)
|
|
117
|
+
const dotenvCode = runDotenvLinter(process.cwd(), readOnly)
|
|
117
118
|
if (dotenvCode !== 0) return dotenvCode
|
|
118
119
|
|
|
119
|
-
const
|
|
120
|
+
const mdArgs = readOnly ? ['markdownlint-cli2', '**/*.md', '**/*.mdc'] : ['markdownlint-cli2', '--fix', '**/*.md', '**/*.mdc']
|
|
121
|
+
const markdownlintCode = runLintStep('markdownlint', 'bunx', mdArgs)
|
|
120
122
|
if (markdownlintCode !== 0) return markdownlintCode
|
|
121
123
|
|
|
122
124
|
console.log('\n▶ v8r (schema-валідація json/json5/yaml/yml/toml)')
|
|
@@ -125,6 +127,8 @@ function runLintTextSteps() {
|
|
|
125
127
|
|
|
126
128
|
/**
|
|
127
129
|
* Публічна CLI-форма: серіалізує через `withLock('lint-text')` + дедуп за станом git-дерева.
|
|
130
|
+
* @param {{ readOnly?: boolean }} [opts] readOnly → детект без авто-фіксу
|
|
128
131
|
* @returns {Promise<number>} код виходу
|
|
129
132
|
*/
|
|
130
|
-
export const runLintTextCli = (
|
|
133
|
+
export const runLintTextCli = (opts = {}) =>
|
|
134
|
+
runStandardLint(import.meta.dirname, () => runLintTextSteps(opts.readOnly === true))
|
|
@@ -52,9 +52,10 @@ function buildExcludeArgs() {
|
|
|
52
52
|
/**
|
|
53
53
|
* Запускає dotenv-linter з авто-фіксом і фінальною перевіркою.
|
|
54
54
|
* @param {string} [cwd] робочий каталог (за замовчуванням `process.cwd()`)
|
|
55
|
+
* @param {boolean} [readOnly] true → пропустити авто-фікс (`fix`), лише `check` (нуль мутацій)
|
|
55
56
|
* @returns {number} 0 — OK; 1 — інструмент відсутній або є залишкові порушення
|
|
56
57
|
*/
|
|
57
|
-
export function runDotenvLinter(cwd = process.cwd()) {
|
|
58
|
+
export function runDotenvLinter(cwd = process.cwd(), readOnly = false) {
|
|
58
59
|
const root = resolve(cwd)
|
|
59
60
|
const bin = resolveCmd('dotenv-linter')
|
|
60
61
|
if (!bin) {
|
|
@@ -63,15 +64,17 @@ export function runDotenvLinter(cwd = process.cwd()) {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
const exclude = buildExcludeArgs()
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
if (!readOnly) {
|
|
68
|
+
const fixRun = spawnSync(bin, ['fix', '-r', '--no-backup', '--quiet', ...exclude, '.'], {
|
|
69
|
+
cwd: root,
|
|
70
|
+
encoding: 'utf8',
|
|
71
|
+
env: process.env,
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
73
|
+
})
|
|
74
|
+
if (fixRun.error) {
|
|
75
|
+
process.stderr.write(`${fixRun.error.message}\n`)
|
|
76
|
+
return 1
|
|
77
|
+
}
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
const checkRun = spawnSync(bin, ['check', '-r', '--quiet', ...exclude, '.'], {
|
|
@@ -96,17 +96,19 @@ export function listShellScriptPaths(cwd) {
|
|
|
96
96
|
/**
|
|
97
97
|
* Запускає shellcheck із авто-виправленнями і фінальною перевіркою.
|
|
98
98
|
* @param {string} [cwd] робочий каталог (за замовчуванням `process.cwd()`)
|
|
99
|
+
* @param {boolean} [readOnly] true → пропустити авто-фікс (diff+patch), лише фінальна перевірка
|
|
99
100
|
* @returns {number} 0 — OK; 1 — помилка середовища або залишкові зауваження shellcheck
|
|
100
101
|
*/
|
|
101
|
-
export function runShellcheckText(cwd = process.cwd()) {
|
|
102
|
+
export function runShellcheckText(cwd = process.cwd(), readOnly = false) {
|
|
102
103
|
const root = resolve(cwd)
|
|
103
104
|
const shellcheck = resolveCmd('shellcheck')
|
|
104
105
|
if (!shellcheck) {
|
|
105
106
|
printShellcheckInstallHints()
|
|
106
107
|
return 1
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
// patch потрібен лише для авто-фіксу (diff+patch); у read-only його відсутність не блокує детект.
|
|
110
|
+
const patchBin = readOnly ? null : resolveCmd('patch')
|
|
111
|
+
if (!readOnly && !patchBin) {
|
|
110
112
|
printPatchInstallHints()
|
|
111
113
|
return 1
|
|
112
114
|
}
|
|
@@ -116,9 +118,11 @@ export function runShellcheckText(cwd = process.cwd()) {
|
|
|
116
118
|
return 0
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
if (!readOnly) {
|
|
122
|
+
for (const rel of files) {
|
|
123
|
+
const fixCode = autofixOneFile(shellcheck, /** @type {string} */ (patchBin), root, rel)
|
|
124
|
+
if (fixCode !== 0) return fixCode
|
|
125
|
+
}
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
return runFinalShellcheck(shellcheck, files, root)
|
package/rules/text/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "auto": "завжди", "lint": "
|
|
1
|
+
{ "auto": "завжди", "lint": "per-file" }
|
package/rules/vue/docs/fix.md
CHANGED
|
@@ -1,127 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/vue/fix.mjs
|
|
4
|
+
crc: 38cf876b
|
|
5
|
+
score: 90
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Файл `npm/rules/vue/fix.mjs` — це **точка входу** (entry-point) для правила `vue` у системі `@nitra/cursor`. Файл одночасно виконує дві ролі:
|
|
6
|
-
|
|
7
|
-
1. **Library mode** — експортує функцію `run(ctx)`, яку викликає зовнішній оркестратор (CLI `@nitra/cursor`, інші правила, тести) з підготовленим контекстом прогону.
|
|
8
|
-
2. **Standalone mode** — якщо файл запущено напряму (наприклад, `bun npm/rules/vue/fix.mjs`), він самостійно піднімає повноцінний CLI-цикл, еквівалентний `npx @nitra/cursor fix vue`.
|
|
9
|
-
|
|
10
|
-
Сам файл не містить специфічної для Vue логіки правил. Уся логіка делегується у спільні бібліотеки `runStandardRule` (виконання стандартних фаз правила) і `runRuleCli` (підготовка CLI-середовища). Завдяки цьому `fix.mjs` у директорії правила `vue` залишається тонким shim-файлом, який лише підставляє свою директорію як ідентифікатор правила.
|
|
11
|
-
|
|
12
|
-
Стандартний пайплайн, який під цим запускається (через `runStandardRule`), складається з фаз:
|
|
13
|
-
|
|
14
|
-
- `applies` — детекція файлів/області застосування правила,
|
|
15
|
-
- `JS-concerns` — перевірки JS/JSX/TS-аспектів коду,
|
|
16
|
-
- `policy` — застосування policy-чеків (warn/error),
|
|
17
|
-
- `mdc-refs` — узгодженість MDC-документації та посилань.
|
|
18
|
-
|
|
19
|
-
## Експорти / API
|
|
20
|
-
|
|
21
|
-
| Назва | Тип | Опис |
|
|
22
|
-
| ----- | ---------- | ----------------------------------------------------------------------------------------------- |
|
|
23
|
-
| `run` | `function` | Named export. Library-точка входу правила. Приймає опційний `ctx` і повертає `Promise<number>`. |
|
|
24
|
-
|
|
25
|
-
**Side-effect експорт:** при виконанні модуля під CLI (умова `isRunAsCli(import.meta.url)`) модуль вмикає standalone-режим і завершує процес викликом `process.exit(...)` з exit-кодом, отриманим від `runRuleCli`. Цей побічний ефект виконується на верхньому рівні модуля (top-level `await`), тому імпорт файлу як ESM-модуля з іншого файлу **не** активує standalone-гілку — її активує лише пряме виконання інтерпретатором.
|
|
26
|
-
|
|
27
|
-
## Функції
|
|
28
|
-
|
|
29
|
-
### `run(ctx)`
|
|
30
|
-
|
|
31
|
-
Library-функція правила. Делегує виконання у спільну реалізацію `runStandardRule`, передаючи їй власну директорію модуля (`import.meta.dirname`) як ідентифікатор правила та переданий контекст.
|
|
32
|
-
|
|
33
|
-
- **Сигнатура:** `function run(ctx): Promise<number>`
|
|
34
|
-
- **Параметри:**
|
|
35
|
-
- `ctx` _(optional)_ — об'єкт типу `RuleContext` із модуля `../../scripts/lib/run-standard-rule.mjs`. У ньому, серед іншого, передається `walkCache` для уникнення повторного обходу файлової системи між послідовно запущеними правилами. Якщо `ctx` не передано, `runStandardRule` створює його самостійно.
|
|
36
|
-
- **Повертає:** `Promise<number>` — exit-код прогону правила:
|
|
37
|
-
- `0` — порушень немає (OK);
|
|
38
|
-
- `1` — знайдено порушення (rule violations).
|
|
39
|
-
- **Side effects:** усі побічні ефекти ховаються всередині `runStandardRule` (читання файлів проєкту, можливі автоматичні фікси, виведення summary в stdout/stderr). Сам `run` додаткових side-effects не має, поза тим, що значення повернення завжди є `Promise`, навіть якщо `runStandardRule` поверне синхронно — це гарантує контракт async-pipeline для оркестратора.
|
|
40
|
-
- **Помилки:** функція не обгортає виняткові ситуації — будь-яка помилка з `runStandardRule` пробрасується нагору (rejection промісу) і має оброблятись на рівні CLI/орхестратора.
|
|
41
|
-
|
|
42
|
-
### Top-level standalone-блок
|
|
43
|
-
|
|
44
|
-
Не функція, а top-level гілка модуля:
|
|
45
|
-
|
|
46
|
-
```js
|
|
47
|
-
if (isRunAsCli(import.meta.url)) {
|
|
48
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
49
|
-
}
|
|
50
|
-
```
|
|
8
|
+
# fix.mjs
|
|
51
9
|
|
|
52
|
-
|
|
53
|
-
- **Side effects:**
|
|
54
|
-
- синхронне завершення процесу через `process.exit`;
|
|
55
|
-
- усе, що робить `runRuleCli` (завантаження конфігу, whitelist, summary).
|
|
56
|
-
- **ESLint-винятки:** standalone-entry-point має право робити `process.exit`, тому над цим викликом стоять директиви `// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit`. Це штатна практика для двороле́вих fix.mjs.
|
|
57
|
-
|
|
58
|
-
## Залежності
|
|
59
|
-
|
|
60
|
-
Імпорти модуля:
|
|
61
|
-
|
|
62
|
-
- `isRunAsCli` — з `../../scripts/lib/run-rule-cli.mjs`. Утиліта-детектор: чи поточний модуль є entry-point (CLI mode), чи його імпортнули як бібліотеку.
|
|
63
|
-
- `runRuleCli` — з `../../scripts/lib/run-rule-cli.mjs`. Виконує повну CLI-оркестрацію для одного правила: завантажує конфіг, формує whitelist, друкує summary та повертає exit-код. Використовується тільки у standalone-гілці.
|
|
64
|
-
- `runStandardRule` — з `../../scripts/lib/run-standard-rule.mjs`. Виконує стандартний пайплайн правила: `applies → JS-concerns → policy → mdc-refs`. JSDoc-типи `RuleContext` теж приходять із цього модуля (через `@param`-import).
|
|
65
|
-
|
|
66
|
-
Неявні залежності:
|
|
67
|
-
|
|
68
|
-
- Структура директорії правила (`npm/rules/vue/`) має містити очікувані `runStandardRule` під-директорії/файли: `js/`, `lib/`, `policy/`, `meta.json`, `vue.mdc` тощо. Сам `fix.mjs` не звертається до них напряму — він лише підставляє свій `import.meta.dirname`, а решту виявляє shared-runner.
|
|
69
|
-
- ESM-середовище (Node.js ≥ 20 / Bun) з підтримкою `import.meta.url` та `import.meta.dirname`.
|
|
70
|
-
|
|
71
|
-
## Потік виконання / Використання
|
|
72
|
-
|
|
73
|
-
### Library mode (виклик з оркестратора)
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
import { run } from './npm/rules/vue/fix.mjs'
|
|
77
|
-
|
|
78
|
-
const exitCode = await run(ctx) // ctx — спільний RuleContext із walkCache
|
|
79
|
-
if (exitCode !== 0) {
|
|
80
|
-
// у правилі vue знайдено порушення → обробляємо
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Послідовність:
|
|
85
|
-
|
|
86
|
-
1. Оркестратор імпортує `fix.mjs`. Гілка `if (isRunAsCli(...))` не виконується, бо `import.meta.url` не є entry-point.
|
|
87
|
-
2. Оркестратор викликає `run(ctx)`.
|
|
88
|
-
3. `run` передає `import.meta.dirname` (= `…/npm/rules/vue`) і `ctx` у `runStandardRule`.
|
|
89
|
-
4. `runStandardRule` виконує фази `applies → JS-concerns → policy → mdc-refs` для правила `vue`, використовуючи кеші з `ctx` (наприклад, `walkCache`).
|
|
90
|
-
5. Повертається exit-код (`0` або `1`), який оркестратор інтегрує у свій агрегований підсумок.
|
|
91
|
-
|
|
92
|
-
### Standalone mode (пряме виконання)
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
bun npm/rules/vue/fix.mjs
|
|
96
|
-
# або
|
|
97
|
-
node npm/rules/vue/fix.mjs
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Послідовність:
|
|
101
|
-
|
|
102
|
-
1. Інтерпретатор завантажує модуль; виконуються імпорти.
|
|
103
|
-
2. Виконується top-level код: `isRunAsCli(import.meta.url)` повертає `true`.
|
|
104
|
-
3. Викликається `await runRuleCli(import.meta.dirname)` — це повний еквівалент `npx @nitra/cursor fix vue`:
|
|
105
|
-
- читає конфіг,
|
|
106
|
-
- застосовує whitelist,
|
|
107
|
-
- усередині піднімає той самий `runStandardRule`-цикл (або сумісний з ним),
|
|
108
|
-
- друкує summary.
|
|
109
|
-
4. Отриманий exit-код передається у `process.exit(...)`, процес завершується з відповідним кодом для CI/IDE.
|
|
10
|
+
## Огляд
|
|
110
11
|
|
|
111
|
-
|
|
12
|
+
Файл застосовує правило `runStandardRule` до наданого контексту прогону через функцію `runStandardRule` і повертає отриманий результат. У режимі CLI він виконує команду `npx @nitra/cursor fix <id>` та визначає вихідний код процесу на основі отриманого результату.
|
|
112
13
|
|
|
113
|
-
|
|
14
|
+
## Поведінка
|
|
114
15
|
|
|
115
|
-
|
|
116
|
-
|
|
16
|
+
1. Запуск правила.
|
|
17
|
+
* Приймає контекст прогону.
|
|
18
|
+
* Використовує runStandardRule для застосування політики.
|
|
19
|
+
* Повертає результат прогону.
|
|
20
|
+
2. Запуск у режимі CLI.
|
|
21
|
+
* Викликається через `import + run`.
|
|
22
|
+
* Виконує повний еквівалент `npx @nitra/cursor fix <id>`.
|
|
23
|
+
* Визначає вихідний код процесу на основі результату.
|
|
117
24
|
|
|
118
|
-
##
|
|
25
|
+
## Публічний API
|
|
119
26
|
|
|
120
|
-
|
|
27
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
28
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
121
29
|
|
|
122
|
-
|
|
123
|
-
- Експортується одна named-функція `run(ctx)`, яка повертає результат `runStandardRule(import.meta.dirname, ctx)` — отже, є async (повертає `Promise<number>`).
|
|
124
|
-
- На рівні модуля стоїть умова `if (isRunAsCli(import.meta.url)) { process.exit(await runRuleCli(import.meta.dirname)) }` з відповідними ESLint-disable-коментарями для `n/no-process-exit` та `unicorn/no-process-exit`.
|
|
125
|
-
- Жодних додаткових іменованих експортів, default-експортів, констант чи побічних викликів у файлі немає.
|
|
30
|
+
## Гарантії поведінки
|
|
126
31
|
|
|
127
|
-
|
|
32
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
33
|
+
- Кешує результати в межах одного прогону.
|
|
34
|
+
- Не звертається до мережі.
|