@nitra/cursor 5.3.3 → 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 +17 -0
- package/bin/n-cursor.js +43 -22
- package/lib/docs/llm.md +23 -12
- 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/rules/doc-files/js/docs/docgen-extract-anchors.md +45 -0
- package/rules/doc-files/js/docs/docgen-extract.md +39 -0
- package/rules/doc-files/js/docs/docgen-files-batch.md +35 -0
- package/rules/doc-files/js/docs/docgen-gen.md +46 -0
- package/rules/doc-files/js/docs/docgen-ignore.md +37 -0
- 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-0012.md +5 -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-extract-anchors.md +0 -27
- package/skills/doc-files/js/docs/docgen-extract.md +0 -29
- package/skills/doc-files/js/docs/docgen-files-batch.md +0 -25
- package/skills/doc-files/js/docs/docgen-gen.md +0 -30
- 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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/docgen-files-batch.mjs
|
|
4
|
+
crc: 5c9b8d72
|
|
5
|
+
score: 95
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# docgen-files-batch.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
runDocFilesGenCli
|
|
13
|
+
Запускає генерацію документації для застарілих або відсутніх файлів.
|
|
14
|
+
|
|
15
|
+
runDocFilesStampCli
|
|
16
|
+
Перештампує frontmatter джерело та CRC у наявних документах без виклику LLM.
|
|
17
|
+
|
|
18
|
+
## Поведінка
|
|
19
|
+
|
|
20
|
+
runDocFilesGenCli
|
|
21
|
+
Запускає генерацію документації для застарілих/відсутніх док.
|
|
22
|
+
|
|
23
|
+
runDocFilesStampCli
|
|
24
|
+
Перештампує frontmatter source+crc у наявних доках без виклику LLM.
|
|
25
|
+
|
|
26
|
+
## Публічний API
|
|
27
|
+
|
|
28
|
+
- runDocFilesGenCli — згенерувати документацію для застарілих/відсутніх док.
|
|
29
|
+
- runDocFilesStampCli — детерміновано (пере)штампувати frontmatter `source`+`crc` у наявних доках без виклику LLM. Для міграції док, які ще не мають CRC. Поля якості (`score`/`issues`) зберігаються з наявного frontmatter.
|
|
30
|
+
|
|
31
|
+
## Гарантії поведінки
|
|
32
|
+
|
|
33
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
34
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
35
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/docgen-gen.mjs
|
|
4
|
+
crc: e2af04d6
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# docgen-gen.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
Огляд
|
|
13
|
+
Публічні функції виконують операції з текстом та оцінками. Вони включають виділення коду, вставлення інформації та генерацію документів на основі визначених параметрів.
|
|
14
|
+
|
|
15
|
+
## Поведінка
|
|
16
|
+
|
|
17
|
+
splitProtected
|
|
18
|
+
Вибирає та видаляє код-фенс-обгортку з секції
|
|
19
|
+
|
|
20
|
+
insertProtected
|
|
21
|
+
Вставляє захищений блок Призначення після заголовка Огляд
|
|
22
|
+
|
|
23
|
+
scoreDoc
|
|
24
|
+
Перевіряє вихід проти фактів і повертає оцінку та список проблем
|
|
25
|
+
|
|
26
|
+
DEFAULT_LOCAL_MODEL
|
|
27
|
+
Повертає дефолтну модель для роботи
|
|
28
|
+
|
|
29
|
+
generateDoc
|
|
30
|
+
Генерує документ з детермінованою оцінкою та метаданими
|
|
31
|
+
|
|
32
|
+
## Публічний API
|
|
33
|
+
|
|
34
|
+
splitProtected — Відокремлює захищену секцію `## Призначення` (Варіант B). Межа — наступний `## ` і `###` не обриває блок. (abie.mdc)
|
|
35
|
+
insertProtected — Вставляє захищений блок `## Призначення` одразу після H1 (фіксована позиція). (abie.mdc)
|
|
36
|
+
scoreDoc — Stage 2.5 — Детермінований скоринг (0 токенів): перевіряє вихід проти фактів. (abie.mdc)
|
|
37
|
+
DEFAULT_LOCAL_MODEL — Дефолтна модель: N_CURSOR_DOCGEN_MODEL → resolveModel → omlx напряму. Останній fallback гарантує локальний виклик без змін середовища (через pi CLI той самий локальний виклик виміряно повільніший на ~46%). (abie.mdc)
|
|
38
|
+
generateDoc — Головний API: файл → md-дока з det-оцінкою. (abie.mdc)
|
|
39
|
+
|
|
40
|
+
## Гарантії поведінки
|
|
41
|
+
|
|
42
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
43
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
44
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
45
|
+
- Кешує результати в межах одного прогону.
|
|
46
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/docgen-ignore.mjs
|
|
4
|
+
crc: c17cd785
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# docgen-ignore.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
DOCGEN_IGNORE_GLOBS
|
|
13
|
+
Список шляхів, які docgen повинен ігнорувати.
|
|
14
|
+
|
|
15
|
+
isDocgenIgnored
|
|
16
|
+
Перевіряє, чи шлях знаходиться у списку ігнорованих шляхів.
|
|
17
|
+
|
|
18
|
+
## Поведінка
|
|
19
|
+
|
|
20
|
+
DOCGEN_IGNORE_GLOBS
|
|
21
|
+
Базовий список glob-ів для docgen ignore
|
|
22
|
+
|
|
23
|
+
isDocgenIgnored
|
|
24
|
+
Перевіряє, чи шлях має бути пропущений docgen
|
|
25
|
+
|
|
26
|
+
## Публічний API
|
|
27
|
+
|
|
28
|
+
DOCGEN_IGNORE_GLOBS — Список glob-ів для ігнорування у `docgen`.
|
|
29
|
+
isDocgenIgnored — Визначає, чи шлях повинен бути пропущений `docgen`. Для `kind = 'dir'` працює і на підкаталоги, наприклад, `**\\/demo/**` спрацьовує на `demo/x` під час рекурсивного обходу.
|
|
30
|
+
|
|
31
|
+
## Гарантії поведінки
|
|
32
|
+
|
|
33
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
34
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
35
|
+
- Кешує результати в межах одного прогону.
|
|
36
|
+
- Свідомо пропускає шляхи: `.git`, `node_modules`.
|
|
37
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/docgen-prompts.mjs
|
|
4
|
+
crc: 72ac304f
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# docgen-prompts.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
Файл надає інструкції для створення лаконічної поведінкової документації українською мовою. Він містить інструменти для формування, перевірки та виправлення тексту документації, а також для визначення гарантій щодо роботи файлу
|
|
13
|
+
|
|
14
|
+
## Поведінка
|
|
15
|
+
|
|
16
|
+
Поведінка:
|
|
17
|
+
- STYLE: Надає інструкцію для генерації лаконічної поведінкової документації українською мовою.
|
|
18
|
+
- sectionMessages: Генерує секційні промпти для різних частин документації.
|
|
19
|
+
- overviewMessages: Формує текст для узагальнення ролі та призначення файлу.
|
|
20
|
+
- criticMessages: Створює запити для перевірки чорновиків документації на наявність дефектів.
|
|
21
|
+
- refineMessages: Переписує та виправляє чорновки документації відповідно до критики.
|
|
22
|
+
- guaranteesFromMarkers: Формує список гарантій щодо поведінки файлу на основі маркерів.
|
|
23
|
+
- oneShotMessages: Створює універсальний запит для генерації повної документації.
|
|
24
|
+
|
|
25
|
+
## Публічний API
|
|
26
|
+
|
|
27
|
+
STYLE — Формулює стиль файлу.
|
|
28
|
+
sectionMessages — Збирає повідомлення з мінімальним контекстом для кожної секції.
|
|
29
|
+
overviewMessages — Надає узагальнення поведінки файлу.
|
|
30
|
+
criticMessages — Виявляє дефекти в чорнетці секції.
|
|
31
|
+
refineMessages — Виправляє чорнетку, усуваючи виявлені дефекти.
|
|
32
|
+
guaranteesFromMarkers — Створює детермінований шаблон гарантій поведінки з фактів.
|
|
33
|
+
|
|
34
|
+
## Гарантії поведінки
|
|
35
|
+
|
|
36
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
37
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
38
|
+
- Кешує результати в межах одного прогону.
|
|
39
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/docgen-scan.mjs
|
|
4
|
+
crc: 46f11827
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# docgen-scan.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
isSourceFile перевіряє, чи є файл кодовим джерелом.
|
|
13
|
+
docPathForSource обчислює шлях md-документа для кодового файлу.
|
|
14
|
+
isDocCandidate перевіряє, чи підлягає файл документуванню.
|
|
15
|
+
describeFile описує кодовий файл, включаючи шлях доки та стан застарілості.
|
|
16
|
+
scanForDocFiles рекурсивно обходить дерево, повертаючи кандидати з інформацією про старілість.
|
|
17
|
+
resolveRoot парсить аргументи, щоб визначити абсолютний корінь.
|
|
18
|
+
runDocFilesScanCli сканує дерево і друкує JSON-масив усіх кодових файлів зі станом застарілості.
|
|
19
|
+
runDocFilesCheckCli детектує застарілість для хук'ів, гейтів або інших режимів, повертаючи код виходу.
|
|
20
|
+
|
|
21
|
+
## Поведінка
|
|
22
|
+
|
|
23
|
+
isSourceFile Обчислює, чи є файл кодовим джерелом.
|
|
24
|
+
docPathForSource Обчислює шлях md-документа для кодового файлу.
|
|
25
|
+
isDocCandidate Перевіряє, чи підлягає файл документуванню.
|
|
26
|
+
describeFile Описує кодовий файл, включаючи шлях доки та стан застарілості.
|
|
27
|
+
scanForDocFiles Рекурсивно обходить дерево, повертаючи кандидати з інформацією про старілість.
|
|
28
|
+
resolveRoot Парсить аргументи, щоб визначити абсолютний корінь.
|
|
29
|
+
runDocFilesScanCli Сканує дерево і друкує JSON-масив усіх кодових файлів зі станом застарілості.
|
|
30
|
+
runDocFilesCheckCli Детектує застарілість для хук'ів, гейтів або інших режимів, повертаючи код виходу.
|
|
31
|
+
|
|
32
|
+
## Публічний API
|
|
33
|
+
|
|
34
|
+
isSourceFile — перевіряє, чи є файл коду для документування.
|
|
35
|
+
docPathForSource — обчислює шлях до документа для кодового файлу, розміщуючи його в теці `docs/` поруч із джерелом. Якщо шлях відносний, документ також відносний; якщо абсолютний, документ залишається абсолютним.
|
|
36
|
+
isDocCandidate — визначає, чи підлягає кодовий файл документуванню: має правильне розширення, не є тестом, не знаходиться в ігнорованому списку, і не є кореневим системним документуванням.
|
|
37
|
+
describeFile — надає опис кодового файлу: шлях до джерела, шлях до документа та стан застарілості за CRC.
|
|
38
|
+
scanForDocFiles — рекурсивно переглядає дерево від заданого кореня і повертає кодові файли разом зі станом застарілості.
|
|
39
|
+
resolveRoot — парсить аргумент `--root <dir>` з командного рядка; за замовчуванням використовує поточну робочу директорію.
|
|
40
|
+
runDocFilesScanCli — сканує дерево і виводить JSON-масив усіх кодових файлів із зазначенням їхнього стану застарілості.
|
|
41
|
+
runDocFilesCheckCli — виконує перевірку застарілості для хуків та командного рядка через інструмент `doc-files check`.
|
|
42
|
+
Режими — це способи виконання:
|
|
43
|
+
--hook — бере шлях до файлу з вводу JSON і перевіряє один файл.
|
|
44
|
+
--git — перевіряє різницю в Git (`git diff --name-only HEAD`) з урахуванням порогу `--max` (за замовчуванням 50); якщо застарілості більше, не блокує (виходить з кодом 0 з попередженням).
|
|
45
|
+
--degraded — генерує інформаційний звіт про документи, які мають оцінку нижче встановленого порогу (виходить з кодом 0).
|
|
46
|
+
<paths…> — використовується для визначення явних шляхів до джерел.
|
|
47
|
+
Exit 2 — повертається, якщо знайдено застарілі дані; повертається 0, якщо дані свіжі або пройдено перевищення порогу.
|
|
48
|
+
|
|
49
|
+
## Гарантії поведінки
|
|
50
|
+
|
|
51
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
52
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
53
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
54
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/lint.mjs
|
|
4
|
+
crc: f25a3bbe
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# lint.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
Адаптер правила doc-files до агрегатора `n-cursor lint`. Дає агрегатору відповідь на одне
|
|
13
|
+
питання: чи має кожен дотичний кодовий файл актуальну файлову документацію поряд із собою.
|
|
14
|
+
|
|
15
|
+
## Поведінка
|
|
16
|
+
|
|
17
|
+
У quick-фазі отримує список змінених файлів і зводить його до набору джерел для перевірки в
|
|
18
|
+
**обидва** боки: змінене джерело перевіряється проти своєї доки, а змінена або видалена дока
|
|
19
|
+
(`<dir>/docs/<stem>.md`) повертається до відповідного джерела з тим самим іменем у каталозі над
|
|
20
|
+
`docs/`. У ci-фазі (списку немає) обходить усе дерево.
|
|
21
|
+
|
|
22
|
+
Порушенням вважається відсутня дока (`missing`) або розбіжність контрольної суми джерела з тією,
|
|
23
|
+
що записана у frontmatter доки (`crc-mismatch`). Документ із низькою якістю, але свіжою сумою —
|
|
24
|
+
не порушення.
|
|
25
|
+
|
|
26
|
+
## Публічний API
|
|
27
|
+
|
|
28
|
+
`lint` — перевіряє документацію для переданого набору змінених файлів (або всього репозиторію,
|
|
29
|
+
якщо набір не задано); повертає код виходу `1`, якщо є застарілі чи відсутні доки, інакше `0`.
|
|
30
|
+
Список проблемних файлів друкується у stderr із підказкою регенерувати.
|
|
31
|
+
|
|
32
|
+
## Гарантії поведінки
|
|
33
|
+
|
|
34
|
+
- Детермінованість: жодного виклику мовної моделі, рішення лише за контрольною сумою.
|
|
35
|
+
- Реверс-мапінг доки до джерела перебирає лише кодові розширення і повертає наявний файл-кандидат.
|
|
36
|
+
- Порожній набір змінених файлів дає код `0` без обходу дерева.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/units-js.mjs
|
|
4
|
+
crc: 58b898cc
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# units-js.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
Файл парсить програму, ітеруючи по її елементах для збору юнітів. Для кожної декларації визначається опис. Для функцій та класів збираються виклики інших юнітів через ребра викликів.
|
|
13
|
+
|
|
14
|
+
## Поведінка
|
|
15
|
+
|
|
16
|
+
1. Парсинг програми.
|
|
17
|
+
2. Ітерація по тілу програми.
|
|
18
|
+
3. Збір юнітів.
|
|
19
|
+
4. Для кожної декларації визначається опис.
|
|
20
|
+
5. Для функцій та класів збираються виклики інших юнітів.
|
|
21
|
+
6. Вибираються виклики інших юнітів з ребрами викликів.
|
|
22
|
+
|
|
23
|
+
## Публічний API
|
|
24
|
+
|
|
25
|
+
extractUnitsJs — Юніт-шар для js/mjs/ts: top-level функції/класи/const-функції з тілом, JSDoc, прапором експорту і ребрами call-graph (виклики ІНШИХ юнітів у тілі).
|
|
26
|
+
|
|
27
|
+
## Гарантії поведінки
|
|
28
|
+
|
|
29
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
30
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
31
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/units-rs.mjs
|
|
4
|
+
crc: 114e9a0b
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# units-rs.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
Файл аналізує структуру коду для вилучення інформації про юніти. Процес включає сканування рядків, ітерацію для визначення глибини блоків та позиції закриваючих лапок. Обробляються рядкові літерали для визначення межі блоків та підраховуються глибини блоків для визначення видимості. Обробляються декларації для визначення публічності. Витягується тіло функцій, структур, перерахувань або трейтів. Визначається експонування функцій через атрибути. Збирається документація перед декларацією. Формується об'єкт юніту з назвою, типом, публічністю, ім'я impl та діапазон. Визначається область видимості тіла за допомогою пошуку закриваючої фігу. Збираються виклики інших юнітів у тілі функції.
|
|
13
|
+
|
|
14
|
+
## Поведінка
|
|
15
|
+
|
|
16
|
+
1. Скан файлу по рядках.
|
|
17
|
+
2. Ітерація по рядках для визначення глибини блоків.
|
|
18
|
+
3. Обробка рядкових літералів для визначення позиції закриваючого лапки.
|
|
19
|
+
4. Підрахунок глибини блоків для визначення видимості.
|
|
20
|
+
5. Обробка декларацій для визначення публічності.
|
|
21
|
+
6. Витягнення тіла функції, структури, перерахування або трейта.
|
|
22
|
+
7. Визначення експонування функції через атрибути.
|
|
23
|
+
8. Збір документації перед декларацією.
|
|
24
|
+
9. Формування об'єкта юніту з назвою, типом, публічністю, ім'ям impl та діапазоном.
|
|
25
|
+
10. Визначення області видимості тіла за допомогою пошуку закриваючої фігу.
|
|
26
|
+
11. Збір викликів інших юнітів у тілі функції.
|
|
27
|
+
|
|
28
|
+
## Публічний API
|
|
29
|
+
|
|
30
|
+
extractUnitsRs — Визначає top-level і impl-методи через підрахунок дужок по рядках. Обмеження: рядкові літерали з `{`/`}` всередині `{}` можуть дати хибну глибину.
|
|
31
|
+
|
|
32
|
+
## Гарантії поведінки
|
|
33
|
+
|
|
34
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
35
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/js/units.mjs
|
|
4
|
+
crc: af91bd0d
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# units.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
Файл витягує одиниці з вмісту файлу залежно від розширення шляху. Якщо розширення належить до набору JS_EXT, використовується extractUnitsJs. Якщо розширення дорівнює 'rs', використовується extractUnitsRs. В інших випадках функція повертає null.
|
|
13
|
+
|
|
14
|
+
## Поведінка
|
|
15
|
+
|
|
16
|
+
1. extractUnits приймає вміст файлу та шлях файлу.
|
|
17
|
+
2. Перевіряє розширення шляху.
|
|
18
|
+
3. Якщо розширення знаходиться у наборі JS_EXT, викликає extractUnitsJs.
|
|
19
|
+
4. Якщо розширення дорівнює 'rs', викликає extractUnitsRs.
|
|
20
|
+
5. У інших випадках повертає null.
|
|
21
|
+
|
|
22
|
+
## Публічний API
|
|
23
|
+
|
|
24
|
+
extractUnits — Визначає тип парсингу залежно від розширення файлу: js/mjs/ts використовує oxc AST, rs використовує regex+brace-counting, vue/py повертає null (повний шлях).
|
|
25
|
+
|
|
26
|
+
## Гарантії поведінки
|
|
27
|
+
|
|
28
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
29
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
30
|
+
- Не звертається до мережі.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Адаптер агрегатора `n-cursor lint` для правила doc-files.
|
|
3
|
+
*
|
|
4
|
+
* Quick-фаза отримує список змінених файлів і мапить їх у пари в **обидва** боки:
|
|
5
|
+
* - змінене **джерело** (`.js/.mjs/.ts/.vue/.py/.rs`) → перевірка його доки `<dir>/docs/<stem>.md`;
|
|
6
|
+
* - змінена/видалена **дока** (`<dir>/docs/<stem>.md`) → перевірка відповідного джерела
|
|
7
|
+
* (той самий stem у каталозі над текою `docs`).
|
|
8
|
+
* Ci-фаза (files === undefined) проганяє повний скан дерева.
|
|
9
|
+
*
|
|
10
|
+
* Порушення — `missing` ∪ `crc-mismatch` (детермінований CRC-детект, 0 LLM-токенів);
|
|
11
|
+
* degraded не блокує. Exit 1 — є stale; 0 — все свіже (конвенція агрегатора).
|
|
12
|
+
*/
|
|
13
|
+
import { join, dirname, basename, extname } from 'node:path'
|
|
14
|
+
import { existsSync, readdirSync } from 'node:fs'
|
|
15
|
+
|
|
16
|
+
import { describeFile, isDocCandidate, isSourceFile, scanForDocFiles } from './docgen-scan.mjs'
|
|
17
|
+
|
|
18
|
+
/** Дока живе у `<dir>/docs/<stem>.md`; повертає `<dir>/<stem>` для реверс-мапінгу. */
|
|
19
|
+
const DOC_MD_RE = /(?:^|\/)docs\/[^/]+\.md$/u
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Реверс-мапінг доки → джерело: для `<dir>/docs/<stem>.md` шукає у `<dir>` файл
|
|
23
|
+
* `<stem>.<ext>` із кодовим розширенням, що існує і є кандидатом на доку.
|
|
24
|
+
* @param {string} cwd корінь репо
|
|
25
|
+
* @param {string} docRel posix-шлях доки від кореня
|
|
26
|
+
* @returns {string|null} posix-шлях джерела або null
|
|
27
|
+
*/
|
|
28
|
+
function sourceForDoc(cwd, docRel) {
|
|
29
|
+
const docsDir = dirname(docRel) // `<dir>/docs`
|
|
30
|
+
const srcDir = dirname(docsDir) // `<dir>`
|
|
31
|
+
const stem = basename(docRel, '.md')
|
|
32
|
+
let entries
|
|
33
|
+
try {
|
|
34
|
+
entries = readdirSync(join(cwd, srcDir), { withFileTypes: true })
|
|
35
|
+
} catch {
|
|
36
|
+
return null
|
|
37
|
+
}
|
|
38
|
+
for (const e of entries) {
|
|
39
|
+
if (!e.isFile() || !isSourceFile(e.name)) continue
|
|
40
|
+
if (basename(e.name, extname(e.name)) !== stem) continue
|
|
41
|
+
const rel = srcDir === '.' ? e.name : `${srcDir}/${e.name}`
|
|
42
|
+
if (isDocCandidate(cwd, rel)) return rel
|
|
43
|
+
}
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Зводить список змінених файлів у множину джерел-кандидатів для перевірки доки.
|
|
49
|
+
* @param {string[]} files змінені шляхи (posix або нативні)
|
|
50
|
+
* @param {string} cwd корінь репо
|
|
51
|
+
* @returns {string[]} унікальні posix-шляхи джерел
|
|
52
|
+
*/
|
|
53
|
+
function sourcesFromChanged(files, cwd) {
|
|
54
|
+
const out = new Set()
|
|
55
|
+
for (const raw of files) {
|
|
56
|
+
const rel = raw.split('\\').join('/')
|
|
57
|
+
if (DOC_MD_RE.test(rel)) {
|
|
58
|
+
const src = sourceForDoc(cwd, rel)
|
|
59
|
+
if (src) out.add(src)
|
|
60
|
+
} else if (isDocCandidate(cwd, rel) && existsSync(join(cwd, rel))) {
|
|
61
|
+
out.add(rel)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return [...out]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Друкує список stale і повертає exit-код.
|
|
69
|
+
* @param {Array<{sourcePath:string, reason:string|null}>} stale застарілі описи
|
|
70
|
+
* @returns {number} 1 — є stale; 0 — немає
|
|
71
|
+
*/
|
|
72
|
+
function reportStale(stale) {
|
|
73
|
+
if (stale.length === 0) return 0
|
|
74
|
+
const list = stale.map(f => ` - ${f.sourcePath} (${f.reason})`).join('\n')
|
|
75
|
+
process.stderr.write(
|
|
76
|
+
`✗ doc-files: документація застаріла/відсутня для ${stale.length} файл(ів):\n${list}\n→ перегенеруй: npx @nitra/cursor fix-doc-files\n`
|
|
77
|
+
)
|
|
78
|
+
return 1
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Крок агрегатора lint для doc-files.
|
|
83
|
+
* @param {string[] | undefined} files quick: лише ці файли; undefined: весь репозиторій
|
|
84
|
+
* @param {string} [cwd] корінь репо
|
|
85
|
+
* @returns {Promise<number>} 0 — OK, 1 — є застарілі доки
|
|
86
|
+
*/
|
|
87
|
+
export function lint(files, cwd = process.cwd()) {
|
|
88
|
+
if (files === undefined) {
|
|
89
|
+
const stale = scanForDocFiles(cwd).filter(f => f.stale)
|
|
90
|
+
return Promise.resolve(reportStale(stale))
|
|
91
|
+
}
|
|
92
|
+
const sources = sourcesFromChanged(files, cwd)
|
|
93
|
+
if (sources.length === 0) return Promise.resolve(0)
|
|
94
|
+
const stale = sources.map(src => describeFile(cwd, src)).filter(f => f.stale)
|
|
95
|
+
return Promise.resolve(reportStale(stale))
|
|
96
|
+
}
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
function skipString(src, i) {
|
|
10
10
|
i++ // відкриваючий "
|
|
11
11
|
while (i < src.length) {
|
|
12
|
-
if (src[i] === '\\') {
|
|
12
|
+
if (src[i] === '\\') {
|
|
13
|
+
i += 2
|
|
14
|
+
continue
|
|
15
|
+
}
|
|
13
16
|
if (src[i] === '"') return i + 1
|
|
14
17
|
i++
|
|
15
18
|
}
|
|
@@ -38,8 +41,15 @@ function findClosingBrace(src, start) {
|
|
|
38
41
|
i = end === -1 ? src.length : end + 2
|
|
39
42
|
continue
|
|
40
43
|
}
|
|
41
|
-
if (ch === '"') {
|
|
42
|
-
|
|
44
|
+
if (ch === '"') {
|
|
45
|
+
i = skipString(src, i)
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
if (ch === '{') {
|
|
49
|
+
depth++
|
|
50
|
+
i++
|
|
51
|
+
continue
|
|
52
|
+
}
|
|
43
53
|
if (ch === '}') {
|
|
44
54
|
depth--
|
|
45
55
|
if (depth === 0) return i
|
|
@@ -73,12 +83,17 @@ function docBefore(lines, lineIdx) {
|
|
|
73
83
|
return doc.join(' ').trim()
|
|
74
84
|
}
|
|
75
85
|
|
|
76
|
-
// Pub-items
|
|
86
|
+
// Pub-items матчаться у два кроки по trim-нутому рядку (прості регекспи без
|
|
87
|
+
// бектрекінгу): спершу опційний pub(...)-префікс, потім сама декларація.
|
|
77
88
|
// Також ловить fn без pub (для localSymbols і impl-методів)
|
|
78
|
-
const
|
|
89
|
+
const PUB_PREFIX_RE = /^pub(?:\([^)]*\))?\s+/
|
|
90
|
+
const ITEM_DECL_RE = /^(?:async\s+)?(?:unsafe\s+)?(fn|struct|enum|trait|type)\s+(\w+)/
|
|
79
91
|
|
|
80
|
-
// impl Type { або impl<T> Trait for Type {
|
|
81
|
-
|
|
92
|
+
// impl Type { або impl<T> Trait for Type { — теж двокроково: голова `impl<...>`,
|
|
93
|
+
// далі тип після `for` (trait-impl) або перше слово (inherent impl)
|
|
94
|
+
const IMPL_HEAD_RE = /^impl(?:<[^>]*>)?\s+/
|
|
95
|
+
const IMPL_FOR_TYPE_RE = /\bfor\s+(\w+)/
|
|
96
|
+
const TYPE_NAME_RE = /^(\w+)/
|
|
82
97
|
|
|
83
98
|
// Підозрілі exposure-атрибути, що роблять непуб-fn фактично публічними
|
|
84
99
|
const EXPOSURE_ATTR_RE = /#\[(?:tauri::command|wasm_bindgen|uniffi::export|pyo3::pyfunction|napi)/
|
|
@@ -93,7 +108,7 @@ const CALL_RE = /\b([a-z_]\w*)\s*\(/g
|
|
|
93
108
|
* хибну глибину (рідкісно в реальному Rust-коді з rustfmt).
|
|
94
109
|
* @param {string} src вміст файлу
|
|
95
110
|
* @param {string} [_relPath] резервний (не використовується)
|
|
96
|
-
* @returns {Array<{name:string, kind:string, exported:boolean, implName:string|null, span:{start:number,end:number}, body:string, calls:string[], doc:string}>|null}
|
|
111
|
+
* @returns {Array<{name:string, kind:string, exported:boolean, implName:string|null, span:{start:number,end:number}, body:string, calls:string[], doc:string}>|null} юніти файлу (fn та impl-методи) або `null`, якщо юнітів не знайдено
|
|
97
112
|
*/
|
|
98
113
|
export function extractUnitsRs(src, _relPath) {
|
|
99
114
|
const lines = src.split('\n')
|
|
@@ -129,7 +144,7 @@ export function extractUnitsRs(src, _relPath) {
|
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
// Закриті impl-блоки прибираємо зі стека
|
|
132
|
-
while (implStack.length > 0 && implStack
|
|
147
|
+
while (implStack.length > 0 && implStack.at(-1).openDepth > depth) {
|
|
133
148
|
implStack.pop()
|
|
134
149
|
}
|
|
135
150
|
|
|
@@ -140,22 +155,27 @@ export function extractUnitsRs(src, _relPath) {
|
|
|
140
155
|
nextFnExposed = true
|
|
141
156
|
}
|
|
142
157
|
|
|
158
|
+
const trimmed = line.trimStart()
|
|
159
|
+
|
|
143
160
|
// Impl-декларація (зазвичай глибина 0, але може бути в mod)
|
|
144
161
|
if (depthAtStart <= 1) {
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
|
|
162
|
+
const headM = trimmed.match(IMPL_HEAD_RE)
|
|
163
|
+
if (headM && line.includes('{')) {
|
|
164
|
+
const rest = trimmed.slice(headM[0].length)
|
|
165
|
+
const typeM = rest.match(IMPL_FOR_TYPE_RE) ?? rest.match(TYPE_NAME_RE)
|
|
166
|
+
if (typeM) implStack.push({ typeName: typeM[1], openDepth: depth })
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
169
|
|
|
151
170
|
// Елементи на глибині 0 (top-level) і 1 (всередині impl)
|
|
152
171
|
if (depthAtStart <= 1) {
|
|
153
|
-
const
|
|
172
|
+
const pubM = trimmed.match(PUB_PREFIX_RE)
|
|
173
|
+
const m = (pubM ? trimmed.slice(pubM[0].length) : trimmed).match(ITEM_DECL_RE)
|
|
154
174
|
if (m) {
|
|
155
|
-
const isPub = Boolean(
|
|
156
|
-
if (m[
|
|
157
|
-
const kind = m[
|
|
158
|
-
const name = m[
|
|
175
|
+
const isPub = Boolean(pubM) || (m[1] === 'fn' && nextFnExposed)
|
|
176
|
+
if (m[1] === 'fn') nextFnExposed = false
|
|
177
|
+
const kind = m[1]
|
|
178
|
+
const name = m[2]
|
|
159
179
|
const doc = docBefore(lines, li)
|
|
160
180
|
|
|
161
181
|
// Витягуємо тіло через findClosingBrace для fn/struct/enum/trait
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/doc-files/lint/lint.mjs
|
|
4
|
+
crc: a30dd81f
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# lint.mjs
|
|
9
|
+
|
|
10
|
+
## Огляд
|
|
11
|
+
|
|
12
|
+
CLI-команда `lint-doc-files` — детермінований детектор застарілості файлових док. Працює без
|
|
13
|
+
мовної моделі скрізь: локально, в hook'ах і в CI.
|
|
14
|
+
|
|
15
|
+
## Поведінка
|
|
16
|
+
|
|
17
|
+
Без прапорців або з переліком шляхів робить повний чи точковий детект і повертає код `1`, якщо є
|
|
18
|
+
застарілі/відсутні доки. `--missing-only` звужує до самих відсутніх. `--json` друкує машинний
|
|
19
|
+
лістинг усіх кандидатів зі станом і завершується кодом `0`. Режими `--hook`, `--git` і
|
|
20
|
+
`--degraded` делегуються детектору hook-протоколу (PostToolUse за одним файлом зі stdin, Stop-гейт
|
|
21
|
+
за зміненими у задачі джерелами з порогом, інформаційний звіт про доки нижчої якості).
|
|
22
|
+
|
|
23
|
+
Повний прогін серіалізується спільним локом під ключем, виведеним зі шляху каталогу, тож паралельні
|
|
24
|
+
запуски не накладаються; hook-форми навмисно виконуються без локу заради завжди-свіжого вердикту.
|
|
25
|
+
|
|
26
|
+
## Публічний API
|
|
27
|
+
|
|
28
|
+
`runLintDocFilesCli` — точка входу команди: маршрутизує між делегатом hook-протоколу, JSON-лістингом
|
|
29
|
+
і повним/точковим детектом; повертає код виходу.
|
|
30
|
+
`runLintDocFilesSteps` — сама робота повного чи точкового детекту, придатна для прямого виклику з
|
|
31
|
+
тестів без локу; повертає `1` за наявності застарілих док, інакше `0`.
|
|
32
|
+
|
|
33
|
+
## Гарантії поведінки
|
|
34
|
+
|
|
35
|
+
- Неіснуючий корінь дає зрозумілу помилку і код `1`.
|
|
36
|
+
- Повний прогін — код `1` (конвенція `lint-*`); hook/git — код `2` (blocking feedback для Claude Code).
|
|
37
|
+
- Жодних викликів мовної моделі.
|