@nitra/cursor 3.27.0 → 3.29.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/CHANGELOG.md +17 -0
- package/package.json +1 -3
- package/rules/abie/js/applies.mjs +1 -5
- package/rules/abie/js/env_dns.mjs +1 -9
- package/rules/abie/js/firebase_hosting.mjs +1 -5
- package/rules/abie/js/hc_pairing.mjs +1 -8
- package/rules/abie/js/ua_http_route.mjs +1 -10
- package/rules/abie/js/ua_node_selector.mjs +1 -8
- package/rules/adr/js/hooks.mjs +1 -20
- package/rules/bun/js/layout.mjs +1 -19
- package/rules/capacitor/js/platforms.mjs +1 -23
- package/rules/changelog/js/consistency.mjs +1 -29
- package/rules/ci4/js/marksman_config.mjs +1 -19
- package/rules/docker/js/lint.mjs +1 -34
- package/rules/ga/docs/fix.md +4 -4
- package/rules/ga/js/docs/lint.md +3 -3
- package/rules/ga/js/docs/workflows.md +14 -14
- package/rules/ga/js/workflows.mjs +1 -16
- package/rules/ga/lint/docs/lint.md +9 -9
- package/rules/graphql/js/tooling.mjs +1 -9
- package/rules/hasura/js/internal_urls.mjs +1 -24
- package/rules/image-avif/js/avif_generation.mjs +1 -27
- package/rules/image-compress/js/package_setup.mjs +1 -18
- package/rules/js-bun-db/js/safety.mjs +1 -31
- package/rules/js-bun-redis/js/imports.mjs +1 -12
- package/rules/js-lint/js/docs/lint-findings.md +30 -0
- package/rules/js-lint/js/lint-findings.mjs +1 -7
- package/rules/js-lint/js/lint.mjs +1 -10
- package/rules/js-lint/js/tooling.mjs +1 -13
- package/rules/js-lint/js/utils_imports.mjs +1 -18
- package/rules/js-lint-ci/js/lint.mjs +1 -6
- package/rules/js-mssql/js/deps.mjs +1 -10
- package/rules/js-run/js/runtime.mjs +1 -37
- package/rules/js-run/lib/docs/temporal-scan.md +25 -0
- package/rules/k8s/js/manifests.mjs +1 -137
- package/rules/nginx-default-tpl/js/template.mjs +1 -18
- package/rules/npm-module/js/docs/header_doc_pointer.md +25 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +82 -0
- package/rules/npm-module/js/package_structure.mjs +1 -28
- package/rules/npm-module/js/rule_meta.mjs +1 -10
- package/rules/npm-module/js/skill_meta.mjs +1 -13
- package/rules/php/js/tooling.mjs +1 -11
- package/rules/python/js/applies.mjs +1 -8
- package/rules/python/js/tooling.mjs +1 -21
- package/rules/rego/js/applies.mjs +1 -11
- package/rules/rust/js/applies.mjs +1 -7
- package/rules/security/js/sample_secret.mjs +1 -28
- package/rules/security/js/trufflehog.mjs +1 -8
- package/rules/style-lint/js/lint.mjs +1 -5
- package/rules/style-lint/js/tooling.mjs +1 -19
- package/rules/tauri/js/cargo_mutants_config.mjs +1 -20
- package/rules/tauri/js/tooling.mjs +1 -21
- package/rules/test/js/cargo_mutants_config.mjs +1 -12
- package/rules/test/js/location.mjs +1 -9
- package/rules/test/js/no-process-chdir.mjs +1 -21
- package/rules/test/js/no-relative-fs-path.mjs +1 -23
- package/rules/test/js/stryker_config.mjs +4 -25
- package/rules/test/js/vitest-config-pool-forks.mjs +1 -17
- package/rules/text/js/forbidden-prettier.mjs +1 -10
- package/rules/text/js/formatting.mjs +1 -31
- package/rules/vue/js/packages.mjs +1 -24
- package/scripts/coverage-classify/index.mjs +60 -72
- package/scripts/coverage-fix.mjs +26 -23
- package/scripts/dispatcher/lib/subagent-runner.mjs +33 -102
- package/scripts/docs/coverage-fix-extract.md +32 -0
- package/scripts/docs/lint-cli.md +25 -0
- package/scripts/docs/post-tool-use-fix.md +27 -0
- package/scripts/docs/rename-yaml-extensions.md +36 -0
- package/scripts/docs/skills-cli.md +35 -0
- package/scripts/docs/sync-claude-config.md +52 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +26 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +29 -0
- package/scripts/docs/worktree-cli.md +46 -0
- package/scripts/lib/docs/assert-project-root.md +28 -0
- package/scripts/lib/docs/diff-added-lines.md +34 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +28 -0
- package/scripts/lib/docs/resolve-target-files.md +34 -0
- package/scripts/lib/docs/root-notice.md +28 -0
- package/scripts/lib/docs/rule-meta-helpers.md +34 -0
- package/scripts/lib/docs/rule-meta.md +34 -0
- package/scripts/lib/docs/rule-predicates.md +30 -0
- package/scripts/lib/docs/run-conftest-batch.md +26 -0
- package/scripts/lib/docs/run-lint-step.md +25 -0
- package/scripts/lib/docs/run-rule-cli.md +27 -0
- package/scripts/lib/docs/run-rule.md +32 -0
- package/scripts/lib/docs/run-standard-lint.md +22 -0
- package/scripts/lib/docs/run-standard-rule.md +24 -0
- package/scripts/lib/docs/skill-meta.md +31 -0
- package/scripts/lib/docs/sync-gitignore-worktree.md +31 -0
- package/scripts/lib/docs/template.md +40 -0
- package/scripts/lib/docs/timing-summary.md +24 -0
- package/scripts/lib/docs/workspaces.md +30 -0
- package/scripts/lib/docs/worktree-notice.md +27 -0
- package/scripts/lib/docs/worktree.md +38 -0
- package/scripts/utils/docs/ast-scan-utils.md +50 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +28 -0
- package/scripts/utils/docs/find-package-json-paths.md +26 -0
- package/scripts/utils/docs/lock-cache-dir.md +25 -0
- package/scripts/utils/docs/pass.md +25 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +23 -0
- package/scripts/utils/docs/resolve-cmd.md +29 -0
- package/scripts/utils/docs/resolve-js-root.md +25 -0
- package/scripts/utils/docs/test-helpers.md +36 -0
- package/scripts/utils/docs/walk-cache.md +27 -0
- package/scripts/utils/docs/walkDir.md +32 -0
- package/scripts/utils/docs/with-lock.md +25 -0
- package/scripts/utils/docs/worktree-fingerprint.md +27 -0
- package/skills/docgen/js/docgen-batch.mjs +95 -0
- package/skills/docgen/js/docgen-extract.mjs +33 -18
- package/skills/docgen/js/docgen-gen.mjs +140 -154
- package/skills/docgen/js/docgen-ignore.mjs +1 -6
- package/skills/docgen/js/docgen-prompts.mjs +33 -22
- package/skills/docgen/js/docgen-scan.mjs +1 -8
- package/skills/docgen/js/docs/docgen-extract.md +28 -0
- package/skills/docgen/js/docs/docgen-gen.md +41 -0
- package/skills/docgen/js/docs/docgen-ignore.md +24 -0
- package/skills/docgen/js/docs/docgen-prompts.md +24 -0
- package/skills/docgen/js/docs/docgen-scan.md +48 -0
- package/skills/fix/js/docs/llm-worker.md +27 -0
- package/skills/fix/js/docs/orchestrator.md +32 -0
- package/skills/fix/js/docs/t0.md +29 -0
- package/skills/fix/js/llm-worker.mjs +64 -29
- package/skills/fix/js/orchestrator.mjs +45 -54
- package/skills/fix/js/t0.mjs +16 -32
- package/skills/start-check/js/check.mjs +1 -16
- package/skills/start-check/js/docs/check.md +34 -0
- package/skills/taze/js/diff.mjs +1 -15
- package/skills/taze/js/docs/diff.md +33 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# ast-scan-utils.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл містить утиліти для AST-сканерів JavaScript та TypeScript, що використовуються для аналізу коду та виявлення потенційних проблем. Він надає інструменти для обробки AST, перетворення даних та взаємодії з різними типами вузлів, забезпечуючи основу для створення правил безпеки та аналізу коду. Ці утиліти спрощують розробку сканерів, усуваючи необхідність повторного написання boilerplate-коду.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
langFromPath: Визначає мову (js, jsx, ts, tsx) на основі розширення файлу.
|
|
10
|
+
offsetToLine: Перетворює байтове зміщення в номер рядка для текстового файлу.
|
|
11
|
+
normalizeSnippet: Стискає текстовий фрагмент до 180 символів, видаляючи пробіли.
|
|
12
|
+
isFunctionNode: Визначає, чи є вузол AST функцією (FunctionDeclaration, FunctionExpression, ArrowFunctionExpression).
|
|
13
|
+
walkAstWithAncestors: Рекурсивно обходить AST, збираючи предки вузла.
|
|
14
|
+
parseProgramOrNull: Парсує файл JS/TS та повертає програму або null, якщо є помилки.
|
|
15
|
+
parseProgramAndCommentsOrNull: Парсує файл JS/TS та повертає програму та список коментарів, або null, якщо є помилки.
|
|
16
|
+
isJoinCall: Визначає, чи є виклик `join` у TemplateLiteral.
|
|
17
|
+
templateQuasisText: Збирає текст quasis з TemplateLiteral.
|
|
18
|
+
isSqlListContextTemplate: Визначає, чи є TemplateLiteral контекстом SQL-списку (IN/VALUES).
|
|
19
|
+
requireCallModule: Витягує ім'я модуля з аргументу виклику `require`.
|
|
20
|
+
dynamicImportModule: Витягує ім'я модуля з аргументу виклику `import`.
|
|
21
|
+
|
|
22
|
+
## Публічний API
|
|
23
|
+
|
|
24
|
+
- langFromPath — Визначає мову Oxc на основі розширення файлу.
|
|
25
|
+
- offsetToLine — Перетворює зміщення в буфер на номер рядка.
|
|
26
|
+
- normalizeSnippet — Форматує текст повідомлення про порушення, видаляючи зайві пробіли.
|
|
27
|
+
- isFunctionNode — Визначає, чи є вузол у абстрактному синтаксичному дереві (AST) функцією.
|
|
28
|
+
- walkAstWithAncestors — Рекурсивно обходить AST, враховуючи контекст (чи знаходиться вузол всередині функції).
|
|
29
|
+
- parseProgramOrNull — Парсить файл та повертає AST, якщо успішно, або `null` у разі помилки.
|
|
30
|
+
- parseProgramAndCommentsOrNull — Парсить файл та повертає об'єкт з AST та коментарями, або `null` у разі помилки.
|
|
31
|
+
- isJoinCall — Визначає, чи є виклик `.join` (для динамічних списків SQL).
|
|
32
|
+
- templateQuasisText — Витягує текст з `quasis` у `TemplateLiteral`, ігноруючи вирази.
|
|
33
|
+
- isSqlListContextTemplate — Визначає, чи є `TemplateLiteral` контекстом SQL-списку (наприклад, `IN` або `VALUES`).
|
|
34
|
+
- requireCallModule — Перевіряє, чи є виклик `require` з рядковим ім'ям.
|
|
35
|
+
|
|
36
|
+
## Гарантії поведінки
|
|
37
|
+
|
|
38
|
+
- `langFromPath` повертає назву мови JavaScript або TypeScript на основі розширення файлу.
|
|
39
|
+
- `langFromPath` повертає `null`, якщо розширення файлу не підтримується.
|
|
40
|
+
- `offsetToLine` перетворює зміщення в коді на номер рядка.
|
|
41
|
+
- `offsetToLine` повертає `null`, якщо зміщення недійсне.
|
|
42
|
+
- `normalizeSnippet` стискає текст сніпета.
|
|
43
|
+
- `normalizeSnippet` повертає `null`, якщо не вдалося стиснути сніпет.
|
|
44
|
+
- `isFunctionNode` визначає, чи є вузол AST функцією.
|
|
45
|
+
- `isFunctionNode` повертає `true` якщо вузол є функцією, інакше `false`.
|
|
46
|
+
- `walkAstWithAncestors` обходить AST, враховуючи предки вузлів.
|
|
47
|
+
- `walkAstWithAncestors` не повертає значень.
|
|
48
|
+
- `parseProgramOrNull` парсує програму та повертає її як AST або `null`, якщо парсинг не вдається.
|
|
49
|
+
- `parseProgramOrNull` повертає `null`, якщо програма не може бути успішно розпарсена.
|
|
50
|
+
- `parseProgramAndCommentsOrNull` парсує програму
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ensure-gitignore-entries.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей модуль відповідає за оновлення файлу `.gitignore` у корені проєкту. Він забезпечує idempotent додавання нових правил ігнорування, перевіряючи їхню наявність перед доповненням. Це необхідно для підтримки консистентності правил ігнорування в проєкті та інтеграції з інструментами тестування, такими як Stryker.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Отримує вхідні дані: каталог проєкту, список шаблонів для `.gitignore`, такий же заголовок для коментаря.
|
|
10
|
+
2. Перевіряє наявність `.gitignore` у вказаному каталозі.
|
|
11
|
+
3. Якщо `.gitignore` відсутній, створює новий файл з порожнім вмістом.
|
|
12
|
+
4. Зчитує вміст `.gitignore` (якщо він існує).
|
|
13
|
+
5. Розбиває вміст `.gitignore` на окремі рядки, видаляє пробіли на початку та в кінці кожного рядка.
|
|
14
|
+
6. Перетворює отримані рядки у набір (Set) для швидкої перевірки на наявність.
|
|
15
|
+
7. Визначає список шаблонів, яких немає у `.gitignore`.
|
|
16
|
+
8. Якщо список шаблонів, яких немає, порожній, повертає порожній масив доданих шаблонів.
|
|
17
|
+
9. Формує новий рядок для додавання у `.gitignore`. Рядок починається з заголовка, потім додає шаблони з порожнього списку, і завершується символом нового рядка.
|
|
18
|
+
10. Додає сформований рядок до вмісту `.gitignore`.
|
|
19
|
+
11. Записує змінений вміст `.gitignore` назад у файл.
|
|
20
|
+
12. Повертає список шаблонів, які були додані до `.gitignore`.
|
|
21
|
+
|
|
22
|
+
## Гарантії поведінки
|
|
23
|
+
|
|
24
|
+
- Якщо файл `.gitignore` існує, то записи додаються лише якщо вони відсутні.
|
|
25
|
+
- Якщо файл `.gitignore` не існує, то створюється новий файл `.gitignore` з доданими записами та header-коментарем.
|
|
26
|
+
- Записи додаються лише після видалення будь-яких пробілів з початку та кінця кожного запису.
|
|
27
|
+
- Якщо запис вже присутній у файлі `.gitignore`, то він не буде доданий повторно.
|
|
28
|
+
- Кеш не використовується.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# find-package-json-paths.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл забезпечує спільну утиліту для збору всіх файлів `package.json` у дереві проєкту, ігноруючи вказані каталоги. Він сортує знайдені шляхи пакетів за відносним розташуванням, що полегшує їх подальше використання в скриптах перевірки. Це дозволяє уникнути дублювання коду з інших інструментів перевірки та спрощує процес збору інформації про залежності.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Отримує абсолютний шлях до кореня репозиторію та список абсолютних шляхів каталогів, які потрібно ігнорувати.
|
|
10
|
+
2. Ініціалізує порожній масив для зберігання шляхів до файлів `package.json`.
|
|
11
|
+
3. Використовує обхід каталогу, починаючи з кореня репозиторію, для пошуку файлів `package.json`.
|
|
12
|
+
4. Для кожного файлу `package.json` у каталозі, перевіряє, чи він відповідає критеріям включення (не знаходиться в ігнорованих каталогах).
|
|
13
|
+
5. Якщо файл відповідає критеріям, додає його абсолютний шлях до масиву шляхів.
|
|
14
|
+
6. Після завершення обходу каталогу, сортує масив шляхів до файлів `package.json` за відносним шляхом відносно кореня репозиторію.
|
|
15
|
+
7. Повертає відсортований масив абсолютних шляхів до файлів `package.json`.
|
|
16
|
+
|
|
17
|
+
## Публічний API
|
|
18
|
+
|
|
19
|
+
- findAllPackageJsonPaths — Знаходить всі файли `package.json` в каталозі та підкаталогах.
|
|
20
|
+
|
|
21
|
+
## Гарантії поведінки
|
|
22
|
+
|
|
23
|
+
- Функція повертає масив рядків, що представляють відносні шляхи до всіх `package.json` файлів, знайдених у дереві.
|
|
24
|
+
- Функція ігнорує каталоги, перелічені в аргументі `walkDir`.
|
|
25
|
+
- Функція не гарантує, що `package.json` файли будуть доступні.
|
|
26
|
+
- Функція не використовує кешування.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# lock-cache-dir.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл визначає структуру каталогу кешування блоків для git-worktree, забезпечуючи унікальний стан локу для кожного головного checkout та пов'язаних worktree. Він використовується для серіалізації запуску інструментів аналізу коду в різних worktree, запобігаючи конфліктам та забезпечуючи ефективну роботу. Створена структура кешування гарантує, що всі worktree мають доступ до одного і того ж стану локу, що необхідно для коректної серіалізації процесів аналізу.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Визначається ключ локу, що представляє конкретну задачу або конфігурацію.
|
|
10
|
+
2. Визначається робоча директорія, яка використовується для виконання операцій.
|
|
11
|
+
3. Використовується команда `git rev-parse --git-common-dir` для визначення спільного каталогу `.git`. Якщо команда успішна, отримується абсолютний шлях до каталогу `.git`. Якщо команда не вдалася, то цей шлях не визначено.
|
|
12
|
+
4. Якщо спільний каталог `.git` визначено, то обчислюється шлях до директорії стану локу, використовуючи спільний каталог, назву ключа та префікс `n-cursor`.
|
|
13
|
+
5. Якщо спільний каталог `.git` не визначено, то обчислюється шлях до директорії стану локу, використовуючи робочу директорію та префікс `node_modules/.cache/n-cursor`.
|
|
14
|
+
6. Повертається обчислений абсолютний шлях до директорії стану локу.
|
|
15
|
+
|
|
16
|
+
## Гарантії поведінки
|
|
17
|
+
|
|
18
|
+
- Спільний лок-стан для всіх git-worktree визначається шляхом `<git-common-dir>/n-cursor/<key>`.
|
|
19
|
+
- Якщо git недоступний, використовується кеш `node_modules/.cache/n-cursor/<key>`.
|
|
20
|
+
- Кеш використовується для збереження стану протягом одного прогону.
|
|
21
|
+
- Стан локу (`lock/owner.json`, `result.json`) є унікальним для кожного головного checkout та всіх linked-worktree.
|
|
22
|
+
- Унікальний стан локу запобігає паралельній роботі інструментів серіалізації.
|
|
23
|
+
- Унікальний стан локу гарантує, що кожен worktree має власний `node_modules/.cache/`.
|
|
24
|
+
- Кеш не відстежується git.
|
|
25
|
+
- Кеш не впливає на стан локу.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# pass.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл містить функцію для виведення повідомлень про успіх у консоль. Функція використовується в скриптах перевірки для інформування користувача про успішне завершення операцій. Вона забезпечує чіткий візуальний сигнал про успіх, що полегшує інтерпретацію результатів перевірки.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Викликається функція `pass`.
|
|
10
|
+
2. Функція `pass` друкує рядок у консоль.
|
|
11
|
+
3. Рядок починається з символу галочки (✅).
|
|
12
|
+
4. Після символу галочки друкується переданий текст повідомлення.
|
|
13
|
+
5. Функція не має жодного впливу на стан системи.
|
|
14
|
+
6. Функція не взаємодіє з будь-якими зовнішніми ресурсами.
|
|
15
|
+
|
|
16
|
+
## Публічний API
|
|
17
|
+
|
|
18
|
+
- pass: Допоміжна функція для скриптів перевірки.
|
|
19
|
+
Друкує в консоль рядок успіху з галочкою (✅).
|
|
20
|
+
|
|
21
|
+
## Гарантії поведінки
|
|
22
|
+
|
|
23
|
+
- Виводить у консоль рядок із символом ✅.
|
|
24
|
+
- Не виконує жодних операцій.
|
|
25
|
+
- Не використовує жодного кешу.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# resolve-cargo-manifest.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл визначає шлях до файлу Cargo.toml проєкту, незалежно від того, чи це кореневий Cargo.toml або один з підкаталогів workspace-у, особливо з урахуванням Tauri-патерну. Він служить утилітою для coverage-провайдера та test-концерну cargo_mutants_config, повертаючи `null` у разі невдачі для обробки ситуації без виключень. Це забезпечує гнучкий спосіб доступу до конфігурації проєкту Cargo.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
resolveCargoManifest: Повертає абсолютний шлях до Cargo.toml у проєкті, починаючи з кореня, або в підкаталозі `src-tauri` якщо він існує. Повертає `null`, якщо Cargo.toml не знайдено.
|
|
10
|
+
resolveAllCargoManifests: Повертає масив абсолютних шляхів до всіх знайдених Cargo.toml у проєкті, пріоритет надається `src-tauri` підкаталогам, а потім загальним Cargo.toml. Повертає порожній масив, якщо жодного Cargo.toml не знайдено.
|
|
11
|
+
|
|
12
|
+
## Публічний API
|
|
13
|
+
|
|
14
|
+
- resolveCargoManifest: Отримує інформацію про маніфест Cargo.toml з конкретного каталогу.
|
|
15
|
+
- resolveAllCargoManifests: Знаходить всі файли Cargo.toml в проєкті, починаючи з кореневого каталогу та підкаталогів workspace, повертаючи їх вміст.
|
|
16
|
+
|
|
17
|
+
## Гарантії поведінки
|
|
18
|
+
|
|
19
|
+
- Функція повертає `null` у разі невдачі.
|
|
20
|
+
- Функція не викидає винятки.
|
|
21
|
+
- Функція не використовує кешування.
|
|
22
|
+
- Функція обробляє шляхи до `Cargo.toml` у каталогах `cwd/Cargo.toml` та підкаталогах workspace (`<workspace>/src-tauri/`).
|
|
23
|
+
- Функція не повертає жодного значення, якщо всі шляхи до `Cargo.toml` успішно оброблені.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# resolve-cmd.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл надає функцію `resolveCmd` для отримання абсолютного шляху до виконуваного файлу, який відповідає заданій команді. Це дозволяє викликати зовнішні інструменти, використовуючи повний шлях до файлу, а не команду з змінної PATH. Це корисно для забезпечення чіткої та однозначної ідентифікації виконуваного файлу.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Перевіряє, чи існує команда в змінній PATH системи.
|
|
10
|
+
2. Визначає інструмент для пошуку команди: `where` на Windows та `which` на інших платформах.
|
|
11
|
+
3. Запускає визначений інструмент з командою для пошуку.
|
|
12
|
+
4. Перевіряє код повернення інструменту. Якщо код не 0 або є помилка, команда не знайдена, повертає `null`.
|
|
13
|
+
5. Якщо команда знайдена, витягує перший рядок результату.
|
|
14
|
+
6. Видаляє пробіли з рядка.
|
|
15
|
+
7. Повертає витягнутий рядок як абсолютний шлях до команди. Якщо рядок порожній, повертає `null`.
|
|
16
|
+
|
|
17
|
+
## Публічний API
|
|
18
|
+
|
|
19
|
+
resolveCmd — Знаходить шлях до виконуваного файлу команди в системному PATH та повертає його. Якщо команда не знайдена, повертає null.
|
|
20
|
+
|
|
21
|
+
## Гарантії поведінки
|
|
22
|
+
|
|
23
|
+
- Функція повертає абсолютний шлях до команди, якщо вона знайдена в змінних середовища PATH.
|
|
24
|
+
- Якщо команда не знайдена в PATH, функція повертає `null`.
|
|
25
|
+
- Функція не викидає винятки у разі невдачі.
|
|
26
|
+
- Функція не використовує жодного кешу.
|
|
27
|
+
- Функція не гарантує, що команда доступна.
|
|
28
|
+
- Функція не гарантує, що команда працює.
|
|
29
|
+
- Функція не гарантує, що команда безпечна для використання.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# resolve-js-root.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл визначає кореневий JavaScript-файл проєкту, необхідний для запуску інструментів аналізу коду. Він використовується як у великих проєктах з декількома workspace-ами, так і в окремих пакетах, забезпечуючи єдине місце для визначення кореневого розташування. Це спрощує інтеграцію з інструментами coverage та тестування.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
resolveJsRoot: повертає абсолютний шлях до першого JS-кореня проєкту.
|
|
10
|
+
resolveAllJsRoots: повертає масив абсолютних шляхів до всіх JS-коренів проєкту, враховуючи glob-патерни з `workspaces` у кореневому `package.json`. Якщо JS-коренів немає, повертає абсолютний шлях до кореневого каталогу.
|
|
11
|
+
|
|
12
|
+
## Публічний API
|
|
13
|
+
|
|
14
|
+
- resolveJsRoot — Знаходить кореневий JS-файл проєкту.
|
|
15
|
+
- resolveAllJsRoots — Знаходить всі кореневі JS-файли проєкту. Включає всі workspace-файли та їхні `package.json`, використовуючи glob-патерни. Для single-package повертає поточну директорію.
|
|
16
|
+
|
|
17
|
+
## Гарантії поведінки
|
|
18
|
+
|
|
19
|
+
- Повертає `true`, якщо кореневий JS-файл знайдено.
|
|
20
|
+
- Повертає `false`, якщо кореневий JS-файл не знайдено.
|
|
21
|
+
- Повертає `null`, якщо не вдалося визначити кореневий JS-файл.
|
|
22
|
+
- Не обробляє помилки, а повертає `false` або `null`.
|
|
23
|
+
- Ігнорує директорії `.git` та `node_modules`.
|
|
24
|
+
- Не використовує кешування.
|
|
25
|
+
- Не здійснює мережевих запитів.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# test-helpers.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл надає допоміжні функції для тестування скриптів пакета `@nitra/cursor`. Він забезпечує створення тимчасових каталогів та запис JSON-файлів у абсолютний шлях, гарантуючи ізольованість тестів та запобігаючи мутації глобального контексту процесу. Ці функції використовуються для створення безпечного середовища для тестування, особливо при використанні git-операцій та інших файлових операцій.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
withTmpDir: Створює тимчасову директорію та виконує функцію з її абсолютним шляхом, потім видаляє директорію.
|
|
10
|
+
writeJson: Записує JSON-файл в абсолютний шлях, форматує його та додає символ переносу рядка.
|
|
11
|
+
ensureDir: Створює вкладену директорію в заданому абсолютному шляху.
|
|
12
|
+
withShellcheckStubInPath: Створює тимчасову директорію з підставленим `shellcheck` (якщо платформа Windows), додає її до `PATH`, виконує функцію, а потім відновлює оригінальний `PATH` та видаляє тимчасову директорію.
|
|
13
|
+
withBinRemovedFromPath: Видаляє заданий виконуваний файл з `PATH`, виконує функцію, а потім відновлює оригінальний `PATH` та встановлює `N_CURSOR_NO_AUTO_INSTALL=1`.
|
|
14
|
+
|
|
15
|
+
## Публічний API
|
|
16
|
+
|
|
17
|
+
- withTmpDir — Створює тимчасову директорію та передає її шлях у `fn`, потім видаляє директорію.
|
|
18
|
+
- writeJson — Записує JSON-файл з форматуванням.
|
|
19
|
+
- ensureDir — Створює вкладені каталоги.
|
|
20
|
+
- withShellcheckStubInPath — Створює тимчасовий каталог із `shellcheck`, додає його на `PATH` та відновлює оригінальний `PATH`.
|
|
21
|
+
- withBinRemovedFromPath — Виконує `fn` з `PATH`, з якого видалено каталоги з `<bin>`.
|
|
22
|
+
- N_CURSOR_NO_AUTO_INSTALL — Встановлює прапорець для запобігання автоматичному встановленню інструментів.
|
|
23
|
+
|
|
24
|
+
## Гарантії поведінки
|
|
25
|
+
|
|
26
|
+
- `withTmpDir` створює тимчасовий каталог і передає його абсолютний шлях у функцію `fn`.
|
|
27
|
+
- `writeJson` записує об'єкт `data` у файл JSON в абсолютний шлях каталогу `dir`.
|
|
28
|
+
- `ensureDir` створює каталог `dir`, якщо він не існує.
|
|
29
|
+
- `withShellcheckStubInPath` встановлює stub Shellcheck у каталозі `dir`.
|
|
30
|
+
- `withBinRemovedFromPath` видаляє біни з шляху `dir`.
|
|
31
|
+
- Абсолютний шлях каталогу тимчасового каталогу, створеного `withTmpDir`, завжди доступний для використання.
|
|
32
|
+
- Функції не кидають винятків. У разі помилки, функція завершується з помилкою.
|
|
33
|
+
- Немає кешування.
|
|
34
|
+
- Не використовується `process.chdir`.
|
|
35
|
+
- `process.cwd` встановлюється на абсолютний шлях тимчасового каталогу.
|
|
36
|
+
- Всі child-процеси отримують абсолютний шлях тимчасового каталогу через `cwd`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# walk-cache.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Файл забезпечує спільний кеш результатів обходу файлової системи для всіх операцій перевірки. Він зберігає список файлів, що відповідають заданим шаблонам, щоб уникнути повторних обходів. Це підвищує ефективність процесу перевірки, особливо при великій кількості файлів та шаблонів.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
getOrCreateWalkCache: Створює або повертає кеш.
|
|
10
|
+
resetWalkCache: Скидає кеш.
|
|
11
|
+
|
|
12
|
+
## Публічний API
|
|
13
|
+
|
|
14
|
+
- getOrCreateWalkCache — Створює або повертає cache, ініціалізує його при першому використанні.
|
|
15
|
+
- resetWalkCache — Очищає cache.
|
|
16
|
+
|
|
17
|
+
## Гарантії поведінки
|
|
18
|
+
|
|
19
|
+
- Кеш існує лише в межах одного процесу.
|
|
20
|
+
- Кеш скидається при виклику `resetWalkCache`.
|
|
21
|
+
- Кеш зберігає список файлів, отриманий в результаті прогону.
|
|
22
|
+
- Значення кешу – `Promise<string[]>`.
|
|
23
|
+
- Кеш використовується для обробки glob/regex дескрипторів.
|
|
24
|
+
- Кеш не використовується для взаємодії з мережею.
|
|
25
|
+
- Кеш зберігає дані лише протягом одного прогону.
|
|
26
|
+
- Кеш не гарантує наявності файлів, що відповідають дескрипторам.
|
|
27
|
+
- Кеш не гарантує порядку файлів у списку.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# walkDir.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Файл `n-cursor.js` забезпечує рекурсивний обхід каталогів для скриптів перевірки, дозволяючи виконувати callback-функцію для кожного звичайного файлу. Він обходить дерево каталогів від заданого кореня, ігноруючи певні директорії (наприклад, `.git`, `node_modules`) та шляхи, вказані в `ignorePaths`. Це дозволяє автоматизувати процес аналізу конфігураційних файлів та інших ресурсів у проєкті.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Починається з заданого кореневого каталогу.
|
|
10
|
+
2. Для кожного підкаталогу в кореневому каталозі:
|
|
11
|
+
2.1. Перевіряє, чи є підкаталог у списку `ignorePaths`. Якщо так, пропускає обхід цього підкаталогу та його вмісту.
|
|
12
|
+
2.2. Якщо підкаталог не в списку `ignorePaths`, обробляє вміст підкаталогу:
|
|
13
|
+
2.2.1. Для кожного файлу в підкаталозі, викликає функцію `onFile` з шляхом до файлу.
|
|
14
|
+
2.2.2. Для кожного підкаталогу в підкаталозі, рекурсивно викликає функцію `walkDir` для обходу цього підкаталогу. Під час рекурсивного виклику, також перевіряє, чи є підкаталог у списку `ignorePaths`.
|
|
15
|
+
3. Не обробляє каталоги `node_modules`, `.git`, `dist`, `coverage`, `.turbo` та `.next`.
|
|
16
|
+
4. Якщо при спробі `readdir` для каталогу виникає помилка, обхід цього каталогу припиняється.
|
|
17
|
+
5. Обхід завершується, коли всі підкаталоги та файли в заданому дереві були оброблені.
|
|
18
|
+
|
|
19
|
+
## Публічний API
|
|
20
|
+
|
|
21
|
+
- walkDir — Обходить каталог рекурсивно, ігноруючи вказані шляхи.
|
|
22
|
+
|
|
23
|
+
## Гарантії поведінки
|
|
24
|
+
|
|
25
|
+
- Функція рекурсивно обходить дерево каталогів, починаючи з заданого кореня.
|
|
26
|
+
- Для кожного звичайного файлу викликається переданий callback.
|
|
27
|
+
- Не обходить каталоги `node_modules`, `.git`, `dist`, `coverage`, `.turbo`, `.next`.
|
|
28
|
+
- Може пропустити каталоги, вказані в `ignorePaths`.
|
|
29
|
+
- У разі невдачі `readdir` для каталогу, функція тихо виходить без викидання помилок.
|
|
30
|
+
- Функція не викидає винятки назовні.
|
|
31
|
+
- У разі невдачі повертає `false` або `null`.
|
|
32
|
+
- Не використовує кешування.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# with-lock.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл реалізує механізм захисту від одночасного виконання критичних операцій, забезпечуючи атомарний lock та дедуплікацію даних для інтенсивних команд. Він використовується для запобігання конфліктів при одночасному виконанні операцій, які можуть призвести до пошкодження даних або непередбачуваних результатів. Механізм гарантує, що кожен прогін операцій виконується без повторень та з атомарним lock.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
- `shouldDedup`: Перевіряє, чи можна повторно використати кешований результат, враховуючи код виходу, відбитковий дерева та час завершення.
|
|
10
|
+
- `withLock`: Встановлює lock-директорію, запускає вказану функцію, кешує результат та повторно використовує його, якщо можливо, з використанням дедуплікації за відбитком.
|
|
11
|
+
|
|
12
|
+
## Публічний API
|
|
13
|
+
|
|
14
|
+
- shouldDedup — Перевіряє, чи можна використовувати попередньо обчислену відповідь для уникнення повторних обчислень.
|
|
15
|
+
- withLock — Забезпечує унікальність виконання важкої операції за допомогою блокування та перевірки на основі відбитків.
|
|
16
|
+
|
|
17
|
+
## Гарантії поведінки
|
|
18
|
+
|
|
19
|
+
- **Атомарність:** Операції lock та dedup виконуються як атомарні дії.
|
|
20
|
+
- **Захист від помилок:** У разі виникнення помилки, функція повертає `false` та `null`.
|
|
21
|
+
- **Детектування неактивного PID:** Перевіряється, чи процес, що утримує lock, все ще активний.
|
|
22
|
+
- **Дедуплікація з обмеженням часу:** Проводиться дедуплікація за допомогою SHA256 з обмеженням часу (TTL).
|
|
23
|
+
- **Кешування:** Результати прогону кешуються для прискорення наступних проходів.
|
|
24
|
+
- **Відсутність винятків:** Функції не викликають винятків.
|
|
25
|
+
- **Створення директорій:** Використовується `mkdirSync` для створення директорій.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# worktree-fingerprint.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Файл надає унікальний відбиток робочої директорії. Цей відбиток використовується для ідентифікації та порівняння робочих директорій, забезпечуючи їх унікальність у системі. Він слугує базовим інструментом для відстеження та управління версіями.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
1. Отримує поточний SHA256 хеш коміту, який знаходиться в гілці HEAD.
|
|
10
|
+
2. Отримує текст зміни між комітом HEAD та робочим каталогом.
|
|
11
|
+
3. Отримує список не відстежених файлів у робочому каталозі, не включаючи стандартні файли, що ігноруються.
|
|
12
|
+
4. Для кожного не відстеженого файлу отримує його SHA256 хеш.
|
|
13
|
+
5. Об'єднує SHA256 хеш коміту, текст зміни та пари "файл:хеш" не відстежених файлів, розділяючи їх новими рядками.
|
|
14
|
+
6. Обчислює SHA256 хеш отриманого текстового рядка.
|
|
15
|
+
7. Повертає отриманий SHA256 хеш у форматі 64-значної шестнадцяткової строки.
|
|
16
|
+
8. Якщо виникає помилка під час виконання будь-якої з операцій, повертає `null`.
|
|
17
|
+
|
|
18
|
+
## Публічний API
|
|
19
|
+
|
|
20
|
+
worktreeFingerprint — генерує унікальний відбиток поточного стану репозиторію Git.
|
|
21
|
+
|
|
22
|
+
## Гарантії поведінки
|
|
23
|
+
|
|
24
|
+
- Функція повертає `true`, якщо відбиток дерева робіт успішно обчислено.
|
|
25
|
+
- Функція повертає `null`, якщо обчислення відбитка дерева робіт не вдалося.
|
|
26
|
+
- Функція не викликає винятків.
|
|
27
|
+
- Функція не використовує кеш.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch docgen для відсутніх файлів проєкту.
|
|
3
|
+
* sym < 4 → gemma3:4b orchestrated (local)
|
|
4
|
+
* sym ≥ 4 → Claude Sonnet (cloud, via generateDoc pre-routing)
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
7
|
+
import { dirname, join, resolve } from 'node:path'
|
|
8
|
+
import { fileURLToPath } from 'node:url'
|
|
9
|
+
import { generateDoc } from './docgen-gen.mjs'
|
|
10
|
+
import { extractFacts } from './docgen-extract.mjs'
|
|
11
|
+
import { execSync } from 'node:child_process'
|
|
12
|
+
|
|
13
|
+
const ROOT = resolve(fileURLToPath(import.meta.url), '../../../../..')
|
|
14
|
+
|
|
15
|
+
// 1. Отримати список відсутніх файлів
|
|
16
|
+
const scanOut = execSync('node npm/bin/n-cursor.js docgen scan', { cwd: ROOT, encoding: 'utf8' })
|
|
17
|
+
const allFiles = JSON.parse(scanOut)
|
|
18
|
+
const missing = allFiles.filter(x => !x.exists)
|
|
19
|
+
|
|
20
|
+
console.log(`\n📋 Файлів для генерації: ${missing.length}`)
|
|
21
|
+
|
|
22
|
+
// 2. Розкласти по тирах
|
|
23
|
+
const local = [],
|
|
24
|
+
cloud = []
|
|
25
|
+
for (const f of missing) {
|
|
26
|
+
try {
|
|
27
|
+
const src = readFileSync(join(ROOT, f.sourcePath), 'utf8')
|
|
28
|
+
const facts = extractFacts(src, join(ROOT, f.sourcePath))
|
|
29
|
+
const sym = (facts.internalSymbols ?? []).length
|
|
30
|
+
if (sym >= 4) cloud.push({ ...f, sym })
|
|
31
|
+
else local.push({ ...f, sym })
|
|
32
|
+
} catch {
|
|
33
|
+
local.push({ ...f, sym: 0 })
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log(` Local (sym<4): ${local.length}`)
|
|
38
|
+
console.log(` Cloud (sym≥4): ${cloud.length}`)
|
|
39
|
+
|
|
40
|
+
const stats = { ok: 0, err: 0, localOk: 0, cloudOk: 0, errors: [] }
|
|
41
|
+
|
|
42
|
+
// 3. Cloud файли (sym≥4) — generateDoc auto-routes до Claude
|
|
43
|
+
console.log('\n☁️ Cloud tier...')
|
|
44
|
+
for (const f of cloud) {
|
|
45
|
+
const t0 = Date.now()
|
|
46
|
+
try {
|
|
47
|
+
const result = await generateDoc(join(ROOT, f.sourcePath), { symThreshold: 4 })
|
|
48
|
+
const docAbs = join(ROOT, f.docPath)
|
|
49
|
+
mkdirSync(dirname(docAbs), { recursive: true })
|
|
50
|
+
writeFileSync(docAbs, result.md)
|
|
51
|
+
stats.ok++
|
|
52
|
+
stats.cloudOk++
|
|
53
|
+
console.log(` ✓ ${f.sourcePath} (sym=${f.sym}, ${Math.round((Date.now() - t0) / 1000)}s)`)
|
|
54
|
+
} catch (e) {
|
|
55
|
+
stats.err++
|
|
56
|
+
stats.errors.push(f.sourcePath)
|
|
57
|
+
console.error(` ✗ ${f.sourcePath}: ${e.message}`)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 4. Local файли (sym<4) — gemma3:4b orchestrated
|
|
62
|
+
console.log('\n💻 Local tier...')
|
|
63
|
+
let done = 0
|
|
64
|
+
for (const f of local) {
|
|
65
|
+
done++
|
|
66
|
+
const t0 = Date.now()
|
|
67
|
+
const pct = Math.round((done / local.length) * 100)
|
|
68
|
+
process.stdout.write(` [${done}/${local.length} ${pct}%] ${f.sourcePath} ... `)
|
|
69
|
+
try {
|
|
70
|
+
const result = await generateDoc(join(ROOT, f.sourcePath), {
|
|
71
|
+
mode: 'orchestrated',
|
|
72
|
+
symThreshold: 999 // force local
|
|
73
|
+
})
|
|
74
|
+
const docAbs = join(ROOT, f.docPath)
|
|
75
|
+
mkdirSync(dirname(docAbs), { recursive: true })
|
|
76
|
+
writeFileSync(docAbs, result.md)
|
|
77
|
+
stats.ok++
|
|
78
|
+
stats.localOk++
|
|
79
|
+
process.stdout.write(`✓ ${Math.round((Date.now() - t0) / 1000)}s score=${result.score ?? '?'}\n`)
|
|
80
|
+
} catch (e) {
|
|
81
|
+
stats.err++
|
|
82
|
+
stats.errors.push(f.sourcePath)
|
|
83
|
+
process.stdout.write(`✗ ${e.message}\n`)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 5. Підсумок
|
|
88
|
+
console.log(`\n${'─'.repeat(50)}`)
|
|
89
|
+
console.log(`✓ OK: ${stats.ok} ✗ Err: ${stats.err}`)
|
|
90
|
+
console.log(` 💻 Local (gemma3:4b): ${stats.localOk} файлів`)
|
|
91
|
+
console.log(` ☁️ Cloud (Claude/pi): ${stats.cloudOk} файлів`)
|
|
92
|
+
if (stats.errors.length > 0) {
|
|
93
|
+
console.log('Помилки:')
|
|
94
|
+
stats.errors.forEach(e => console.log(` - ${e}`))
|
|
95
|
+
}
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stage 0 docgen-конвеєра: детермінована екстракція «факт-листа» з коду (0 токенів LLM).
|
|
3
|
-
*
|
|
4
|
-
* Ідея: винести з-під локальної моделі все, що вона псує (імена експортів, stdlib-vs-internal,
|
|
5
|
-
* крайові деталі поведінки), і віддати їй лише перефразування вже відомих фактів. Тут — суто
|
|
6
|
-
* парсинг JS/MJS регулярками: жодних мереж, LLM чи запису.
|
|
7
|
-
*
|
|
8
|
-
* Повертає об'єкт-факт-лист, який Stage 1 (docgen-prompts) перетворює на точкові промпти.
|
|
9
|
-
*/
|
|
1
|
+
/** @see ./docs/docgen-extract.md */
|
|
10
2
|
|
|
11
3
|
const BUILTIN_MODULES = new Set([
|
|
12
|
-
'fs',
|
|
13
|
-
'
|
|
4
|
+
'fs',
|
|
5
|
+
'path',
|
|
6
|
+
'crypto',
|
|
7
|
+
'os',
|
|
8
|
+
'util',
|
|
9
|
+
'stream',
|
|
10
|
+
'events',
|
|
11
|
+
'http',
|
|
12
|
+
'https',
|
|
13
|
+
'url',
|
|
14
|
+
'child_process',
|
|
15
|
+
'process',
|
|
16
|
+
'assert',
|
|
17
|
+
'buffer',
|
|
18
|
+
'zlib',
|
|
19
|
+
'readline'
|
|
14
20
|
])
|
|
15
21
|
|
|
16
22
|
/** Прибирає `/** */`-обрамлення й `*`-префікси, повертає чистий текст рядками. */
|
|
@@ -40,7 +46,10 @@ function parseJsDoc(raw) {
|
|
|
40
46
|
params.push({ name: pm[1], desc: desc === 'опис.' ? '' : desc })
|
|
41
47
|
continue
|
|
42
48
|
}
|
|
43
|
-
if (rm) {
|
|
49
|
+
if (rm) {
|
|
50
|
+
ret = rm[1].trim()
|
|
51
|
+
continue
|
|
52
|
+
}
|
|
44
53
|
if (l.startsWith('@')) continue
|
|
45
54
|
descLines.push(l)
|
|
46
55
|
}
|
|
@@ -81,7 +90,9 @@ function extractExports(src) {
|
|
|
81
90
|
|
|
82
91
|
/** Імпорти, класифіковані на stdlib / npm / internal. */
|
|
83
92
|
function extractImports(src) {
|
|
84
|
-
const stdlib = new Set(),
|
|
93
|
+
const stdlib = new Set(),
|
|
94
|
+
npm = new Set(),
|
|
95
|
+
internal = new Set()
|
|
85
96
|
const re = /^import\s+[\s\S]*?from\s+['"]([^'"]+)['"]/gm
|
|
86
97
|
let m
|
|
87
98
|
while ((m = re.exec(src))) {
|
|
@@ -100,10 +111,11 @@ function extractInternalSymbols(src) {
|
|
|
100
111
|
let m
|
|
101
112
|
while ((m = re.exec(src))) {
|
|
102
113
|
if (m[1]) out.add(m[1].trim())
|
|
103
|
-
if (m[2])
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
if (m[2])
|
|
115
|
+
for (const n of m[2].split(',')) {
|
|
116
|
+
const name = n.replace(/\s+as\s+.*/, '').trim()
|
|
117
|
+
if (name) out.add(name)
|
|
118
|
+
}
|
|
107
119
|
}
|
|
108
120
|
return [...out]
|
|
109
121
|
}
|
|
@@ -152,7 +164,10 @@ import { isRunAsCli } from '../../../scripts/cli-entry.mjs'
|
|
|
152
164
|
import { readFileSync } from 'node:fs'
|
|
153
165
|
if (isRunAsCli(import.meta.url)) {
|
|
154
166
|
const file = process.argv[2]
|
|
155
|
-
if (!file) {
|
|
167
|
+
if (!file) {
|
|
168
|
+
console.error('Usage: node docgen-extract.mjs <file>')
|
|
169
|
+
process.exit(1)
|
|
170
|
+
}
|
|
156
171
|
const facts = extractFacts(readFileSync(file, 'utf8'), file)
|
|
157
172
|
console.log(JSON.stringify(facts, null, 2))
|
|
158
173
|
}
|