@nitra/cursor 5.1.0 → 5.2.1
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 +22 -0
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +15 -9
- package/CHANGELOG.md +18 -1
- package/bin/n-cursor.js +73 -16
- package/docs/stryker.config.md +6 -0
- package/docs/vitest.config.md +6 -0
- package/lib/docs/llm.md +29 -0
- package/lib/docs/models.md +24 -17
- package/lib/docs/omlx.md +32 -0
- package/lib/llm.mjs +137 -0
- package/lib/omlx.mjs +49 -4
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +6 -0
- package/rules/abie/js/docs/applies.md +6 -0
- package/rules/abie/js/docs/env_dns.md +25 -22
- package/rules/abie/js/docs/firebase_hosting.md +6 -0
- package/rules/abie/js/docs/hc_pairing.md +21 -25
- package/rules/abie/js/docs/ua_http_route.md +27 -19
- package/rules/abie/js/docs/ua_node_selector.md +24 -19
- package/rules/abie/lib/docs/enabled.md +13 -7
- package/rules/abie/lib/docs/env-dns.md +9 -3
- package/rules/abie/lib/docs/hc-yaml.md +6 -0
- package/rules/abie/lib/docs/http-route.md +6 -0
- package/rules/abie/lib/docs/k8s-tree.md +6 -0
- package/rules/abie/lib/docs/kustomization-patches.md +6 -0
- package/rules/abie/lib/docs/overlay-paths.md +6 -0
- package/rules/abie/lib/docs/yaml.md +6 -0
- package/rules/adr/docs/fix.md +6 -0
- package/rules/adr/js/docs/hooks.md +29 -244
- package/rules/bun/docs/fix.md +6 -0
- package/rules/bun/js/docs/layout.md +37 -375
- package/rules/capacitor/docs/fix.md +22 -108
- package/rules/capacitor/js/docs/platforms.md +62 -268
- package/rules/changelog/docs/fix.md +6 -0
- package/rules/changelog/js/docs/consistency.md +36 -383
- package/rules/changelog/lib/docs/package-manifest.md +6 -0
- package/rules/ci4/docs/fix.md +23 -165
- package/rules/ci4/js/docs/marksman_config.md +9 -1
- package/rules/docker/docs/fix.md +6 -0
- package/rules/docker/js/docs/lint.md +55 -239
- package/rules/docker/lib/docs/docker-hadolint.md +6 -0
- package/rules/docker/lib/docs/docker-mirror.md +6 -0
- package/rules/docker/lib/docs/docker-native-addon.md +6 -0
- package/rules/docker/lib/docs/docker-nginx-user.md +6 -0
- package/rules/docker/lint/docs/lint.md +9 -1
- package/rules/efes/docs/fix.md +6 -0
- package/rules/feedback/docs/fix.md +21 -131
- package/rules/ga/docs/fix.md +14 -12
- package/rules/ga/js/docs/lint.md +12 -9
- package/rules/ga/js/docs/workflows.md +20 -19
- package/rules/ga/lint/docs/lint.md +6 -0
- package/rules/graphql/docs/fix.md +6 -0
- package/rules/graphql/js/docs/tooling.md +18 -253
- package/rules/graphql/lib/docs/graphql-gql-scan.md +6 -0
- package/rules/hasura/docs/fix.md +18 -111
- package/rules/image-avif/docs/fix.md +6 -0
- package/rules/image-avif/js/docs/avif_generation.md +6 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +9 -3
- package/rules/js-bun-redis/lib/docs/redis-imports.md +6 -0
- package/rules/js-lint/js/docs/utils_imports.md +6 -0
- package/rules/js-lint-ci/docs/fix.md +7 -1
- package/rules/js-mssql/docs/fix.md +6 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +6 -0
- package/rules/js-run/docs/fix.md +6 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +6 -0
- package/rules/js-run/lib/docs/check-env-scan.md +6 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +6 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +6 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +6 -0
- package/rules/js-run/lib/docs/temporal-scan.md +6 -0
- package/rules/k8s/docs/fix.md +6 -0
- package/rules/k8s/lint/docs/lint.md +6 -0
- package/rules/nginx-default-tpl/docs/fix.md +6 -0
- package/rules/npm-module/js/docs/header_doc_pointer.md +7 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +2 -8
- package/rules/php/docs/fix.md +6 -0
- package/rules/php/lint/docs/lint.md +6 -0
- package/rules/python/docs/fix.md +6 -0
- package/rules/python/lint/docs/lint.md +6 -0
- package/rules/rego/lint/docs/lint.md +6 -0
- package/rules/release/docs/change.md +6 -0
- package/rules/release/docs/fix.md +6 -0
- package/rules/release/docs/release.md +6 -0
- package/rules/release/lib/docs/aggregate.md +6 -0
- package/rules/release/lib/docs/change-file.md +6 -0
- package/rules/release/lib/docs/fallback.md +6 -0
- package/rules/rust/lib/docs/has-cargo-toml.md +6 -0
- package/rules/security/docs/fix.md +7 -1
- package/rules/security/js/docs/lint.md +6 -0
- package/rules/style-lint/docs/fix.md +6 -0
- package/rules/tauri/docs/fix.md +6 -0
- package/rules/test/docs/fix.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +6 -0
- package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +6 -0
- package/rules/text/docs/fix.md +6 -0
- package/rules/text/lint/docs/lint.md +6 -0
- package/rules/text/lint/docs/run-dotenv-linter.md +6 -0
- package/rules/text/lint/docs/run-shellcheck.md +6 -0
- package/rules/text/lint/docs/run-v8r.md +6 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +6 -0
- package/scripts/coverage-classify/cache.mjs +1 -1
- package/scripts/coverage-classify/docs/apply.md +6 -0
- package/scripts/coverage-classify/docs/cache.md +6 -0
- package/scripts/coverage-classify/docs/prompt.md +6 -0
- package/scripts/coverage-classify/docs/verdict-schema.md +6 -0
- package/scripts/coverage-classify/prompt.mjs +1 -1
- package/scripts/coverage-fix-extract.mjs +1 -1
- package/scripts/coverage-fix.mjs +2 -1
- package/scripts/docs/auto-skills.md +6 -0
- package/scripts/docs/build-agents-commands.md +7 -1
- package/scripts/docs/cli-entry.md +6 -0
- package/scripts/docs/coverage-fix-extract.md +6 -0
- package/scripts/docs/coverage-fix.md +6 -0
- package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +6 -0
- package/scripts/docs/lint-cli.md +6 -0
- package/scripts/docs/post-tool-use-fix.md +6 -0
- package/scripts/docs/rename-yaml-extensions.md +6 -0
- package/scripts/docs/skills-cli.md +6 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +6 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +6 -0
- package/scripts/docs/worktree-cli.md +6 -0
- package/scripts/lib/docs/assert-project-root.md +6 -0
- package/scripts/lib/docs/check-mdc-template-refs.md +6 -0
- package/scripts/lib/docs/check-reporter.md +6 -0
- package/scripts/lib/docs/diff-added-lines.md +6 -0
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +6 -0
- package/scripts/lib/docs/discover-checkable-rules.md +6 -0
- package/scripts/lib/docs/ensure-tool.md +6 -0
- package/scripts/lib/docs/generated-markdown.md +6 -0
- package/scripts/lib/docs/gha-workflow.md +6 -0
- package/scripts/lib/docs/inline-template-links.md +6 -0
- package/scripts/lib/docs/list-rule-ids.md +6 -0
- package/scripts/lib/docs/load-cursor-config.md +6 -0
- package/scripts/lib/docs/mirror-parity.md +6 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +6 -0
- package/scripts/lib/docs/resolve-target-files.md +6 -0
- package/scripts/lib/docs/root-notice.md +6 -0
- package/scripts/lib/docs/rule-meta-helpers.md +6 -0
- package/scripts/lib/docs/rule-meta.md +6 -0
- package/scripts/lib/docs/run-conftest-batch.md +6 -0
- package/scripts/lib/docs/run-lint-step.md +6 -0
- package/scripts/lib/docs/run-rule-cli.md +6 -0
- package/scripts/lib/docs/run-rule.md +6 -0
- package/scripts/lib/docs/run-standard-lint.md +6 -0
- package/scripts/lib/docs/run-standard-rule.md +6 -0
- package/scripts/lib/docs/skill-meta.md +6 -0
- package/scripts/lib/docs/template.md +6 -0
- package/scripts/lib/docs/timing-summary.md +6 -0
- package/scripts/lib/docs/workspaces.md +6 -0
- package/scripts/lib/docs/worktree-notice.md +6 -0
- package/scripts/lib/docs/worktree.md +6 -0
- package/scripts/lib/mirror-parity.mjs +1 -1
- package/scripts/lib/root-notice.mjs +1 -1
- package/scripts/lib/worktree-notice.mjs +5 -5
- package/scripts/lib/worktree.mjs +1 -1
- package/scripts/sync-claude-config.mjs +3 -0
- package/scripts/utils/docs/ast-scan-utils.md +6 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +6 -0
- package/scripts/utils/docs/find-package-json-paths.md +6 -0
- package/scripts/utils/docs/lock-cache-dir.md +6 -0
- package/scripts/utils/docs/pass.md +6 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +6 -0
- package/scripts/utils/docs/resolve-cmd.md +6 -0
- package/scripts/utils/docs/resolve-js-root.md +6 -0
- package/scripts/utils/docs/test-helpers.md +6 -0
- package/scripts/utils/docs/walk-cache.md +6 -0
- package/scripts/utils/docs/walkDir.md +6 -0
- package/scripts/utils/docs/worktree-fingerprint.md +6 -0
- package/scripts/utils/resolve-js-root.mjs +1 -1
- package/skills/doc-aggregate/SKILL.md +129 -0
- package/skills/doc-aggregate/js/docgen-ignore.mjs +9 -0
- package/skills/{docgen → doc-aggregate}/js/docgen-scan.mjs +22 -67
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +21 -0
- package/skills/doc-files/SKILL.md +100 -0
- package/skills/doc-files/js/docgen-crc.mjs +164 -0
- package/skills/{docgen → doc-files}/js/docgen-extract-anchors.mjs +48 -13
- package/skills/{docgen → doc-files}/js/docgen-extract.mjs +39 -10
- package/skills/doc-files/js/docgen-files-batch.mjs +181 -0
- package/skills/doc-files/js/docgen-gen.mjs +336 -0
- package/skills/{docgen → doc-files}/js/docgen-prompts.mjs +65 -50
- package/skills/doc-files/js/docgen-scan.mjs +298 -0
- package/skills/doc-files/js/docs/docgen-crc.md +32 -0
- package/skills/doc-files/js/docs/docgen-extract-anchors.md +27 -0
- package/skills/doc-files/js/docs/docgen-extract.md +29 -0
- package/skills/doc-files/js/docs/docgen-files-batch.md +25 -0
- package/skills/doc-files/js/docs/docgen-gen.md +30 -0
- package/skills/doc-files/js/docs/docgen-prompts.md +32 -0
- package/skills/doc-files/js/docs/docgen-scan.md +25 -0
- package/skills/doc-files/js/units-js.mjs +139 -0
- package/skills/doc-files/js/units.mjs +19 -0
- package/skills/doc-files/meta.json +1 -0
- package/skills/fix/js/docs/llm-worker.md +6 -0
- package/skills/fix/js/docs/orchestrator.md +6 -0
- package/skills/fix/js/llm-worker.mjs +3 -3
- package/skills/fix/js/orchestrator.mjs +1 -1
- package/skills/start-check/js/check.mjs +5 -3
- package/skills/start-check/js/docs/check.md +6 -0
- package/skills/docgen/SKILL.md +0 -224
- package/skills/docgen/bench/etalon/firebase_hosting.md +0 -19
- package/skills/docgen/bench/etalon/k8s-tree.md +0 -24
- package/skills/docgen/bench/etalon/overlay-paths.md +0 -24
- package/skills/docgen/js/docgen-batch-omlx.mjs +0 -82
- package/skills/docgen/js/docgen-batch.mjs +0 -95
- package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +0 -95
- package/skills/docgen/js/docgen-gen.mjs +0 -306
- package/skills/docgen/js/docs/docgen-extract.md +0 -28
- package/skills/docgen/js/docs/docgen-gen.md +0 -41
- package/skills/docgen/js/docs/docgen-ignore.md +0 -24
- package/skills/docgen/js/docs/docgen-prompts.md +0 -24
- package/skills/docgen/js/docs/docgen-scan.md +0 -48
- /package/skills/{docgen → doc-aggregate}/meta.json +0 -0
- /package/skills/{docgen → doc-files}/js/docgen-ignore.mjs +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/skills/doc-files/js/docgen-prompts.mjs
|
|
4
|
+
crc: c454d2a6
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# docgen-prompts
|
|
8
|
+
|
|
9
|
+
## Огляд
|
|
10
|
+
|
|
11
|
+
Промптовий шар local-only конвеєра файлових док: будує messages-набори для секційної генерації, критики й переписування, а секцію «Гарантії поведінки» формує детерміновано без LLM. Весь стиль документа (українська, поведінковість, заборона сигнатур) зашитий у спільний system-блок.
|
|
12
|
+
|
|
13
|
+
## Поведінка
|
|
14
|
+
|
|
15
|
+
1. Для кожної секції збирається мінімальний контекст: «Огляд» — лише людиночитний витяг фактів (без коду), «Поведінка» — єдина секція з повним кодом файлу у вікні, «Публічний API» — лише список експортів з їхніми описами. Анкори (URL, константи, маркери, приклади) додаються окремим блоком, коли вони є.
|
|
16
|
+
2. Факт-лист перекладається в негативні й позитивні твердження для моделі: свідомі пропуски шляхів, read-only, перехоплення помилок, явне «Кешування: НЕМАЄ — не згадуй кеш» — щоб відсікти типові галюцинації ще в промпті.
|
|
17
|
+
3. Критик отримує чорнетку секції і закритий список критеріїв дефектів (generic-фрази, пропущені анкори, граматика, підзаголовки, скопійовані сигнатури, вигадані факти); відповідь — список проблем або `NONE`. Переписувач отримує чорнетку разом зі списком проблем і повертає лише оновлений текст.
|
|
18
|
+
4. «Гарантії поведінки» складаються шаблоном з маркерів факт-листа (read-only, fail-safe, кешування, пропуски шляхів, відсутність мережі) — нуль запитів і нуль generic-фраз; за відсутності маркерів — твердження про детермінованість.
|
|
19
|
+
|
|
20
|
+
## Публічний API
|
|
21
|
+
|
|
22
|
+
- `sectionMessages` — секційні набори messages з мінімальним контекстом під кожну секцію.
|
|
23
|
+
- `criticMessages` / `refineMessages` — пара критика й переписувача для одного циклу уточнення секції.
|
|
24
|
+
- `guaranteesFromMarkers` — детермінований текст секції гарантій з маркерів.
|
|
25
|
+
- `oneShotMessages` — один запит на весь документ для нестандартних структур файлів.
|
|
26
|
+
- `STYLE` — спільний system-блок стилю.
|
|
27
|
+
|
|
28
|
+
## Гарантії поведінки
|
|
29
|
+
|
|
30
|
+
- Код файлу потрапляє лише у промпт секції «Поведінка» й у one-shot — решта секцій працюють на факт-листі.
|
|
31
|
+
- Формування промптів детерміноване: однакові факти й код → однакові messages.
|
|
32
|
+
- Не звертається до мережі й не виконує LLM-викликів — лише будує тексти.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/skills/doc-files/js/docgen-scan.mjs
|
|
4
|
+
crc: b517ab25
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# docgen-scan
|
|
8
|
+
|
|
9
|
+
## Огляд
|
|
10
|
+
|
|
11
|
+
Сканер кодових файлів і детектор стану файлових док: які джерела підлягають документуванню, де лежить їхня дока, що застаріло, що degraded. Працює і як бібліотека для batch-генерації, і як CLI (`doc-files scan` / `doc-files check`) для хуків.
|
|
12
|
+
|
|
13
|
+
## Поведінка
|
|
14
|
+
|
|
15
|
+
1. Рекурсивний обхід від кореня збирає кодові файли (`js`/`mjs`/`ts`/`vue`/`py`), пропускаючи тести, оголошення типів, ignore-дерева і теки `docs/`; для кореня з system-wide docs-layout файлові доки на верхньому рівні не плануються.
|
|
16
|
+
2. Для кожного джерела обчислюється шлях доки (`<dir>/docs/<stem>.md`) і стан застарілості за контрольною сумою.
|
|
17
|
+
3. `check` працює в режимах: `--hook` — один файл зі stdin-payload редакторського хука; `--git` — змінені відносно HEAD джерела як Stop-гейт із порогом великого прогону (`--max`, дефолт `50` або `N_CURSOR_DOC_FILES_GATE_MAX`: більше застарілих — попередження без блоку); явні шляхи — точкова перевірка.
|
|
18
|
+
4. Застарілі доки → exit-код `2` зі списком і підказкою перегенерації; усе свіже або великий прогін — `0`.
|
|
19
|
+
5. `check --degraded` — інформаційний звіт (exit `0`): свіжі за сумою доки з оцінкою нижче порогу, з кодами проблем і підказкою про `gen --retry-degraded`. Degraded — видимий борг, не гейт.
|
|
20
|
+
|
|
21
|
+
## Гарантії поведінки
|
|
22
|
+
|
|
23
|
+
- Сканер read-only: жодних записів у дерево.
|
|
24
|
+
- Рішення «застаріла/свіжа» детерміноване і залежить лише від вмісту джерела й frontmatter доки.
|
|
25
|
+
- Stop-гейт ніколи не блокує масовий перший прогін понад поріг — захист від нескінченного блокування задач.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** @see ./docs/units-js.md */
|
|
2
|
+
|
|
3
|
+
import { parseProgramOrNull, walkAstWithAncestors } from '../../../scripts/utils/ast-scan-utils.mjs'
|
|
4
|
+
|
|
5
|
+
// JSDoc-блок, що стоїть впритул перед позицією (лише пробіли між ними).
|
|
6
|
+
const JSDOC_BEFORE_RE = /\/\*\*(?:(?!\*\/)[\s\S])*\*\/\s*$/
|
|
7
|
+
const JSDOC_OPEN_RE = /^\s*\/\*\*?/
|
|
8
|
+
const JSDOC_CLOSE_RE = /\*\/\s*$/
|
|
9
|
+
const STAR_PREFIX_RE = /^\s*\*?\s?/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Очищає JSDoc від обрамлення `/** */` і `*`-префіксів.
|
|
13
|
+
* @param {string} raw сирий блок або порожній рядок
|
|
14
|
+
* @returns {string} текст опису без тегів-обрамлення
|
|
15
|
+
*/
|
|
16
|
+
function cleanDoc(raw) {
|
|
17
|
+
if (!raw) return ''
|
|
18
|
+
return raw
|
|
19
|
+
.replace(JSDOC_OPEN_RE, '')
|
|
20
|
+
.replace(JSDOC_CLOSE_RE, '')
|
|
21
|
+
.split('\n')
|
|
22
|
+
.map(l => l.replace(STAR_PREFIX_RE, '').trimEnd())
|
|
23
|
+
.join('\n')
|
|
24
|
+
.trim()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* JSDoc, що передує позиції `start` у джерелі (або порожній рядок).
|
|
29
|
+
* @param {string} src вміст файлу
|
|
30
|
+
* @param {number} start зміщення початку декларації
|
|
31
|
+
* @returns {string} очищений опис
|
|
32
|
+
*/
|
|
33
|
+
function precedingDoc(src, start) {
|
|
34
|
+
const m = src.slice(0, start).match(JSDOC_BEFORE_RE)
|
|
35
|
+
return cleanDoc(m ? m[0] : '')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Імʼя функції, що викликається (проста Identifier або `obj.method`).
|
|
40
|
+
* @param {Record<string, unknown>} node CallExpression
|
|
41
|
+
* @returns {string|null} імʼя callee або null
|
|
42
|
+
*/
|
|
43
|
+
function calleeName(node) {
|
|
44
|
+
const c = node.callee
|
|
45
|
+
if (!c || typeof c !== 'object') return null
|
|
46
|
+
if (c.type === 'Identifier') return c.name
|
|
47
|
+
if (c.type === 'MemberExpression' && !c.computed && c.property?.type === 'Identifier') return c.property.name
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Множина імен, що викликаються у тілі вузла (сирі callee — фільтрація на ребра
|
|
53
|
+
* call-graph робиться у `extractUnitsJs` після збору всіх імен юнітів).
|
|
54
|
+
* @param {unknown} node AST-вузол юніта
|
|
55
|
+
* @returns {Set<string>} імена викликів
|
|
56
|
+
*/
|
|
57
|
+
function collectCalls(node) {
|
|
58
|
+
const names = new Set()
|
|
59
|
+
walkAstWithAncestors(node, [], n => {
|
|
60
|
+
if (n.type === 'CallExpression') {
|
|
61
|
+
const name = calleeName(n)
|
|
62
|
+
if (name) names.add(name)
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
return names
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Будує юніт із декларації, додає у `units`. Розпізнає function/class та
|
|
70
|
+
* const-функції (`const x = () => {}` / `function expression`).
|
|
71
|
+
* @param {Record<string, unknown>} decl декларація (function/class/variable)
|
|
72
|
+
* @param {boolean} exported чи експортується
|
|
73
|
+
* @param {number} docStart зміщення для пошуку JSDoc (зовнішній export-вузол)
|
|
74
|
+
* @param {string} src вміст файлу
|
|
75
|
+
* @param {Array<object>} units акумулятор
|
|
76
|
+
* @returns {void}
|
|
77
|
+
*/
|
|
78
|
+
function pushUnits(decl, exported, docStart, src, units) {
|
|
79
|
+
if (!decl || typeof decl !== 'object') return
|
|
80
|
+
const doc = precedingDoc(src, docStart)
|
|
81
|
+
if (decl.type === 'FunctionDeclaration' || decl.type === 'ClassDeclaration') {
|
|
82
|
+
const name = decl.id?.name
|
|
83
|
+
if (!name) return
|
|
84
|
+
units.push({
|
|
85
|
+
name,
|
|
86
|
+
kind: decl.type === 'ClassDeclaration' ? 'class' : 'function',
|
|
87
|
+
exported,
|
|
88
|
+
span: { start: decl.start, end: decl.end },
|
|
89
|
+
body: src.slice(decl.start, decl.end),
|
|
90
|
+
calls: collectCalls(decl),
|
|
91
|
+
doc
|
|
92
|
+
})
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
if (decl.type === 'VariableDeclaration') {
|
|
96
|
+
for (const d of decl.declarations ?? []) {
|
|
97
|
+
const init = d.init
|
|
98
|
+
const isFn = init && (init.type === 'ArrowFunctionExpression' || init.type === 'FunctionExpression')
|
|
99
|
+
if (!isFn || d.id?.type !== 'Identifier') continue
|
|
100
|
+
units.push({
|
|
101
|
+
name: d.id.name,
|
|
102
|
+
kind: 'const',
|
|
103
|
+
exported,
|
|
104
|
+
span: { start: init.start, end: init.end },
|
|
105
|
+
body: src.slice(init.start, init.end),
|
|
106
|
+
calls: collectCalls(init),
|
|
107
|
+
doc
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Юніт-шар для js/mjs/ts: top-level функції/класи/const-функції з тілом, JSDoc,
|
|
115
|
+
* прапором експорту і ребрами call-graph (виклики ІНШИХ юнітів у тілі).
|
|
116
|
+
* @param {string} src вміст файлу
|
|
117
|
+
* @param {string} [relPath] шлях (для вибору мови oxc)
|
|
118
|
+
* @returns {Array<{name:string, kind:string, exported:boolean, span:{start:number,end:number}, body:string, calls:string[], doc:string}>|null} юніти або null, якщо файл не парситься
|
|
119
|
+
*/
|
|
120
|
+
export function extractUnitsJs(src, relPath = 'scan.ts') {
|
|
121
|
+
const program = parseProgramOrNull(src, relPath)
|
|
122
|
+
if (!program || !Array.isArray(program.body)) return null
|
|
123
|
+
|
|
124
|
+
const units = []
|
|
125
|
+
for (const node of program.body) {
|
|
126
|
+
if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
|
127
|
+
pushUnits(node.declaration, true, node.start, src, units)
|
|
128
|
+
} else if (node.type === 'ExportDefaultDeclaration' && node.declaration) {
|
|
129
|
+
pushUnits(node.declaration, true, node.start, src, units)
|
|
130
|
+
} else {
|
|
131
|
+
pushUnits(node, false, node.start, src, units)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Ребра call-graph: лишаємо тільки виклики інших внутрішніх юнітів
|
|
136
|
+
const names = new Set(units.map(u => u.name))
|
|
137
|
+
for (const u of units) u.calls = [...u.calls].filter(n => names.has(n) && n !== u.name)
|
|
138
|
+
return units
|
|
139
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @see ./docs/units.md */
|
|
2
|
+
|
|
3
|
+
import { extractUnitsJs } from './units-js.mjs'
|
|
4
|
+
|
|
5
|
+
const JS_EXT = new Set(['js', 'mjs', 'ts', 'jsx', 'tsx', 'cts', 'mts'])
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Мовно-агностичний фасад юніт-шару (Інкремент 1). Диспатчить за розширенням:
|
|
9
|
+
* js/mjs/ts → oxc; vue/py — додаються наступними кроками (поки `null` → виклик
|
|
10
|
+
* відкочується на whole-file шлях, як і раніше).
|
|
11
|
+
* @param {string} src вміст файлу
|
|
12
|
+
* @param {string} relPath шлях файлу
|
|
13
|
+
* @returns {Array<object>|null} юніти або null, якщо мова ще не підтримана / файл не парситься
|
|
14
|
+
*/
|
|
15
|
+
export function extractUnits(src, relPath) {
|
|
16
|
+
const ext = (relPath.split('.').pop() || '').toLowerCase()
|
|
17
|
+
if (JS_EXT.has(ext)) return extractUnitsJs(src, relPath)
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "auto": "завжди", "worktree": false, "requireRoot": true }
|
|
@@ -12,7 +12,7 @@ import { callOmlx, isOmlxModel } from '../../../lib/omlx.mjs'
|
|
|
12
12
|
export const MODEL = env.N_CURSOR_FIX_MODEL ?? resolveModel('min')
|
|
13
13
|
export const MODEL_HEAVY = env.N_CURSOR_FIX_MODEL_HEAVY ?? resolveModel('avg')
|
|
14
14
|
|
|
15
|
-
const JSON_CODE_BLOCK_RE = /```(?:json)
|
|
15
|
+
const JSON_CODE_BLOCK_RE = /```(?:json)?[ \t]{0,8}\n?([\s\S]*?)```/
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Витягує відносні шляхи файлів із violation output.
|
|
@@ -35,7 +35,7 @@ function extractFilePaths(output) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// Патерн без workspace: просто path/to/file.ext або ./file.ext
|
|
38
|
-
const re = /(?:^|\s)(
|
|
38
|
+
const re = /(?:^|\s)(\.?\w[\w./-]*\.(?:json|js|mjs|ts|vue|yml|yaml|toml|mdc|md|sh|py))(?::\d+)?/gm
|
|
39
39
|
for (const m of output.matchAll(re)) {
|
|
40
40
|
const p = m[1]
|
|
41
41
|
if (!seen.has(p)) {
|
|
@@ -116,7 +116,7 @@ function callModel(prompt, model) {
|
|
|
116
116
|
error: [
|
|
117
117
|
`pi: немає ключа для ${provider}.`,
|
|
118
118
|
`Встановіть N_CLOUD_MIN_MODEL=provider/model-id`,
|
|
119
|
-
`(напр.: openai/gpt-5.4-mini, google/gemini-2.5-flash, ollama/gemma3:4b)
|
|
119
|
+
`(напр.: openai/gpt-5.4-mini, google/gemini-2.5-flash, ollama/gemma3:4b)`
|
|
120
120
|
].join(' ')
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -20,7 +20,7 @@ export async function runOrchestratorCli(args, cwd) {
|
|
|
20
20
|
|
|
21
21
|
const maxIterIdx = args.indexOf('--max-iter')
|
|
22
22
|
const maxIter =
|
|
23
|
-
maxIterIdx === -1 ? DEFAULT_MAX_ITER :
|
|
23
|
+
maxIterIdx === -1 ? DEFAULT_MAX_ITER : Number(args[maxIterIdx + 1] ?? DEFAULT_MAX_ITER) || DEFAULT_MAX_ITER
|
|
24
24
|
const skipIdxs = new Set(maxIterIdx === -1 ? [] : [maxIterIdx, maxIterIdx + 1])
|
|
25
25
|
const ruleFilter = args.filter((a, i) => !a.startsWith('-') && !skipIdxs.has(i))
|
|
26
26
|
|
|
@@ -67,8 +67,8 @@ export async function scanStartWorkspaces(cwd) {
|
|
|
67
67
|
* @param {string} log обʼєднаний stdout+stderr
|
|
68
68
|
* @returns {{ready:boolean, firstError:string|null, logTail:string}} витяг
|
|
69
69
|
*/
|
|
70
|
-
export function parseStartLog(log) {
|
|
71
|
-
const text = log
|
|
70
|
+
export function parseStartLog(log = '') {
|
|
71
|
+
const text = log
|
|
72
72
|
const lines = text.split('\n')
|
|
73
73
|
const firstError = lines.find(l => ERROR_RE.test(l))?.trim() ?? null
|
|
74
74
|
const logTail = lines
|
|
@@ -137,7 +137,9 @@ export async function runWorkspaceStart(cwd, workspace, opts = {}) {
|
|
|
137
137
|
|
|
138
138
|
// server: успіх = дожив до кінця grace (timedOut) або встиг віддати рядок готовності.
|
|
139
139
|
// cli: успіх = чистий вихід 0 у межах grace.
|
|
140
|
-
|
|
140
|
+
let status
|
|
141
|
+
if (type === 'server') status = timedOut || ready ? 'OK' : 'FAIL'
|
|
142
|
+
else status = exitCode === 0 ? 'OK' : 'FAIL'
|
|
141
143
|
|
|
142
144
|
return {
|
|
143
145
|
workspace,
|
package/skills/docgen/SKILL.md
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: docgen
|
|
3
|
-
description: >-
|
|
4
|
-
Обходить проєкт і для кожного кодового файлу (js/mjs/ts/vue/py) пише лаконічну поведінкову українську md-документацію у теку docs/ поряд із кодом — диспатчить окремого субагента на кожен файл, за правилами adr/ci4
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# docgen — генерація документації по файлах
|
|
8
|
-
|
|
9
|
-
## Мета
|
|
10
|
-
|
|
11
|
-
Для кожного кодового файлу проєкту створити лаконічну поведінкову `.md`-документацію у теці `docs/`
|
|
12
|
-
**поряд із самим файлом** (`<dir>/docs/<stem>.md`). Документацію пише **окремий субагент**
|
|
13
|
-
на кожен файл — не один прохід, а батч-диспатч. Джерело правди стилю — правила `adr` і
|
|
14
|
-
`ci4` (`docs/explanation`/`docs/adr`-каталоги з тих правил **не застосовуємо** — доку
|
|
15
|
-
кладемо локально поряд із кодом).
|
|
16
|
-
|
|
17
|
-
Документація — **трирівнева**, рівні виконуються строго послідовно:
|
|
18
|
-
|
|
19
|
-
1. **Tier 1 — файли**: `<dir>/docs/<stem>.md`, субагент на файл (нижче).
|
|
20
|
-
2. **Tier 2 — module-summary**: `<module_root>/docs/ARCHITECTURE.md`, субагент на модуль.
|
|
21
|
-
3. **Tier 3 — доменні доки**: `docs/<домен>.md` у кореневій `docs/`, субагент-синтезатор
|
|
22
|
-
виділяє бізнес-домени й пише файл на кожен домен.
|
|
23
|
-
|
|
24
|
-
Агрегат ніколи не випереджає джерело: Tier 2 — лише після завершення всього Tier 1,
|
|
25
|
-
Tier 3 — лише після завершення всього Tier 2.
|
|
26
|
-
|
|
27
|
-
## ⚠️ Паралелізм
|
|
28
|
-
|
|
29
|
-
Диспатч субагентів — **батчами по 5 одночасно**. Не запускати весь список одразу
|
|
30
|
-
(перевантаження). Кожен субагент пише свій окремий файл — спільного стану немає, гонок
|
|
31
|
-
за файли немає.
|
|
32
|
-
|
|
33
|
-
Рівні строго послідовні: Tier 2 стартує лише після завершення всього Tier 1, Tier 3 —
|
|
34
|
-
лише після всього Tier 2. Усередині Tier 1 і Tier 2 — батчі по 5. Tier 3 — один субагент.
|
|
35
|
-
|
|
36
|
-
## Передумова
|
|
37
|
-
|
|
38
|
-
- Поточна директорія — корінь проєкту, який документуємо.
|
|
39
|
-
- Доступний `npx @nitra/cursor` (пакет `@nitra/cursor` встановлено або через npx).
|
|
40
|
-
|
|
41
|
-
## Workflow
|
|
42
|
-
|
|
43
|
-
### Крок 1: Зібрати список файлів
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
npx @nitra/cursor docgen scan
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Команда друкує JSON-масив об'єктів. Усі шляхи в ньому — відносні до кореня проєкту:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
[{ "sourcePath": "src/lib/foo.js", "docPath": "src/lib/docs/foo.md", "exists": false }]
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Розпарси JSON.
|
|
56
|
-
|
|
57
|
-
### Крок 2: Відфільтрувати вже описані
|
|
58
|
-
|
|
59
|
-
За замовчуванням **пропусти** елементи з `"exists": true`. Перегенеровуй їх лише якщо
|
|
60
|
-
користувач явно попросив `--overwrite` (тоді обробляй усі). `--overwrite` — **не** прапор
|
|
61
|
-
`docgen scan`: scanner лише лістить файли, а рішення «пропустити чи перегенерувати» приймаєш
|
|
62
|
-
ти тут, фільтруючи за полем `exists`.
|
|
63
|
-
|
|
64
|
-
Якщо після фільтра список порожній — зупинись:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
✓ Усі кодові файли вже мають документацію. Нічого робити.
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Запам'ятай `total = довжина відфільтрованого списку`.
|
|
71
|
-
|
|
72
|
-
### Крок 3: Диспатч субагентів батчами по 5
|
|
73
|
-
|
|
74
|
-
Розбий список на батчі по 5 елементів. Для кожного батчу запусти **до 5 субагентів
|
|
75
|
-
одночасно (в одному повідомленні)**, дочекайся завершення батчу, переходь до наступного.
|
|
76
|
-
|
|
77
|
-
Промпт кожного субагента (підстав `sourcePath` і `docPath`):
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
Напиши лаконічну технічну документацію для одного файлу коду — орієнтовану на поведінку, не реалізацію.
|
|
81
|
-
|
|
82
|
-
ФАЙЛ-ДЖЕРЕЛО: <sourcePath>
|
|
83
|
-
ЗАПИСАТИ В: <docPath>
|
|
84
|
-
|
|
85
|
-
Кроки:
|
|
86
|
-
1. Прочитай файл <sourcePath> повністю.
|
|
87
|
-
2. Створи теку для <docPath>, якщо її немає.
|
|
88
|
-
3. Запиши markdown-документ у <docPath> за правилами нижче.
|
|
89
|
-
|
|
90
|
-
Правила документа (за adr/ci4):
|
|
91
|
-
- Мова — УКРАЇНСЬКА для всього тексту (заголовки, абзаци, таблиці). Code identifiers,
|
|
92
|
-
шляхи, імена API, команди — лишай як у коді (зазвичай ASCII).
|
|
93
|
-
- ЧИСТИЙ Markdown. Жодних HTML-обгорток (<div>/<span>/класів) — токен-ефективність.
|
|
94
|
-
- ФОКУС НА ПОВЕДІНЦІ, не реалізації. Пиши ЩО і НАВІЩО, а не як саме це зроблено.
|
|
95
|
-
- НЕ перелічуй модулі стандартної бібліотеки (node:fs, node:path, node:crypto, python stdlib
|
|
96
|
-
тощо) — вони не несуть бізнес-значення. Зовнішні залежності (npm-пакети, внутрішні модулі)
|
|
97
|
-
згадуй лише якщо їхня роль не очевидна з контексту.
|
|
98
|
-
- НЕ перелічуй внутрішні назви допоміжних функцій/змінних — описуй їхню роль і поведінку.
|
|
99
|
-
Імена публічних exports згадуй лише коли export — справжня точка інтеграції, яку кличуть
|
|
100
|
-
ззовні. Для дрібних/листкових модулів з однією відповідальністю опиши роль поведінково,
|
|
101
|
-
БЕЗ сигнатур, таблиць типів і переліку параметрів — це деталі реалізації.
|
|
102
|
-
- Контекстна незалежність: кожна секція самодостатня. Уникай «як вище», «ця функція», «той сервіс».
|
|
103
|
-
- Секції (включай лише доречні — порожніх не вигадуй):
|
|
104
|
-
## Огляд — 1-3 речення: що файл робить і навіщо він існує (роль у системі). Згадай
|
|
105
|
-
ключову семантику, якщо вона визначає сенс файлу (opt-in/gate, кеш, ідемпотентність тощо).
|
|
106
|
-
## Поведінка — покроковий алгоритм у бізнес-термінах (не деталі реалізації).
|
|
107
|
-
Нумерований список: що відбувається, умови, гілки логіки. Якщо файл керується
|
|
108
|
-
конфігом чи форматом даних — наведи короткий приклад (тільки реальний з коду).
|
|
109
|
-
## Публічний API — ЛИШЕ якщо модуль має нетривіальну зовнішню поверхню, яку називають
|
|
110
|
-
споживачі. Для кожного export: назва + що робить. Без сигнатур і таблиць типів.
|
|
111
|
-
Не дублюй ## Поведінка. Для модуля з однією функцією-предикатом цю секцію пропусти.
|
|
112
|
-
## Де використовується — де в системі цей файл вживається (якщо відомо з коду).
|
|
113
|
-
## Гарантії поведінки — інваріанти й крайові випадки: що гарантовано (read-only,
|
|
114
|
-
не кидає винятків, fail-safe-значення за замовчуванням, безпечна обробка поганих даних)
|
|
115
|
-
і що стається при відсутніх ресурсах чи некоректному вводі. Пропусти, якщо таких гарантій немає.
|
|
116
|
-
- Для .vue додай ## Інтерфейс компонента — props (типи, defaults), emits, slots, реактивний стан.
|
|
117
|
-
- НЕ вигадуй деталей, яких немає в коді.
|
|
118
|
-
- Мета — Behavior Test: читач розуміє, що робить файл і як він вписується в систему,
|
|
119
|
-
без потреби читати реалізацію.
|
|
120
|
-
|
|
121
|
-
Поверни лише підтвердження, що файл <docPath> записано.
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Крок 4: Tier 2 — module-summary
|
|
125
|
-
|
|
126
|
-
Після завершення **всіх** батчів Tier 1 зібрати список модулів:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
npx @nitra/cursor docgen modules
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Команда друкує JSON-масив:
|
|
133
|
-
|
|
134
|
-
```json
|
|
135
|
-
[
|
|
136
|
-
{
|
|
137
|
-
"moduleRoot": "/abs/npm/rules/adr",
|
|
138
|
-
"relRoot": "npm/rules/adr",
|
|
139
|
-
"slug": "npm-rules-adr",
|
|
140
|
-
"docPath": "/abs/npm/rules/adr/docs/ARCHITECTURE.md",
|
|
141
|
-
"members": ["npm/rules/adr/index.mjs"],
|
|
142
|
-
"exists": false
|
|
143
|
-
}
|
|
144
|
-
]
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
module-summary **завжди регенерується** (це агрегат — поле `exists` ігноруй). Розбий модулі на батчі по 5 і диспатч субагентів. Промпт кожного (підстав `relRoot`, `docPath`, `members`):
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
Напиши module-summary для одного логічного модуля.
|
|
151
|
-
|
|
152
|
-
МОДУЛЬ: <relRoot>
|
|
153
|
-
ЗАПИСАТИ В: <docPath>
|
|
154
|
-
ФАЙЛИ МОДУЛЯ (members): <members>
|
|
155
|
-
|
|
156
|
-
Кроки:
|
|
157
|
-
1. Прочитай файлові доки членів модуля. <member> — sourcePath відносно кореня проєкту
|
|
158
|
-
(= поточний CWD); його файлова дока — <CWD>/<dir>/docs/<stem>.md. За потреби зазирни
|
|
159
|
-
в самі файли.
|
|
160
|
-
2. Створи теку для <docPath>, якщо її немає.
|
|
161
|
-
3. Запиши markdown у <docPath> за тими ж правилами стилю, що й файлова дока
|
|
162
|
-
(українська, чистий Markdown, контекстна незалежність, без HTML).
|
|
163
|
-
|
|
164
|
-
Секції module-summary:
|
|
165
|
-
## Огляд модуля — призначення модуля <relRoot>, його роль у проєкті.
|
|
166
|
-
## Ключові файли — список із кліковими посиланнями (відносними до розташування цього
|
|
167
|
-
ARCHITECTURE.md) на члени модуля та їхні файлові доки.
|
|
168
|
-
## Публічний API — що модуль експортує назовні.
|
|
169
|
-
## Внутрішній потік — як компоненти модуля взаємодіють.
|
|
170
|
-
## Підмодулі — вкладені модулі, якщо є.
|
|
171
|
-
|
|
172
|
-
Поверни лише підтвердження, що файл <docPath> записано.
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Крок 5: Tier 3 — доменні доки
|
|
176
|
-
|
|
177
|
-
Після завершення **всіх** module-summary диспатч **одного** субагента-синтезатора.
|
|
178
|
-
У промпт підстав конкретний перелік шляхів module-summary (<module_root>/docs/ARCHITECTURE.md
|
|
179
|
-
кожного модуля з виводу `docgen modules`), а не інструкцію їх шукати. Промпт:
|
|
180
|
-
|
|
181
|
-
```
|
|
182
|
-
Синтезуй доменну документацію бізнес-процесів проєкту.
|
|
183
|
-
|
|
184
|
-
ДЖЕРЕЛА (module-summary, читай усі): <перелік шляхів ARCHITECTURE.md, підставлений вище>
|
|
185
|
-
|
|
186
|
-
Кроки:
|
|
187
|
-
1. Прочитай усі module-summary.
|
|
188
|
-
2. Виділи бізнес-домени та процеси (можуть перетинати межі модулів). Доменів може бути багато.
|
|
189
|
-
3. Для КОЖНОГО домену запиши окремий файл docs/<домен>.md у кореневій docs/:
|
|
190
|
-
- назва файлу — короткий kebab-slug домену;
|
|
191
|
-
- не перезаписуй файлові доки кореневих файлів у docs/ (напр. app.md, eslint.config.md):
|
|
192
|
-
якщо слаґ домену збігається з іменем такого файлу — додай суфікс -domain
|
|
193
|
-
(напр. app-domain.md). Інакше пиши docs/<домен>.md як є;
|
|
194
|
-
- опиши бізнес-процес домену з кліковими відносними посиланнями на module-summary, конкретні файли й директорії.
|
|
195
|
-
|
|
196
|
-
Правила стилю — ті ж (українська, чистий Markdown, контекстна незалежність, без HTML).
|
|
197
|
-
|
|
198
|
-
Поверни перелік створених файлів docs/<домен>.md.
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Крок 6: Підсумок
|
|
202
|
-
|
|
203
|
-
Після всіх батчів виведи:
|
|
204
|
-
|
|
205
|
-
```
|
|
206
|
-
✓ docgen завершено.
|
|
207
|
-
Tier 1 (файли): описано <N>, пропущено <S>, помилок <E>.
|
|
208
|
-
Tier 2 (модулі): <M> module-summary.
|
|
209
|
-
Tier 3 (домени): <D> доменних доків у docs/.
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
Перелічи файли з помилками (субагент впав або не записав `docPath`), якщо такі є.
|
|
213
|
-
Помилка одного файлу не зупиняє решту — обробляй усі батчі до кінця.
|
|
214
|
-
|
|
215
|
-
## Нотатки
|
|
216
|
-
|
|
217
|
-
- Не комітити автоматично — користувач вирішує, коли комітити згенеровану доку.
|
|
218
|
-
- Scanner ігнорує `node_modules`, `dist`, `.git`, `__pycache__`, `coverage`, `.cursor`,
|
|
219
|
-
`.claude`, усі теки `docs/`, а також `*.test.*` / `*.spec.*` / `*.d.ts`.
|
|
220
|
-
Кореневий repo `docs/` — system-wide only: file-level docs туди не пишуться, і Tier 1
|
|
221
|
-
має трактувати цей корінь як повністю нецільовий.
|
|
222
|
-
- Список glob-ів для ignore живе в окремому snippet-модулі
|
|
223
|
-
`npm/skills/docgen/js/docgen-ignore.mjs` (`DOCGEN_IGNORE_GLOBS`).
|
|
224
|
-
Scanner лише читає цей список.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# firebase_hosting.mjs
|
|
2
|
-
|
|
3
|
-
## Огляд
|
|
4
|
-
|
|
5
|
-
Перевірка-концерн правила abie: у підкаталогах першого рівня репозиторію не повинно бути артефактів Firebase Hosting (`.firebaserc`, `firebase.json`, `.firebase/`), бо `abie.mdc` забороняє Firebase Hosting. Сам корінь репозиторію не перевіряється — там ці імена можуть належати суміжним проєктам.
|
|
6
|
-
|
|
7
|
-
## Поведінка
|
|
8
|
-
|
|
9
|
-
1. Прочитати список елементів кореня репозиторію. Якщо каталог не читається — зафіксувати помилку (fail) і завершитися.
|
|
10
|
-
2. Відібрати підкаталоги першого рівня, пропустивши `.git` і `node_modules`.
|
|
11
|
-
3. У кожному такому підкаталозі перевірити наявність заборонених імен: файлів `.firebaserc`, `firebase.json` і каталогу `.firebase/`. Кожна знахідка — окремий fail.
|
|
12
|
-
4. Якщо жодного порушення не знайдено — зафіксувати pass.
|
|
13
|
-
5. Повернути підсумковий exit-код.
|
|
14
|
-
|
|
15
|
-
## Гарантії поведінки
|
|
16
|
-
|
|
17
|
-
- Read-only: лише перелічує й перевіряє існування шляхів.
|
|
18
|
-
- Помилка читання кореня не валить процес винятком, а стає fail.
|
|
19
|
-
- Перевіряється лише перший рівень; корінь і глибші рівні поза охопленням.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# k8s-tree.mjs
|
|
2
|
-
|
|
3
|
-
## Огляд
|
|
4
|
-
|
|
5
|
-
Обхід Kubernetes-дерева для перевірок abie з кешуванням на час одного прогону. Знаходить YAML під сегментом `k8s/` і визначає каталоги з `Deployment`. Перший виклик платить за обхід; наступні концерни прогону беруть із кешу.
|
|
6
|
-
|
|
7
|
-
## Поведінка
|
|
8
|
-
|
|
9
|
-
1. Пошук маніфестів: рекурсивно обійти дерево, відібравши `.yaml`/`.yml` під сегментом `k8s/`; `.github/` свідомо пропускається. Результат відсортований.
|
|
10
|
-
2. Каталоги з Deployment: розпарсити передані YAML, відібрати `kind: Deployment`, зібрати унікальні каталоги.
|
|
11
|
-
3. Кешування: обидві операції кешуються module-level singleton-ом за ключем із входів; повтор без I/O.
|
|
12
|
-
4. Пошкоджені YAML за замовчуванням мовчки пропускаються; репортер передає викликач.
|
|
13
|
-
|
|
14
|
-
## Публічний API
|
|
15
|
-
|
|
16
|
-
- `findK8sYamlFiles` — відсортований список YAML під `k8s/` (з кешем, пропуск `.github/`).
|
|
17
|
-
- `collectDeploymentDirs` — множина каталогів із Deployment (кеш, опц. репортер помилок).
|
|
18
|
-
|
|
19
|
-
## Гарантії поведінки
|
|
20
|
-
|
|
21
|
-
- Read-only щодо проєкту.
|
|
22
|
-
- Стійкість до пошкоджених YAML: помилкові документи пропускаються, обхід не переривається.
|
|
23
|
-
- Детермінований вивід (стабільне сортування).
|
|
24
|
-
- Кеш у межах прогону; повторні виклики безкоштовні.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# overlay-paths.mjs
|
|
2
|
-
|
|
3
|
-
## Огляд
|
|
4
|
-
|
|
5
|
-
Набір чистих path-хелперів для overlay-перевірок правила abie: класифікація шляхів (ua-overlay проти base-шару), виведення каталогу пакета з overlay-шляху, умовні питання правила (чи потрібен HTTPRoute, чи є Deployment). Уся логіка — над рядками/шляхами та перевіркою існування файлів; YAML не парситься.
|
|
6
|
-
|
|
7
|
-
## Поведінка
|
|
8
|
-
|
|
9
|
-
- ua-overlay: шлях закінчується на `ua/kustomization.yaml`; base-шар — за сегментом `base/`.
|
|
10
|
-
- Каталог пакета: з `…/k8s/ua/kustomization.yaml` виділяється батько `k8s/`; без збігу — немає результату.
|
|
11
|
-
- HTTPRoute-gate: вимога лише для Vite-пакетів (є `vite.config.{js,mjs,ts}`).
|
|
12
|
-
- Deployment: чи хоч один каталог із Deployment лежить у `k8s/` цього пакета.
|
|
13
|
-
- base-шар: yaml під `<пакет>/k8s/` і не в `ua/`.
|
|
14
|
-
- Шляхи нормалізуються до posix (`\`→`/`).
|
|
15
|
-
|
|
16
|
-
## Публічний API
|
|
17
|
-
|
|
18
|
-
- `isUaKustomizationPath`, `abiePackageDirFromK8sOverlay`, `abieOverlayRequiresHttpRouteByVite`, `abieOverlayK8sTreeHasDeployment`, `isAbieK8sBaseYamlPath`, `isK8sYamlInAbiePackageExcludingUaOverlay`.
|
|
19
|
-
|
|
20
|
-
## Гарантії поведінки
|
|
21
|
-
|
|
22
|
-
- Read-only, без побічних ефектів.
|
|
23
|
-
- Невідповідність шаблону → негативний/порожній результат, не виняток.
|
|
24
|
-
- Незалежність від ОС (розділювачі зводяться до `/`).
|