@nitra/cursor 12.8.3 → 12.8.4
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/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/rules/js/docs/index.md +3 -3
- package/rules/js/docs/main.md +6 -6
- package/rules/js/js/docs/check.md +12 -17
- package/rules/js/js/docs/index.md +4 -4
- package/rules/js/js/docs/tooling.md +8 -8
- package/rules/js/js/docs/utils_imports.md +21 -200
- package/rules/npm-module/js/docs/index.md +5 -5
- package/rules/npm-module/js/docs/rule_meta.md +13 -13
- package/rules/npm-module/js/docs/skill_meta.md +19 -9
- package/rules/npm-module/js/rule_meta.mjs +9 -9
- package/rules/npm-module/js/skill_meta.mjs +6 -6
- package/rules/test/js/docs/index.md +7 -7
- package/rules/test/js/docs/stryker_config.md +18 -35
- package/rules/test/js/docs/vitest-config-pool-forks.md +14 -12
- package/schemas/v8r-catalog.json +4 -4
- package/scripts/docs/index.md +16 -16
- package/scripts/docs/sync-setup-bun-deps-action.md +13 -14
- package/scripts/lib/check-mdc-template-refs.mjs +2 -2
- package/scripts/lib/docs/check-mdc-template-refs.md +12 -214
- package/scripts/lib/docs/index.md +36 -36
- package/scripts/lib/docs/mirror-parity.md +18 -157
- package/scripts/lib/docs/rule-meta.md +19 -22
- package/scripts/lib/docs/run-rule.md +11 -11
- package/scripts/lib/docs/skill-meta.md +17 -19
- package/scripts/lib/docs/timing-summary.md +6 -6
- package/scripts/lib/mirror-parity.mjs +1 -1
- package/scripts/lib/rule-meta.mjs +1 -1
- package/scripts/lib/run-rule.mjs +4 -4
- package/scripts/lib/skill-meta.mjs +1 -1
- package/scripts/utils/docs/index.md +14 -14
- package/scripts/utils/docs/resolve-js-root.md +12 -13
- /package/rules/abie/{meta.json → main.json} +0 -0
- /package/rules/abie/{abie.mdc → main.mdc} +0 -0
- /package/rules/adr/{meta.json → main.json} +0 -0
- /package/rules/adr/{adr.mdc → main.mdc} +0 -0
- /package/rules/bun/{meta.json → main.json} +0 -0
- /package/rules/bun/{bun.mdc → main.mdc} +0 -0
- /package/rules/capacitor/{meta.json → main.json} +0 -0
- /package/rules/capacitor/{capacitor.mdc → main.mdc} +0 -0
- /package/rules/changelog/{meta.json → main.json} +0 -0
- /package/rules/changelog/{changelog.mdc → main.mdc} +0 -0
- /package/rules/ci4/{meta.json → main.json} +0 -0
- /package/rules/ci4/{ci4.mdc → main.mdc} +0 -0
- /package/rules/doc-files/{meta.json → main.json} +0 -0
- /package/rules/doc-files/{doc-files.mdc → main.mdc} +0 -0
- /package/rules/docker/{meta.json → main.json} +0 -0
- /package/rules/docker/{docker.mdc → main.mdc} +0 -0
- /package/rules/efes/{meta.json → main.json} +0 -0
- /package/rules/efes/{efes.mdc → main.mdc} +0 -0
- /package/rules/feedback/{meta.json → main.json} +0 -0
- /package/rules/feedback/{feedback.mdc → main.mdc} +0 -0
- /package/rules/ga/{meta.json → main.json} +0 -0
- /package/rules/ga/{ga.mdc → main.mdc} +0 -0
- /package/rules/graphql/{meta.json → main.json} +0 -0
- /package/rules/graphql/{graphql.mdc → main.mdc} +0 -0
- /package/rules/hasura/{meta.json → main.json} +0 -0
- /package/rules/hasura/{hasura.mdc → main.mdc} +0 -0
- /package/rules/image-avif/{meta.json → main.json} +0 -0
- /package/rules/image-avif/{image-avif.mdc → main.mdc} +0 -0
- /package/rules/image-compress/{meta.json → main.json} +0 -0
- /package/rules/image-compress/{image-compress.mdc → main.mdc} +0 -0
- /package/rules/js/{meta.json → main.json} +0 -0
- /package/rules/js/{js.mdc → main.mdc} +0 -0
- /package/rules/js-bun-db/{meta.json → main.json} +0 -0
- /package/rules/js-bun-db/{js-bun-db.mdc → main.mdc} +0 -0
- /package/rules/js-bun-redis/{meta.json → main.json} +0 -0
- /package/rules/js-bun-redis/{js-bun-redis.mdc → main.mdc} +0 -0
- /package/rules/js-mssql/{meta.json → main.json} +0 -0
- /package/rules/js-mssql/{js-mssql.mdc → main.mdc} +0 -0
- /package/rules/js-run/{meta.json → main.json} +0 -0
- /package/rules/js-run/{js-run.mdc → main.mdc} +0 -0
- /package/rules/k8s/{meta.json → main.json} +0 -0
- /package/rules/k8s/{k8s.mdc → main.mdc} +0 -0
- /package/rules/nginx-default-tpl/{meta.json → main.json} +0 -0
- /package/rules/nginx-default-tpl/{nginx-default-tpl.mdc → main.mdc} +0 -0
- /package/rules/npm-module/{meta.json → main.json} +0 -0
- /package/rules/npm-module/{npm-module.mdc → main.mdc} +0 -0
- /package/rules/php/{meta.json → main.json} +0 -0
- /package/rules/php/{php.mdc → main.mdc} +0 -0
- /package/rules/python/{meta.json → main.json} +0 -0
- /package/rules/python/{python.mdc → main.mdc} +0 -0
- /package/rules/rego/{meta.json → main.json} +0 -0
- /package/rules/rego/{rego.mdc → main.mdc} +0 -0
- /package/rules/release/{meta.json → main.json} +0 -0
- /package/rules/release/{release.mdc → main.mdc} +0 -0
- /package/rules/rust/{meta.json → main.json} +0 -0
- /package/rules/rust/{rust.mdc → main.mdc} +0 -0
- /package/rules/security/{meta.json → main.json} +0 -0
- /package/rules/security/{security.mdc → main.mdc} +0 -0
- /package/rules/style/{meta.json → main.json} +0 -0
- /package/rules/style/{style.mdc → main.mdc} +0 -0
- /package/rules/tauri/{meta.json → main.json} +0 -0
- /package/rules/tauri/{tauri.mdc → main.mdc} +0 -0
- /package/rules/test/{meta.json → main.json} +0 -0
- /package/rules/test/{test.mdc → main.mdc} +0 -0
- /package/rules/text/{meta.json → main.json} +0 -0
- /package/rules/text/{text.mdc → main.mdc} +0 -0
- /package/rules/tool-surface/{meta.json → main.json} +0 -0
- /package/rules/tool-surface/{tool-surface.mdc → main.mdc} +0 -0
- /package/rules/vue/{meta.json → main.json} +0 -0
- /package/rules/vue/{vue.mdc → main.mdc} +0 -0
- /package/rules/worktree/{meta.json → main.json} +0 -0
- /package/rules/worktree/{worktree.mdc → main.mdc} +0 -0
- /package/skills/adr-normalize/{meta.json → main.json} +0 -0
- /package/skills/coverage-fix/{meta.json → main.json} +0 -0
- /package/skills/doc-aggregate/{meta.json → main.json} +0 -0
- /package/skills/doc-files/{meta.json → main.json} +0 -0
- /package/skills/lint/{meta.json → main.json} +0 -0
- /package/skills/llm-patch/{meta.json → main.json} +0 -0
- /package/skills/publish-telegram/{meta.json → main.json} +0 -0
- /package/skills/start-check/{meta.json → main.json} +0 -0
- /package/skills/taze/{meta.json → main.json} +0 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/rules/js/docs/index.md
CHANGED
package/rules/js/docs/main.md
CHANGED
|
@@ -3,26 +3,26 @@ type: JS Module
|
|
|
3
3
|
title: main.mjs
|
|
4
4
|
resource: npm/rules/js/main.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 00294e8e
|
|
7
7
|
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
8
|
score: 100
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## Огляд
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Дозволяє запускати повний аналіз проєкту за допомогою `run`, виконувати лінтинг за допомогою `lint` або фільтрувати файли з розширенням JavaScript за допомогою `filterJsFiles`.
|
|
14
14
|
|
|
15
15
|
## Поведінка
|
|
16
16
|
|
|
17
17
|
run виконує стандартну перевірку проєкту.
|
|
18
18
|
filterJsFiles відбирає з наданого списку лише файли, що мають розширення, характерне для JavaScript.
|
|
19
|
-
lint запускає
|
|
19
|
+
lint запускає перевірку проєкту: або повний аналіз усіх файлів, або класифікований аналіз лише змінених файлів.
|
|
20
20
|
|
|
21
21
|
## Публічний API
|
|
22
22
|
|
|
23
|
-
run —
|
|
24
|
-
filterJsFiles — відбирає лише
|
|
25
|
-
lint —
|
|
23
|
+
run — виконує повний цикл перевірки: аналіз конфігурації, перевірку логіки та посилання на метадані.
|
|
24
|
+
filterJsFiles — відбирає лише файли з розширенням JavaScript.
|
|
25
|
+
lint — запускає інструменти для форматування та стилізації коду (oxlint, eslint, jscpd, knip).
|
|
26
26
|
|
|
27
27
|
## Гарантії поведінки
|
|
28
28
|
|
|
@@ -3,34 +3,29 @@ type: JS Module
|
|
|
3
3
|
title: check.mjs
|
|
4
4
|
resource: npm/rules/js/js/check.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 7ad4aa59
|
|
7
7
|
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
-
score:
|
|
8
|
+
score: 90
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## Огляд
|
|
12
12
|
|
|
13
|
-
Модуль
|
|
13
|
+
Модуль перевіряє відповідність структури та конфігураційних файлів проєкту встановленим стандартам. Він валідує файли, такі як `package.json`, `.oxlintrc.json`, `.eslintrc.json` та файли робочих процесів GitHub, відповідно до вимог (js.mdc). Перевірка свідомо ігнорує шляхи `.github` та `.git`. Модуль забезпечує перехоплення помилок (fail-safe) під час виконання перевірок.
|
|
14
14
|
|
|
15
15
|
## Поведінка
|
|
16
16
|
|
|
17
|
-
1.
|
|
18
|
-
2.
|
|
19
|
-
3.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
а. Перевіряє наявність `lint-js.yml`.
|
|
26
|
-
б. Перевіряє, чи не дублює `lint.yml` кроки лінтінгу JS.
|
|
27
|
-
6. Перевіряє наявність файлу `knip.json` у корені проєкту. Якщо він відсутній, копіює канонічний шаблон.
|
|
28
|
-
7. Перевіряє наявність застарілих конфігурацій ESLint (`.eslintrc`, `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`) та повідомляє про їхнє існування.
|
|
29
|
-
8. Повертає код виходу, що відображає загальний статус перевірки.
|
|
17
|
+
1. Викликати `check` для запуску перевірок конфігурації проєкту.
|
|
18
|
+
2. Перевірити наявність конфігурацій ESLint (flat config) та валідувати їх вміст відповідно до вимог (js.mdc).
|
|
19
|
+
3. Перевірити `package.json` у корені та у всіх пакетах workspace на відповідність вимогам: наявність `"type": "module"` та мінімальні версії `engines.node` (>=24) та `engines.bun` (>=1.3) (js.mdc).
|
|
20
|
+
4. Перевірити конфігураційний файл `.oxlintrc.json` на відповідність канонічному шаблону (js.mdc).
|
|
21
|
+
5. Перевірити файли робочих процесів (`.github/workflows/lint-js.yml` та `.github/workflows/lint.yml`) на відповідність політикам лінтингу (js.mdc).
|
|
22
|
+
6. Перевірити наявність конфігурацій Knip (`knip.json`). Якщо відсутній, створити його, скопіювавши канонічний шаблон (js.mdc).
|
|
23
|
+
7. Перевірити наявність застарілих конфігурацій ESLint (наприклад, `.eslintrc.*`) та повідомити про їхнє використання.
|
|
24
|
+
8. Ігнорувати перевірки у каталогах `.github` та `.git`.
|
|
30
25
|
|
|
31
26
|
## Публічний API
|
|
32
27
|
|
|
33
|
-
check —
|
|
28
|
+
check — перевіряє відповідність проєкту стандартам js.mdc
|
|
34
29
|
|
|
35
30
|
## Гарантії поведінки
|
|
36
31
|
|
|
@@ -6,9 +6,9 @@ resource: npm/rules/js/js/
|
|
|
6
6
|
|
|
7
7
|
# npm/rules/js/js
|
|
8
8
|
|
|
9
|
-
| Файл
|
|
10
|
-
|
|
11
|
-
| [check.mjs](check.md)
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
|---|---|
|
|
11
|
+
| [check.mjs](check.md) | JS Module |
|
|
12
12
|
| [lint-findings.mjs](lint-findings.md) | JS Module |
|
|
13
|
-
| [tooling.mjs](tooling.md)
|
|
13
|
+
| [tooling.mjs](tooling.md) | JS Module |
|
|
14
14
|
| [utils_imports.mjs](utils_imports.md) | JS Module |
|
|
@@ -3,26 +3,26 @@ type: JS Module
|
|
|
3
3
|
title: tooling.mjs
|
|
4
4
|
resource: npm/rules/js/js/tooling.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 101a5230
|
|
7
7
|
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
8
|
score: 95
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## Огляд
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Модуль визначає шляхи до канонічних JSON-файлів для інструментів oxlint та knip через функції OXLINT_CANONICAL_JSON_PATH та KNIP_CANONICAL_JSON_PATH. Він також надає функцію verifyOxlintRcAgainstCanonical для валідації конфігурацій, перевіряючи, чи відповідає `.oxlintrc.json` правилам, визначеним у oxlint-canonical.json.
|
|
14
14
|
|
|
15
15
|
## Поведінка
|
|
16
16
|
|
|
17
|
-
OXLINT_CANONICAL_JSON_PATH — Вказує шлях до канонічного JSON-файлу oxlint у цьому пакеті.
|
|
18
|
-
KNIP_CANONICAL_JSON_PATH — Вказує шлях до канонічного JSON-файлу knip у цьому пакеті.
|
|
19
|
-
verifyOxlintRcAgainstCanonical — Перевіряє
|
|
17
|
+
OXLINT_CANONICAL_JSON_PATH — Вказує на шлях до канонічного JSON-файлу для oxlint у цьому пакеті.
|
|
18
|
+
KNIP_CANONICAL_JSON_PATH — Вказує на шлях до канонічного JSON-файлу для knip у цьому пакеті.
|
|
19
|
+
verifyOxlintRcAgainstCanonical — Перевіряє конфігурацію `.oxlintrc.json` на відповідність канонічному файлу oxlint-canonical.json, виявляючи відхилення у правилах та інших полях.
|
|
20
20
|
|
|
21
21
|
## Публічний API
|
|
22
22
|
|
|
23
|
-
OXLINT_CANONICAL_JSON_PATH —
|
|
24
|
-
KNIP_CANONICAL_JSON_PATH —
|
|
25
|
-
verifyOxlintRcAgainstCanonical —
|
|
23
|
+
OXLINT_CANONICAL_JSON_PATH — вказує на файл з еталонними налаштуваннями oxlint у пакеті.
|
|
24
|
+
KNIP_CANONICAL_JSON_PATH — вказує на файл з еталонними налаштуваннями knip, який копіюється у корінь проєкту, якщо його там немає.
|
|
25
|
+
verifyOxlintRcAgainstCanonical — порівнює конфігураційний файл `.oxlintrc.json` з еталоном, перевіряючи, чи всі правила з еталону присутні, а інші поля збігаються з `oxlint-canonical.json`.
|
|
26
26
|
|
|
27
27
|
## Гарантії поведінки
|
|
28
28
|
|
|
@@ -3,210 +3,31 @@ type: JS Module
|
|
|
3
3
|
title: utils_imports.mjs
|
|
4
4
|
resource: npm/rules/js/js/utils_imports.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 3fc9bf1b
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Модуль сканує файли у монорепозиторії. Він зчитує вміст JavaScript/TypeScript файлів та витягує всі рядкові імпорти. На основі конфігурації `.n-cursor.json` він перевіряє, чи не містять імпорти заборонених відносних шляхів, реєструючи відповідний статус у логіці (js.mdc). Публічна функція `check` виконує цю перевірку, свідомо пропускаючи шляхи `.git` та `node_modules`.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- Якщо файлу треба сусідній модуль (наприклад, `lib/foo.mjs` чи cross-rule helper) — він мусить переїхати у `lib/`, а не отримувати доступ через `../lib/foo.mjs`.
|
|
15
|
-
- Дозволені імпорт-джерела: `./X`, `./sub/X` (свій каталог чи глибше), bare-package (`oxc-parser`, `@scope/pkg`), Node-builtin (`node:fs`, `fs`).
|
|
16
|
-
- Заборонено будь-який `..`-шлях (`../X`, `../../X`, ...).
|
|
15
|
+
## Поведінка
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
1. Визначає корінь проекту.
|
|
18
|
+
2. Зчитує список шляхів, які слід ігнорувати, на основі конфігурації .n-cursor.json.
|
|
19
|
+
3. Визначає кореневі каталоги пакетів у монорепозиторії.
|
|
20
|
+
4. Для кожного кореневого каталогу пакета рекурсивно шукає каталоги з назвою `utils`, ігноруючи типові артефакти (наприклад, node_modules, .git, dist).
|
|
21
|
+
5. Якщо знайдено каталоги `utils`, для кожного з них рекурсивно збирає всі файли з розширеннями `.js`, `.jsx`, `.ts`, `.tsx`, які не є тестовими.
|
|
22
|
+
6. Для кожного зібраного файлу зчитує його вміст.
|
|
23
|
+
7. Витягує з вмісту файлу всі рядкові імпорти (статичні, динамічні та виклики `require`).
|
|
24
|
+
8. Для кожного витягнутого імпорту перевіряє, чи відповідає він шаблону забороненого відносного шляху, що вказує на імпорт з іншого каталогу, який не є загальним.
|
|
25
|
+
9. Якщо заборонений імпорт знайдено, реєструє помилку, посилаючись на файл та заборонений імпорт (js.mdc).
|
|
26
|
+
10. Якщо жодних порушень не знайдено, реєструє успіх (js.mdc).
|
|
27
|
+
11. Повертає код виходу, що відображає статус перевірки.
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
## Гарантії поведінки
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
| ------- | ----------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
26
|
-
| `check` | `() => Promise<number>` | named export; запускає перевірку від `process.cwd()` і повертає `0` (OK) або `1` (знайдено порушення) |
|
|
27
|
-
|
|
28
|
-
Усе інше — приватні helpers модуля без `export`.
|
|
29
|
-
|
|
30
|
-
## Функції
|
|
31
|
-
|
|
32
|
-
### `isIgnored(dir, ignorePaths)`
|
|
33
|
-
|
|
34
|
-
Перевіряє, чи каталог входить у список ignore (точний збіг або префіксне співпадіння).
|
|
35
|
-
|
|
36
|
-
- **Сигнатура:** `function isIgnored(dir: string, ignorePaths: string[]): boolean`
|
|
37
|
-
- **Параметри:**
|
|
38
|
-
- `dir` — абсолютний posix-шлях каталогу.
|
|
39
|
-
- `ignorePaths` — масив абсолютних posix-шляхів, отриманих з `.n-cursor.json` через `loadCursorIgnorePaths`.
|
|
40
|
-
- **Повертає:** `true`, якщо `dir` дорівнює якомусь елементу `ignorePaths` або починається з нього + `/`; інакше `false`.
|
|
41
|
-
- **Side effects:** немає.
|
|
42
|
-
|
|
43
|
-
### `findUtilsDirs(root, ignorePosix)`
|
|
44
|
-
|
|
45
|
-
Рекурсивно шукає всі каталоги з ім'ям `utils` під `root`.
|
|
46
|
-
|
|
47
|
-
- **Сигнатура:** `async function findUtilsDirs(root: string, ignorePosix: string[]): Promise<string[]>`
|
|
48
|
-
- **Параметри:**
|
|
49
|
-
- `root` — абсолютний шлях кореня обходу (зазвичай корінь package).
|
|
50
|
-
- `ignorePosix` — список абсолютних posix-шляхів, які пропускати.
|
|
51
|
-
- **Повертає:** масив абсолютних шляхів знайдених `utils/`-каталогів. Порядок — результат DFS у тому ж порядку, в якому повертає `readdir`.
|
|
52
|
-
- **Алгоритм:**
|
|
53
|
-
- Вкладена рекурсивна функція `walk(dir)` читає `readdir(dir, { withFileTypes: true })`.
|
|
54
|
-
- Помилка `readdir` (наприклад, нема прав чи каталог зник) проглинається через `try/catch` і дає ранній `return`.
|
|
55
|
-
- Для кожного запису-каталогу:
|
|
56
|
-
- якщо ім'я входить у `SKIP_DIR_NAMES` (`node_modules`, `.git`, `dist`, `coverage`, `.turbo`, `.next`, `__fixtures__`) — скіп;
|
|
57
|
-
- повний шлях конвертується у posix і перевіряється через `isIgnored` — скіп якщо так;
|
|
58
|
-
- якщо ім'я — рівно `utils`, додається у `found` і **не** заходить глибше (вкладені `utils/utils/` не очікуються; навіть якщо є — внутрішній `utils/` усе одно під самим `utils/` і його файли все одно пройдуть як файли зовнішнього `utils/`);
|
|
59
|
-
- інакше — рекурсивно `walk(full)`.
|
|
60
|
-
- **Side effects:** filesystem-чтення.
|
|
61
|
-
|
|
62
|
-
### `collectUtilsSources(utilsDir)`
|
|
63
|
-
|
|
64
|
-
Збирає всі не-тестові source-файли під `utilsDir`.
|
|
65
|
-
|
|
66
|
-
- **Сигнатура:** `async function collectUtilsSources(utilsDir: string): Promise<string[]>`
|
|
67
|
-
- **Параметри:** `utilsDir` — абсолютний шлях каталогу `utils/`.
|
|
68
|
-
- **Повертає:** масив абсолютних шляхів файлів-джерел.
|
|
69
|
-
- **Фільтри:**
|
|
70
|
-
- Каталоги `tests/`, `__fixtures__/` і будь-що з `SKIP_DIR_NAMES` — пропускаються (тести легально мають імпорти `../X` до свого модуля).
|
|
71
|
-
- Файли мають матчити `JS_SOURCE_RE` (`.mjs`, `.mts`, `.cjs`, `.cts`, `.js`, `.ts`, `.jsx`, `.tsx`).
|
|
72
|
-
- Файли, що матчать `TEST_FILE_RE` (`*.test.*`), — виключаються.
|
|
73
|
-
- **Алгоритм:** аналогічний DFS через вкладену `walk(dir)` з тим самим проглинанням помилок `readdir`.
|
|
74
|
-
- **Side effects:** filesystem-чтення.
|
|
75
|
-
|
|
76
|
-
### `extractImportSources(source, filePath)`
|
|
77
|
-
|
|
78
|
-
Витягає всі рядкові імпорт-source з тексту файлу.
|
|
79
|
-
|
|
80
|
-
- **Сигнатура:** `function extractImportSources(source: string, filePath: string): string[]`
|
|
81
|
-
- **Параметри:**
|
|
82
|
-
- `source` — текст файлу (UTF-8).
|
|
83
|
-
- `filePath` — шлях до файлу, потрібен для визначення мови парсингу через `langFromPath`.
|
|
84
|
-
- **Повертає:** масив рядків — значення source кожного імпорту в тому вигляді, в якому вони записані в коді (`'./foo'`, `'../bar'`, `'oxc-parser'`, ...).
|
|
85
|
-
- **Що збирає:**
|
|
86
|
-
- **Статичні імпорти** — з `parsed.module.staticImports[*].moduleRequest.value` (oxc-parser API).
|
|
87
|
-
- **Динамічні імпорти** (`import('...')`) — через `dynamicImportModule(node)` під час обходу AST.
|
|
88
|
-
- **CommonJS `require('...')`** — через `requireCallModule(node)`.
|
|
89
|
-
- **Обробка помилок парсингу:** `try/catch` на `parseSync` повертає порожній масив і **не** падає, бо синтаксична помилка — окремий концерн іншої перевірки; ця має запуститись чисто і не блокувати решту.
|
|
90
|
-
- **Side effects:** немає (виклик `parseSync` — CPU-only).
|
|
91
|
-
|
|
92
|
-
### `check()` (named export)
|
|
93
|
-
|
|
94
|
-
Точка входу. Виконує всю перевірку від поточного робочого каталогу.
|
|
95
|
-
|
|
96
|
-
- **Сигнатура:** `export async function check(): Promise<number>`
|
|
97
|
-
- **Параметри:** немає; використовує `process.cwd()` як корінь monorepo.
|
|
98
|
-
- **Повертає:** `0` — порушень немає; `1` — є хоча б одне (реальний exit-code обчислює `reporter.getExitCode()`).
|
|
99
|
-
- **Покроковий алгоритм:**
|
|
100
|
-
1. Створити `reporter` через `createCheckReporter()`.
|
|
101
|
-
2. `root = process.cwd()`.
|
|
102
|
-
3. Завантажити `ignorePaths` з `.n-cursor.json` (`loadCursorIgnorePaths`) і перевести у posix-варіант (`ignorePosix`).
|
|
103
|
-
4. Отримати relative-paths package-roots monorepo через `getMonorepoPackageRootDirs(root)`.
|
|
104
|
-
5. Для кожного package-root знайти всі `utils/`-каталоги (`findUtilsDirs`) і покласти у `Set` (`utilsDirSet`) для де-дуплікації.
|
|
105
|
-
6. Якщо `utils/`-каталогів немає взагалі — `reporter.pass(...)` з повідомленням про пропуск і повернути exit-code.
|
|
106
|
-
7. Інакше пройти кожен `utils/`-каталог:
|
|
107
|
-
- зібрати джерела (`collectUtilsSources`);
|
|
108
|
-
- для кожного файлу прочитати контент, витягти імпорти (`extractImportSources`);
|
|
109
|
-
- кожен import з префіксом `..` — `reporter.fail(...)` з relative-шляхом файлу та порушеним import-source, інкремент `violations`;
|
|
110
|
-
- `checkedFiles` рахує всі перевірені файли.
|
|
111
|
-
8. Якщо `violations === 0` — `reporter.pass(...)` зі статистикою (кількість utils-каталогів і файлів).
|
|
112
|
-
9. Повернути `reporter.getExitCode()`.
|
|
113
|
-
- **Side effects:**
|
|
114
|
-
- filesystem-чтення (рекурсивне сканування + `readFile`);
|
|
115
|
-
- запис у `reporter` (виводить рядки у stdout/stderr, залежно від реалізації);
|
|
116
|
-
- читає `process.cwd()`.
|
|
117
|
-
|
|
118
|
-
## Залежності
|
|
119
|
-
|
|
120
|
-
### Node-builtin
|
|
121
|
-
|
|
122
|
-
- `node:fs/promises` — `readdir`, `readFile`.
|
|
123
|
-
- `node:path` — `join`, `relative`, `sep`.
|
|
124
|
-
|
|
125
|
-
### npm-пакет
|
|
126
|
-
|
|
127
|
-
- `oxc-parser` — `parseSync` для парсингу JS/TS у AST з достовірною підтримкою сучасних синтаксисів (zero-config).
|
|
128
|
-
|
|
129
|
-
### Внутрішні модулі проєкту
|
|
130
|
-
|
|
131
|
-
- `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера; має методи `pass`, `fail`, `getExitCode`. Уніфікований API для всіх check-функцій.
|
|
132
|
-
- `../../../scripts/lib/load-cursor-config.mjs` → `loadCursorIgnorePaths` — читає `.n-cursor.json` (чи аналог) і повертає масив абсолютних шляхів, які треба пропустити.
|
|
133
|
-
- `../../../scripts/lib/workspaces.mjs` → `getMonorepoPackageRootDirs` — повертає relative-paths коренів пакетів у monorepo (включно з `.`-коренем, якщо це теж пакет).
|
|
134
|
-
- `../../../scripts/utils/ast-scan-utils.mjs`:
|
|
135
|
-
- `langFromPath(filePath)` — мапить розширення файлу у `lang`-параметр для `oxc-parser`.
|
|
136
|
-
- `walkAstWithAncestors(program, ancestors, visitor)` — обхід AST з трекінгом предків.
|
|
137
|
-
- `dynamicImportModule(node)` — повертає рядок source для `import('...')`, або `null`.
|
|
138
|
-
- `requireCallModule(node)` — повертає рядок source для `require('...')`, або `null`.
|
|
139
|
-
|
|
140
|
-
### Константи модуля
|
|
141
|
-
|
|
142
|
-
| Ім'я | Значення | Призначення |
|
|
143
|
-
| -------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
144
|
-
| `JS_SOURCE_RE` | `/\.(?:[cm]?[jt]sx?)$/u` | матчить `.mjs`, `.mts`, `.cjs`, `.cts`, `.js`, `.ts`, `.jsx`, `.tsx` |
|
|
145
|
-
| `TEST_FILE_RE` | `/\.test\.[cm]?[jt]sx?$/u` | матчить `*.test.{js,ts,...}` для виключення тестів |
|
|
146
|
-
| `PARENT_RELATIVE_RE` | `/^\.\.(?:\/ | $)/u` | матчить `..` як цілий сегмент (`..` або `../*`); відсіює false-positive типу `..foo` |
|
|
147
|
-
| `SKIP_DIR_NAMES` | `Set(['node_modules', '.git', 'dist', 'coverage', '.turbo', '.next', '__fixtures__'])` | каталоги, які скіпаємо при обходах |
|
|
148
|
-
|
|
149
|
-
## Потік виконання / Використання
|
|
150
|
-
|
|
151
|
-
### Інтеграція в перевірочний рантайм
|
|
152
|
-
|
|
153
|
-
Модуль викликається check-runner-ом правила `js.mdc` (зазвичай із `npm/rules/js/js/`). Runner імпортує named export `check` і чекає на її resolved-значення як на process exit-code. Сам файл **не** має top-level executable коду — лише визначення; це дозволяє безпечно імпортувати його у тестах.
|
|
154
|
-
|
|
155
|
-
Типовий виклик (псевдокод):
|
|
156
|
-
|
|
157
|
-
```mjs
|
|
158
|
-
import { check } from './utils_imports.mjs'
|
|
159
|
-
|
|
160
|
-
const exitCode = await check()
|
|
161
|
-
process.exit(exitCode)
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Сценарій "усе чисто"
|
|
165
|
-
|
|
166
|
-
1. Runner запускається з кореня monorepo.
|
|
167
|
-
2. `check()` знаходить `utils/` каталоги в усіх package-roots.
|
|
168
|
-
3. Для кожного non-test source файлу витягає імпорти.
|
|
169
|
-
4. Жоден імпорт не починається з `..`.
|
|
170
|
-
5. `reporter.pass('utils-каталогів: N, перевірено M файлів — domain-bound імпортів немає (js.mdc)')`.
|
|
171
|
-
6. `getExitCode() → 0`.
|
|
172
|
-
|
|
173
|
-
### Сценарій "є порушення"
|
|
174
|
-
|
|
175
|
-
1. Знайдено файл `packages/foo/utils/helper.mjs`.
|
|
176
|
-
2. У ньому є `import bar from '../lib/bar.mjs'`.
|
|
177
|
-
3. `PARENT_RELATIVE_RE` матчить `../lib/bar.mjs`.
|
|
178
|
-
4. `reporter.fail('packages/foo/utils/helper.mjs: заборонений імпорт \'../lib/bar.mjs\' — utils/-файли мають бути generic (js.mdc)')`.
|
|
179
|
-
5. `violations` інкрементується.
|
|
180
|
-
6. По завершенню `getExitCode() → 1`.
|
|
181
|
-
|
|
182
|
-
### Сценарій "немає utils/"
|
|
183
|
-
|
|
184
|
-
1. У жодному package немає каталогу `utils/`.
|
|
185
|
-
2. `utilsDirSet.size === 0`.
|
|
186
|
-
3. `reporter.pass('utils-каталогів немає — перевірку пропущено (js.mdc)')`.
|
|
187
|
-
4. `getExitCode() → 0`.
|
|
188
|
-
|
|
189
|
-
### Сценарій "файл із синтаксичною помилкою"
|
|
190
|
-
|
|
191
|
-
1. `parseSync` кидає виключення.
|
|
192
|
-
2. `extractImportSources` ловить його у `try/catch` і повертає `[]`.
|
|
193
|
-
3. Цей файл не дає порушень. Проблему синтаксису ловить інша перевірка.
|
|
194
|
-
|
|
195
|
-
### Сценарій "ignore-шлях"
|
|
196
|
-
|
|
197
|
-
1. У `.n-cursor.json` зазначено абсолютний шлях, що покриває певний `utils/`-каталог.
|
|
198
|
-
2. `findUtilsDirs` через `isIgnored` пропускає його ще на стадії обходу — той `utils/` навіть не потрапляє у `utilsDirSet`.
|
|
199
|
-
|
|
200
|
-
### Особливості/edge cases
|
|
201
|
-
|
|
202
|
-
- **Тести**: каталог `tests/` усередині `utils/` ігнорується повністю; також ігноруються файли `*.test.{js,ts,...}` будь-де всередині `utils/`. Це свідомо: тести легально імпортують свій модуль через `../X`.
|
|
203
|
-
- **`__fixtures__/`**: ігнорується і в `findUtilsDirs`, і в `collectUtilsSources` — фікстури можуть бути будь-якими.
|
|
204
|
-
- **Bare-imports** (`oxc-parser`, `node:fs`): не відсіюються спеціально, бо просто не матчать `PARENT_RELATIVE_RE`.
|
|
205
|
-
- **Same-dir імпорти** (`./X`): дозволені автоматично з тієї ж причини.
|
|
206
|
-
- **POSIX-шляхи для ignore**: під Windows `sep` — `\\`, тому шляхи нормалізуються у `/`-формат перед порівнянням з ignore-конфігом.
|
|
207
|
-
- **De-duplication** через `Set`: якщо monorepo-структура повертає однаковий `utils/`-шлях двічі (наприклад, `.`-root і назва вкладеного пакета перетинаються), він обробиться лише раз.
|
|
208
|
-
- **Помилки `readdir`** глушаться — недоступний каталог просто пропускається без падіння всієї перевірки.
|
|
209
|
-
|
|
210
|
-
### Залежність від конвенцій правила `js.mdc`
|
|
211
|
-
|
|
212
|
-
Файл є технічною реалізацією одного з пунктів правила `js.mdc`. Усі повідомлення `reporter.pass/fail` посилаються на `(js.mdc)`, щоб користувач знав, де читати про сам принцип розділу `utils/` ↔ `lib/`.
|
|
31
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
32
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
33
|
+
- Свідомо пропускає шляхи: `.git`, `node_modules`.
|
|
@@ -6,9 +6,9 @@ resource: npm/rules/npm-module/js/
|
|
|
6
6
|
|
|
7
7
|
# npm/rules/npm-module/js
|
|
8
8
|
|
|
9
|
-
| Файл
|
|
10
|
-
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
|---|---|
|
|
11
11
|
| [header_doc_pointer.mjs](header_doc_pointer.md) | JS Module |
|
|
12
|
-
| [package_structure.mjs](package_structure.md)
|
|
13
|
-
| [rule_meta.mjs](rule_meta.md)
|
|
14
|
-
| [skill_meta.mjs](skill_meta.md)
|
|
12
|
+
| [package_structure.mjs](package_structure.md) | JS Module |
|
|
13
|
+
| [rule_meta.mjs](rule_meta.md) | JS Module |
|
|
14
|
+
| [skill_meta.mjs](skill_meta.md) | JS Module |
|
|
@@ -3,31 +3,31 @@ type: JS Module
|
|
|
3
3
|
title: rule_meta.mjs
|
|
4
4
|
resource: npm/rules/npm-module/js/rule_meta.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 84394694
|
|
7
7
|
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
8
|
score: 100
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## Огляд
|
|
12
12
|
|
|
13
|
-
Модуль перевіряє
|
|
13
|
+
Модуль перевіряє конфігурації правил, розташованих у каталозі `npm/rules`. Він гарантує, що кожен підкаталог правила містить необхідні файли, включаючи маркери повідомлень (`scripts.mdc`), та коректно структурований конфігураційний файл, що базується на `main.json` та `meta.json`. Перевірка включає валідацію визначених предикатів та експортованих функцій відповідно до очікуваного контракту.
|
|
14
14
|
|
|
15
15
|
## Поведінка
|
|
16
16
|
|
|
17
|
-
1.
|
|
18
|
-
2.
|
|
19
|
-
3. Для кожного
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
4. Після обробки всіх
|
|
17
|
+
1. Перевіряє наявність каталогу `npm/rules` у корені репозиторію. Якщо каталог відсутній, завершує роботу, повідомляючи про відсутність правил для валідації.
|
|
18
|
+
2. Ітерує по всім підкаталогах у `npm/rules`, ігноруючи приховані каталоги.
|
|
19
|
+
3. Для кожного каталогу виконує перевірку правила:
|
|
20
|
+
а. Перевіряє відсутність файлу `auto.md`. Якщо знайдено, повідомляє про залишковий файл.
|
|
21
|
+
б. Перевіряє наявність файлу `main.mdc`. Якщо відсутній, повідомляє про відсутність обов'язкового файлу (scripts.mdc).
|
|
22
|
+
в. Зчитує вміст `main.json` каталогу правила. Якщо файл відсутній або невалідний, повідомляє про це та пропускає подальшу валідацію цього правила.
|
|
23
|
+
г. Перевіряє поле `auto` у `main.json`. Якщо поле присутнє, валідує його структуру та перевіряє, чи всі використані предикати визначені.
|
|
24
|
+
ґ. Перевіряє поле `lint` у `main.json`. Якщо поле присутнє, валідує його структуру та перевіряє, чи експортує файл `main.mjs` відповідну функцію `lint`.
|
|
25
|
+
і. Якщо всі перевірки для правила пройдені успішно, повідомляє про валідність `main.json`.
|
|
26
|
+
4. Після обробки всіх правил повертає код виходу, що відображає загальний статус валідації.
|
|
27
27
|
|
|
28
28
|
## Публічний API
|
|
29
29
|
|
|
30
|
-
check — перевіряє відповідність усіх
|
|
30
|
+
check — перевіряє відповідність усіх `npm/rules/<id>/meta.json` вимогам.
|
|
31
31
|
|
|
32
32
|
## Гарантії поведінки
|
|
33
33
|
|
|
@@ -3,24 +3,34 @@ type: JS Module
|
|
|
3
3
|
title: skill_meta.mjs
|
|
4
4
|
resource: npm/rules/npm-module/js/skill_meta.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: d02dd00d
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
7
8
|
score: 100
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Перевіряє структуру та конфігурацію скілів у каталозі `npm/skills`, використовуючи правила, визначені в `meta.json`. Валідує, що кожен скіл не містить файлу `auto.md`. Перевіряє валідність полів `worktree`, `auto` та `requireRoot` у `main.json` кожного скіла.
|
|
11
14
|
|
|
12
15
|
## Поведінка
|
|
13
16
|
|
|
14
|
-
1.
|
|
15
|
-
2.
|
|
16
|
-
3.
|
|
17
|
-
|
|
17
|
+
1. Перевіряє наявність каталогу `npm/skills` у поточному робочому каталозі. Якщо каталог відсутній, операція завершується успішно.
|
|
18
|
+
2. Ітерує по всіх підкаталогах у `npm/skills`.
|
|
19
|
+
3. Для кожного підкаталогу виконується перевірка метаданих скіла:
|
|
20
|
+
а. Перевіряється наявність файлу `auto.md` у каталозі скіла. Якщо він присутній, це вважається порушенням.
|
|
21
|
+
б. Зчитується вміст `main.json` скіла. Якщо файл відсутній або невалідний, перевірка для цього скіла припиняється.
|
|
22
|
+
в. Виконується перевірка полів `main.json` скіла:
|
|
23
|
+
i. `worktree` має бути булевим значенням.
|
|
24
|
+
ii. Якщо поле `auto` визначене, його вміст має бути розпізнаним як "завжди" або непорожній масив правил.
|
|
25
|
+
iii. `requireRoot` має бути булевим значенням, якщо визначений.
|
|
26
|
+
iv. Якщо `worktree` встановлено як `true`, а `requireRoot` як `false`, це вважається порушенням.
|
|
27
|
+
г. Якщо всі поля `main.json` валідні, це вважається успішним результатом для скіла.
|
|
28
|
+
4. Після перевірки всіх скілів повертається код виходу, що відображає загальний статус (0 — успіх, 1 — порушення).
|
|
18
29
|
|
|
19
30
|
## Публічний API
|
|
20
31
|
|
|
21
|
-
check —
|
|
32
|
+
check — перевіряє відповідність усіх файлів `meta.json` у каталозі `npm/skills/<id>/` заданим критеріям.
|
|
22
33
|
|
|
23
34
|
## Гарантії поведінки
|
|
24
35
|
|
|
25
|
-
- Read-only:
|
|
26
|
-
- Не звертається до мережі.
|
|
36
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -17,11 +17,11 @@ function checkAutoField(id, raw, reporter) {
|
|
|
17
17
|
if (raw.auto === undefined) return true
|
|
18
18
|
const spec = parseRuleAutoSpec(raw.auto)
|
|
19
19
|
if (spec === null) {
|
|
20
|
-
reporter.fail(`rules/${id}:
|
|
20
|
+
reporter.fail(`rules/${id}: main.json.auto нерозпізнане (очікується "завжди" / масив / {glob} / {predicate})`)
|
|
21
21
|
return false
|
|
22
22
|
}
|
|
23
23
|
if ('predicate' in spec && !Object.hasOwn(RULE_PREDICATES, spec.predicate)) {
|
|
24
|
-
reporter.fail(`rules/${id}: невідомий predicate "${spec.predicate}" (немає в RULE_PREDICATES)`)
|
|
24
|
+
reporter.fail(`rules/${id}: main.json — невідомий predicate "${spec.predicate}" (немає в RULE_PREDICATES)`)
|
|
25
25
|
return false
|
|
26
26
|
}
|
|
27
27
|
return true
|
|
@@ -38,7 +38,7 @@ function checkAutoField(id, raw, reporter) {
|
|
|
38
38
|
function checkLintField(id, ruleDir, raw, reporter) {
|
|
39
39
|
if (raw.lint === undefined) return true
|
|
40
40
|
if (parseRuleLintSpec(raw.lint) === null) {
|
|
41
|
-
reporter.fail(`rules/${id}:
|
|
41
|
+
reporter.fail(`rules/${id}: main.json.lint нерозпізнане (очікується "per-file"|"full")`)
|
|
42
42
|
return false
|
|
43
43
|
}
|
|
44
44
|
const mainPath = join(ruleDir, 'main.mjs')
|
|
@@ -63,19 +63,19 @@ function checkRule(id, ruleDir, reporter) {
|
|
|
63
63
|
let ruleOk = true
|
|
64
64
|
|
|
65
65
|
if (existsSync(join(ruleDir, 'auto.md'))) {
|
|
66
|
-
reporter.fail(`rules/${id}: залишковий auto.md — видали (метадані тепер у
|
|
66
|
+
reporter.fail(`rules/${id}: залишковий auto.md — видали (метадані тепер у main.json)`)
|
|
67
67
|
ruleOk = false
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
// Канон (scripts.mdc):
|
|
71
|
-
if (!existsSync(join(ruleDir,
|
|
72
|
-
reporter.fail(`rules/${id}: відсутній
|
|
70
|
+
// Канон (scripts.mdc): main.mdc — ОБОВ'ЯЗКОВИЙ у кожному npm/rules/<id>/.
|
|
71
|
+
if (!existsSync(join(ruleDir, 'main.mdc'))) {
|
|
72
|
+
reporter.fail(`rules/${id}: відсутній main.mdc — обов'язковий (scripts.mdc)`)
|
|
73
73
|
ruleOk = false
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
const raw = readRuleMetaRaw(ruleDir)
|
|
77
77
|
if (!raw) {
|
|
78
|
-
reporter.fail(`rules/${id}: відсутній або невалідний
|
|
78
|
+
reporter.fail(`rules/${id}: відсутній або невалідний main.json`)
|
|
79
79
|
return
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -83,7 +83,7 @@ function checkRule(id, ruleDir, reporter) {
|
|
|
83
83
|
if (!checkLintField(id, ruleDir, raw, reporter)) ruleOk = false
|
|
84
84
|
|
|
85
85
|
if (ruleOk) {
|
|
86
|
-
reporter.pass(`rules/${id}:
|
|
86
|
+
reporter.pass(`rules/${id}: main.json валідний`)
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|