@nitra/cursor 3.22.0 → 3.23.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/.pi-template/extensions/n-cursor-adr/docs/index.md +181 -0
- package/AGENTS.template.md +4 -0
- package/CHANGELOG.md +37 -3
- package/bin/docs/n-cursor.md +636 -0
- package/bin/docs/rename-yaml-extensions.md +207 -0
- package/bin/n-cursor.js +30 -3
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +18 -0
- package/rules/abie/js/docs/applies.md +26 -0
- package/rules/abie/js/docs/env_dns.md +32 -0
- package/rules/abie/js/docs/firebase_hosting.md +23 -0
- package/rules/abie/js/docs/hc_pairing.md +35 -0
- package/rules/abie/js/docs/ua_http_route.md +28 -0
- package/rules/abie/js/docs/ua_node_selector.md +28 -0
- package/rules/abie/lib/docs/enabled.md +29 -0
- package/rules/abie/lib/docs/env-dns.md +35 -0
- package/rules/abie/lib/docs/hc-yaml.md +33 -0
- package/rules/abie/lib/docs/http-route.md +44 -0
- package/rules/abie/lib/docs/k8s-tree.md +40 -0
- package/rules/abie/lib/docs/kustomization-patches.md +47 -0
- package/rules/abie/lib/docs/overlay-paths.md +38 -0
- package/rules/abie/lib/docs/yaml.md +29 -0
- package/rules/adr/docs/fix.md +148 -0
- package/rules/adr/js/docs/hooks.md +259 -0
- package/rules/bun/docs/fix.md +156 -0
- package/rules/bun/js/docs/layout.md +393 -0
- package/rules/capacitor/docs/fix.md +121 -0
- package/rules/capacitor/js/docs/platforms.md +295 -0
- package/rules/changelog/changelog.mdc +4 -2
- package/rules/changelog/docs/fix.md +174 -0
- package/rules/changelog/js/consistency.mjs +114 -13
- package/rules/changelog/js/docs/consistency.md +387 -0
- package/rules/changelog/lib/docs/package-manifest.md +210 -0
- package/rules/ci4/docs/fix.md +179 -0
- package/rules/ci4/js/docs/marksman_config.md +128 -0
- package/rules/docker/docker.mdc +8 -3
- package/rules/docker/docs/fix.md +171 -0
- package/rules/docker/js/docs/lint.md +258 -0
- package/rules/docker/lib/docs/docker-hadolint.md +184 -0
- package/rules/docker/lib/docs/docker-mirror.md +247 -0
- package/rules/docker/lib/docs/docker-native-addon.md +170 -0
- package/rules/docker/lib/docs/docker-nginx-user.md +219 -0
- package/rules/docker/lint/docs/lint.md +193 -0
- package/rules/efes/docs/fix.md +203 -0
- package/rules/feedback/docs/fix.md +140 -0
- package/rules/flow/docs/fix.md +152 -0
- package/rules/ga/docs/fix.md +158 -0
- package/rules/ga/js/docs/lint.md +100 -0
- package/rules/ga/js/docs/workflows.md +217 -0
- package/rules/ga/lint/docs/lint.md +209 -0
- package/rules/ga/policy/clean_merged_branch/clean_merged_branch.rego +11 -2
- package/rules/ga/policy/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml +3 -4
- package/rules/graphql/docs/fix.md +126 -0
- package/rules/graphql/js/docs/tooling.md +264 -0
- package/rules/graphql/lib/docs/graphql-gql-scan.md +219 -0
- package/rules/hasura/docs/fix.md +120 -0
- package/rules/hasura/hasura.mdc +14 -0
- package/rules/hasura/js/docs/internal_urls.md +326 -0
- package/rules/image-avif/docs/fix.md +132 -0
- package/rules/image-avif/js/docs/avif_generation.md +241 -0
- package/rules/image-compress/docs/fix.md +150 -0
- package/rules/image-compress/js/docs/package_setup.md +191 -0
- package/rules/js-bun-db/docs/fix.md +148 -0
- package/rules/js-bun-db/js/docs/safety.md +231 -0
- package/rules/js-bun-db/js-bun-db.mdc +42 -13
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +347 -0
- package/rules/js-bun-redis/docs/fix.md +123 -0
- package/rules/js-bun-redis/js/docs/imports.md +176 -0
- package/rules/js-bun-redis/lib/docs/redis-imports.md +223 -0
- package/rules/js-lint/docs/fix.md +117 -0
- package/rules/js-lint/js/docs/lint.md +250 -0
- package/rules/js-lint/js/docs/tooling.md +348 -0
- package/rules/js-lint/js/docs/utils_imports.md +207 -0
- package/rules/js-lint-ci/docs/fix.md +154 -0
- package/rules/js-lint-ci/js/docs/lint.md +144 -0
- package/rules/js-mssql/docs/fix.md +128 -0
- package/rules/js-mssql/js/docs/deps.md +263 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +367 -0
- package/rules/js-run/docs/fix.md +144 -0
- package/rules/js-run/js/docs/runtime.md +388 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +117 -0
- package/rules/js-run/lib/docs/check-env-scan.md +433 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +300 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +204 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +326 -0
- package/rules/k8s/docs/fix.md +129 -0
- package/rules/k8s/js/docs/manifests.md +344 -0
- package/rules/k8s/js/manifests.mjs +6 -2
- package/rules/k8s/k8s.mdc +4 -2
- package/rules/k8s/lint/docs/lint.md +411 -0
- package/rules/k8s/policy/network_policy/template/deployment.snippet.yaml +2 -0
- package/rules/k8s/policy/network_policy/template/stateful-set.snippet.yaml +2 -0
- package/rules/nginx-default-tpl/docs/fix.md +124 -0
- package/rules/nginx-default-tpl/js/docs/template.md +378 -0
- package/rules/npm-module/docs/fix.md +98 -0
- package/rules/npm-module/js/docs/package_structure.md +274 -0
- package/rules/npm-module/js/docs/rule_meta.md +137 -0
- package/rules/npm-module/js/docs/skill_meta.md +190 -0
- package/rules/php/docs/fix.md +107 -0
- package/rules/php/js/docs/tooling.md +152 -0
- package/rules/php/lint/docs/lint.md +215 -0
- package/rules/python/docs/fix.md +163 -0
- package/rules/python/js/docs/applies.md +108 -0
- package/rules/python/js/docs/tooling.md +153 -0
- package/rules/python/lint/docs/lint.md +322 -0
- package/rules/rego/docs/fix.md +121 -0
- package/rules/rego/js/docs/applies.md +174 -0
- package/rules/rego/js/docs/lint.md +118 -0
- package/rules/rego/lint/docs/lint.md +204 -0
- package/rules/release/docs/change.md +185 -0
- package/rules/release/docs/fix.md +119 -0
- package/rules/release/docs/release.md +222 -0
- package/rules/release/lib/docs/aggregate.md +246 -0
- package/rules/release/lib/docs/change-file.md +200 -0
- package/rules/release/lib/docs/fallback.md +203 -0
- package/rules/rust/docs/fix.md +129 -0
- package/rules/rust/js/docs/applies.md +140 -0
- package/rules/rust/lib/docs/has-cargo-toml.md +130 -0
- package/rules/security/docs/fix.md +86 -0
- package/rules/security/js/docs/lint.md +171 -0
- package/rules/security/js/docs/sample_secret.md +190 -0
- package/rules/security/js/docs/trufflehog.md +137 -0
- package/rules/security/js/lint.mjs +9 -1
- package/rules/style-lint/docs/fix.md +155 -0
- package/rules/style-lint/js/docs/lint.md +184 -0
- package/rules/style-lint/js/docs/tooling.md +194 -0
- package/rules/tauri/docs/fix.md +158 -0
- package/rules/tauri/js/docs/cargo_mutants_config.md +168 -0
- package/rules/tauri/js/docs/tooling.md +228 -0
- package/rules/test/coverage/coverage.mjs +15 -3
- package/rules/test/docs/fix.md +132 -0
- package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +138 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +134 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +160 -0
- package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +195 -0
- package/rules/test/js/docs/cargo_mutants_config.md +173 -0
- package/rules/test/js/docs/location.md +136 -0
- package/rules/test/js/docs/no-process-chdir.md +160 -0
- package/rules/test/js/docs/no-relative-fs-path.md +271 -0
- package/rules/test/js/docs/stryker_config.md +152 -0
- package/rules/test/js/docs/vitest-config-pool-forks.md +174 -0
- package/rules/text/docs/fix.md +118 -0
- package/rules/text/js/docs/forbidden-prettier.md +143 -0
- package/rules/text/js/docs/formatting.md +256 -0
- package/rules/text/js/docs/lint.md +122 -0
- package/rules/text/lint/docs/lint.md +220 -0
- package/rules/text/lint/docs/run-dotenv-linter.md +157 -0
- package/rules/text/lint/docs/run-shellcheck.md +212 -0
- package/rules/text/lint/docs/run-v8r.md +197 -0
- package/rules/vue/docs/fix.md +127 -0
- package/rules/vue/js/docs/packages.md +335 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +261 -0
- package/rules/worktree/docs/fix.md +161 -0
- package/schemas/rule-meta.json +5 -1
- package/scripts/auto-rules.mjs +7 -4
- package/scripts/coverage-classify/docs/apply.md +202 -0
- package/scripts/coverage-classify/docs/cache.md +203 -0
- package/scripts/coverage-classify/docs/index.md +218 -0
- package/scripts/coverage-classify/docs/prompt.md +132 -0
- package/scripts/coverage-classify/docs/verdict-schema.md +169 -0
- package/scripts/coverage-fix-extract.mjs +122 -0
- package/scripts/coverage-fix.mjs +1 -1
- package/scripts/dispatcher/docs/graph.md +346 -0
- package/scripts/dispatcher/docs/index.md +236 -0
- package/scripts/dispatcher/docs/trace.md +296 -0
- package/scripts/dispatcher/index.mjs +1 -1
- package/scripts/dispatcher/lib/active.mjs +4 -8
- package/scripts/dispatcher/lib/commands.mjs +7 -11
- package/scripts/dispatcher/lib/docs/active.md +348 -0
- package/scripts/dispatcher/lib/docs/artifact.md +232 -0
- package/scripts/dispatcher/lib/docs/budget.md +167 -0
- package/scripts/dispatcher/lib/docs/capability.md +196 -0
- package/scripts/dispatcher/lib/docs/commands.md +210 -0
- package/scripts/dispatcher/lib/docs/events.md +182 -0
- package/scripts/dispatcher/lib/docs/executor.md +190 -0
- package/scripts/dispatcher/lib/docs/flow-lock.md +161 -0
- package/scripts/dispatcher/lib/docs/flow-resolve.md +267 -0
- package/scripts/dispatcher/lib/docs/gate.md +231 -0
- package/scripts/dispatcher/lib/docs/level.md +335 -0
- package/scripts/dispatcher/lib/docs/plan-panel.md +181 -0
- package/scripts/dispatcher/lib/docs/plan.md +200 -0
- package/scripts/dispatcher/lib/docs/planner.md +269 -0
- package/scripts/dispatcher/lib/docs/review.md +255 -0
- package/scripts/dispatcher/lib/docs/reviewer.md +240 -0
- package/scripts/dispatcher/lib/docs/snapshot.md +247 -0
- package/scripts/dispatcher/lib/docs/spec.md +203 -0
- package/scripts/dispatcher/lib/docs/state-store.md +303 -0
- package/scripts/dispatcher/lib/docs/subagent-runner.md +173 -0
- package/scripts/dispatcher/lib/executor.mjs +6 -1
- package/scripts/dispatcher/lib/flow-resolve.mjs +3 -1
- package/scripts/dispatcher/lib/level.mjs +29 -3
- package/scripts/dispatcher/lib/review.mjs +1 -1
- package/scripts/dispatcher/lib/subagent-runner.mjs +5 -3
- package/scripts/docs/auto-rules.md +376 -0
- package/scripts/docs/auto-skills.md +173 -0
- package/scripts/docs/build-agents-commands.md +183 -0
- package/scripts/docs/cli-entry.md +153 -0
- package/scripts/docs/coverage-fix.md +177 -0
- package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +189 -0
- package/scripts/lib/changed-files.mjs +4 -1
- package/scripts/lib/docs/changed-files.md +149 -0
- package/scripts/lib/docs/check-mdc-template-refs.md +222 -0
- package/scripts/lib/docs/check-reporter.md +175 -0
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +157 -0
- package/scripts/lib/docs/discover-checkable-rules.md +165 -0
- package/scripts/lib/docs/ensure-tool.md +254 -0
- package/scripts/lib/docs/generated-markdown.md +275 -0
- package/scripts/lib/docs/gha-workflow.md +326 -0
- package/scripts/lib/docs/inline-template-links.md +303 -0
- package/scripts/lib/docs/list-rule-ids.md +156 -0
- package/scripts/lib/docs/load-cursor-config.md +147 -0
- package/scripts/lib/docs/mirror-parity.md +167 -0
- package/scripts/lib/worktree.mjs +26 -0
- package/scripts/worktree-cli.mjs +12 -2
- package/skills/coverage-fix/SKILL.md +34 -45
- package/skills/docgen/SKILL.md +44 -23
- package/skills/docgen/bench/etalon/firebase_hosting.md +19 -0
- package/skills/docgen/bench/etalon/k8s-tree.md +24 -0
- package/skills/docgen/bench/etalon/overlay-paths.md +24 -0
- package/skills/docgen/js/docgen-ignore.mjs +54 -0
- package/skills/docgen/js/docgen-scan.mjs +37 -21
- package/skills/llm-patch/SKILL.md +23 -2
- package/skills/start-check/SKILL.md +26 -53
- package/skills/start-check/js/check.mjs +211 -0
- package/skills/taze/SKILL.md +9 -3
- package/skills/taze/js/diff.mjs +154 -0
- package/types/bin/n-cursor.d.ts +1 -1
- package/skills/fix-tests/SKILL.md +0 -119
- package/skills/fix-tests/meta.json +0 -1
|
@@ -24,35 +24,46 @@ description: >-
|
|
|
24
24
|
|
|
25
25
|
## Workflow
|
|
26
26
|
|
|
27
|
-
### Крок
|
|
27
|
+
### Крок 0: Визнач команди (з `package.json#scripts`)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
Прочитай кореневий `package.json` і зафіксуй дві команди (перша що існує):
|
|
30
|
+
|
|
31
|
+
- **coverage-команда**: `scripts["coverage"]` → виклик `bun run coverage`; fallback `n-cursor coverage`
|
|
32
|
+
- **test-команда**: `scripts["test"]` → виклик `bun run test` (або те, що в скрипті); fallback `bun test`
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
Далі по тексту «coverage-команда» / «test-команда» = знайдені тут значення.
|
|
35
|
+
|
|
36
|
+
### Крок 1: Згенеруй або переви́користай `COVERAGE.md`
|
|
37
|
+
|
|
38
|
+
**Early-skip.** Якщо `COVERAGE.md` уже існує, свіжий (новіший за останню зміну source/тестів) і має секцію `## Вцілілі мутанти` — можеш одразу перейти до Кроку 2 без повторної генерації. Інакше — згенеруй звіт:
|
|
34
39
|
|
|
35
40
|
```bash
|
|
36
|
-
|
|
41
|
+
n-cursor coverage # або coverage-команда з Кроку 0
|
|
37
42
|
```
|
|
38
43
|
|
|
39
44
|
Ця команда генерує `COVERAGE.md`. Якщо є survived mutants — COVERAGE.md матиме секцію `## Вцілілі мутанти` з JSON-блоком.
|
|
40
45
|
|
|
41
|
-
### Крок 2:
|
|
46
|
+
### Крок 2: Прочитай компактний index вцілілих
|
|
42
47
|
|
|
43
|
-
|
|
48
|
+
> **Не читай `COVERAGE.md` сам.** Файл може важити мегабайти (секція `## Вцілілі
|
|
49
|
+
мутанти` на сотні файлів) — його читання спалило б сотні тисяч токенів. Важкий
|
|
50
|
+
> парсинг несе CLI; ти отримуєш лише крихітний index.
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
```bash
|
|
53
|
+
n-cursor coverage-fix index
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Друкує компактний JSON-масив `[{ "file": "<path>", "mutants": <N> }]` (кілобайти, не мегабайти). Якщо `[]` — зупинись:
|
|
46
57
|
|
|
47
58
|
```
|
|
48
59
|
✓ Жодних вцілілих мутантів — mutation score повний. Coverage завершено.
|
|
49
60
|
```
|
|
50
61
|
|
|
51
|
-
Запам'ятай `prevCount =
|
|
62
|
+
Запам'ятай `prevCount = сума всіх mutants` (загальна кількість вцілілих мутантів).
|
|
52
63
|
|
|
53
|
-
### Крок 3: Для кожного файлу —
|
|
64
|
+
### Крок 3: Для кожного файлу — slice + Agent
|
|
54
65
|
|
|
55
|
-
|
|
66
|
+
Для кожного запису `{ file, mutants }` з index:
|
|
56
67
|
|
|
57
68
|
**3a. Визнач test файл (завжди у `tests/` директорії):**
|
|
58
69
|
|
|
@@ -65,42 +76,20 @@ bun run coverage
|
|
|
65
76
|
- Оновити відносні imports (тепер `../` рівень вгору до source)
|
|
66
77
|
3. Жоден не знайдено → буде створено `<dir>/tests/<basename>.test.mjs`
|
|
67
78
|
|
|
68
|
-
**3b.
|
|
79
|
+
**3b. Отримай готовий зріз-промпт лише для цього файлу:**
|
|
69
80
|
|
|
81
|
+
```bash
|
|
82
|
+
n-cursor coverage-fix slice --file <file>
|
|
70
83
|
```
|
|
71
|
-
Тобі дані вцілілі мутанти зі Stryker для файлу `<file>`.
|
|
72
|
-
Ці мутанти вціліли, бо наявні тести НЕ вловили конкретні зміни коду.
|
|
73
|
-
|
|
74
|
-
**Вихідний код** (`<file>`):
|
|
75
|
-
\`\`\`
|
|
76
|
-
<зміст source-файлу>
|
|
77
|
-
\`\`\`
|
|
78
|
-
|
|
79
|
-
**Наявні тести** (`<test-file>`):
|
|
80
|
-
\`\`\`
|
|
81
|
-
<зміст test-файлу або "файл ще не існує">
|
|
82
|
-
\`\`\`
|
|
83
|
-
|
|
84
|
-
**Вцілілі мутанти** (кожен — зміна коду що НЕ вловлена):
|
|
85
|
-
<для кожного мутанта:>
|
|
86
|
-
- Рядок <line>, колонка <col>: `<original>` → `<replacement>` (тип: <mutantType>)
|
|
87
|
-
|
|
88
|
-
**Завдання:**
|
|
89
|
-
Допиши мінімальні test-cases у файл `<test-file>` які вловлять кожен мутант.
|
|
90
|
-
Правила:
|
|
91
|
-
- НЕ видаляй і НЕ змінюй наявні тести
|
|
92
|
-
- Стиль тестів — відповідно до наявного файлу (той самий фреймворк, describe/test)
|
|
93
|
-
- Якщо файл ще не існує — створи `<dir>/tests/<basename>.test.mjs` з правильними імпортами.
|
|
94
|
-
Приклад: source `src/services/auth-store.js` → import `import { ... } from '../auth-store.js'`
|
|
95
|
-
- Після написання запусти: `bun test <test-file>` і переконайся що тести проходять (виправ якщо падають, 1-2 спроби)
|
|
96
|
-
```
|
|
97
84
|
|
|
98
|
-
|
|
85
|
+
CLI друкує самодостатній промпт **рівно для одного файлу**: список вцілілих мутантів цього файлу (рядок/колонка/`original → replacement`/тип) з контекстом ±3 рядки навколо кожного та фіксовані правила. Це і є «порція під когнітивне навантаження» одного субагента — нічого зайвого.
|
|
86
|
+
|
|
87
|
+
**3c. Запусти Agent** з цим зрізом як промптом, дописавши один рядок про цільовий test-файл із 3a (`<dir>/tests/<basename>.test.mjs`, з правильними відносними imports). Дочекайся завершення.
|
|
99
88
|
|
|
100
89
|
### Крок 4: Перевір що всі тести проходять
|
|
101
90
|
|
|
102
91
|
```bash
|
|
103
|
-
bun test
|
|
92
|
+
bun test # або test-команда з Кроку 0
|
|
104
93
|
```
|
|
105
94
|
|
|
106
95
|
Якщо падають — поверни відповідний Agent з помилкою і попроси виправити.
|
|
@@ -108,15 +97,15 @@ bun test
|
|
|
108
97
|
### Крок 5: Запусти coverage і порівняй
|
|
109
98
|
|
|
110
99
|
```bash
|
|
111
|
-
n-cursor coverage
|
|
100
|
+
n-cursor coverage # або coverage-команда з Кроку 0
|
|
101
|
+
n-cursor coverage-fix index
|
|
112
102
|
```
|
|
113
103
|
|
|
114
|
-
|
|
115
|
-
`newCount = новий масив.length`
|
|
104
|
+
`newCount = сума mutants` зі свіжого index (знову — без читання `COVERAGE.md` вручну).
|
|
116
105
|
|
|
117
106
|
**Рішення:**
|
|
118
107
|
|
|
119
|
-
- `newCount < prevCount` AND iterations < 3 → повтор з Кроку 2 з оновленим
|
|
108
|
+
- `newCount < prevCount` AND iterations < 3 → повтор з Кроку 2 з оновленим index
|
|
120
109
|
- `newCount >= prevCount` → конвергенція:
|
|
121
110
|
|
|
122
111
|
```
|
package/skills/docgen/SKILL.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: docgen
|
|
3
3
|
description: >-
|
|
4
|
-
Обходить проєкт і для кожного кодового файлу (js/mjs/ts/vue/py) пише
|
|
4
|
+
Обходить проєкт і для кожного кодового файлу (js/mjs/ts/vue/py) пише лаконічну поведінкову українську md-документацію у теку docs/ поряд із кодом — диспатчить окремого субагента на кожен файл, за правилами adr/ci4
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# docgen — генерація документації по файлах
|
|
8
8
|
|
|
9
9
|
## Мета
|
|
10
10
|
|
|
11
|
-
Для кожного кодового файлу проєкту створити
|
|
11
|
+
Для кожного кодового файлу проєкту створити лаконічну поведінкову `.md`-документацію у теці `docs/`
|
|
12
12
|
**поряд із самим файлом** (`<dir>/docs/<stem>.md`). Документацію пише **окремий субагент**
|
|
13
13
|
на кожен файл — не один прохід, а батч-диспатч. Джерело правди стилю — правила `adr` і
|
|
14
14
|
`ci4` (`docs/explanation`/`docs/adr`-каталоги з тих правил **не застосовуємо** — доку
|
|
@@ -46,13 +46,10 @@ Tier 3 — лише після завершення всього Tier 2.
|
|
|
46
46
|
npx @nitra/cursor docgen scan
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Команда друкує JSON-масив об'
|
|
49
|
+
Команда друкує JSON-масив об'єктів. Усі шляхи в ньому — відносні до кореня проєкту:
|
|
50
50
|
|
|
51
51
|
```json
|
|
52
|
-
[
|
|
53
|
-
{ "sourcePath": "/abs/src/lib/foo.js", "relSource": "src/lib/foo.js",
|
|
54
|
-
"docPath": "/abs/src/lib/docs/foo.md", "exists": false }
|
|
55
|
-
]
|
|
52
|
+
[{ "sourcePath": "src/lib/foo.js", "docPath": "src/lib/docs/foo.md", "exists": false }]
|
|
56
53
|
```
|
|
57
54
|
|
|
58
55
|
Розпарси JSON.
|
|
@@ -80,7 +77,7 @@ npx @nitra/cursor docgen scan
|
|
|
80
77
|
Промпт кожного субагента (підстав `sourcePath` і `docPath`):
|
|
81
78
|
|
|
82
79
|
```
|
|
83
|
-
Напиши
|
|
80
|
+
Напиши лаконічну технічну документацію для одного файлу коду — орієнтовану на поведінку, не реалізацію.
|
|
84
81
|
|
|
85
82
|
ФАЙЛ-ДЖЕРЕЛО: <sourcePath>
|
|
86
83
|
ЗАПИСАТИ В: <docPath>
|
|
@@ -94,18 +91,32 @@ npx @nitra/cursor docgen scan
|
|
|
94
91
|
- Мова — УКРАЇНСЬКА для всього тексту (заголовки, абзаци, таблиці). Code identifiers,
|
|
95
92
|
шляхи, імена API, команди — лишай як у коді (зазвичай ASCII).
|
|
96
93
|
- ЧИСТИЙ Markdown. Жодних HTML-обгорток (<div>/<span>/класів) — токен-ефективність.
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
-
|
|
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, реактивний стан.
|
|
107
117
|
- НЕ вигадуй деталей, яких немає в коді.
|
|
108
|
-
- Мета —
|
|
118
|
+
- Мета — Behavior Test: читач розуміє, що робить файл і як він вписується в систему,
|
|
119
|
+
без потреби читати реалізацію.
|
|
109
120
|
|
|
110
121
|
Поверни лише підтвердження, що файл <docPath> записано.
|
|
111
122
|
```
|
|
@@ -122,9 +133,14 @@ npx @nitra/cursor docgen modules
|
|
|
122
133
|
|
|
123
134
|
```json
|
|
124
135
|
[
|
|
125
|
-
{
|
|
126
|
-
"
|
|
127
|
-
"
|
|
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
|
+
}
|
|
128
144
|
]
|
|
129
145
|
```
|
|
130
146
|
|
|
@@ -138,7 +154,7 @@ module-summary **завжди регенерується** (це агрегат
|
|
|
138
154
|
ФАЙЛИ МОДУЛЯ (members): <members>
|
|
139
155
|
|
|
140
156
|
Кроки:
|
|
141
|
-
1. Прочитай файлові доки членів модуля. <member> —
|
|
157
|
+
1. Прочитай файлові доки членів модуля. <member> — sourcePath відносно кореня проєкту
|
|
142
158
|
(= поточний CWD); його файлова дока — <CWD>/<dir>/docs/<stem>.md. За потреби зазирни
|
|
143
159
|
в самі файли.
|
|
144
160
|
2. Створи теку для <docPath>, якщо її немає.
|
|
@@ -201,3 +217,8 @@ Tier 3 (домени): <D> доменних доків у docs/.
|
|
|
201
217
|
- Не комітити автоматично — користувач вирішує, коли комітити згенеровану доку.
|
|
202
218
|
- Scanner ігнорує `node_modules`, `dist`, `.git`, `__pycache__`, `coverage`, `.cursor`,
|
|
203
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 лише читає цей список.
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
- Перевіряється лише перший рівень; корінь і глибші рівні поза охопленням.
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
- Кеш у межах прогону; повторні виклики безкоштовні.
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
- Незалежність від ОС (розділювачі зводяться до `/`).
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Глоби, які `docgen` завжди ігнорує.
|
|
3
|
+
*
|
|
4
|
+
* Це окремий snippet-модуль: список правиться тут, scanner лише читає його
|
|
5
|
+
* через predicate. Патерни пишуться в posix-формі відносно кореня проєкту.
|
|
6
|
+
*/
|
|
7
|
+
import picomatch from 'picomatch'
|
|
8
|
+
|
|
9
|
+
/** Базовий список glob-ів для `docgen` ignore. */
|
|
10
|
+
export const DOCGEN_IGNORE_GLOBS = Object.freeze([
|
|
11
|
+
'**/node_modules/**',
|
|
12
|
+
'**/dist/**',
|
|
13
|
+
'.git/**',
|
|
14
|
+
'**/__pycache__/**',
|
|
15
|
+
'**/coverage/**',
|
|
16
|
+
'.cursor/**',
|
|
17
|
+
'.claude/**',
|
|
18
|
+
'.pi/**',
|
|
19
|
+
'.pi-template/**',
|
|
20
|
+
'.worktrees/**',
|
|
21
|
+
'**/benchmarks/**',
|
|
22
|
+
'**/demo/**',
|
|
23
|
+
'**/docs/**'
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
const IGNORE_MATCHERS = DOCGEN_IGNORE_GLOBS.map(glob => picomatch(glob, { dot: true }))
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Нормалізує відносний шлях до posix-формату для glob-matching.
|
|
30
|
+
* @param {string} relPath відносний шлях із path.relative(...)
|
|
31
|
+
* @returns {string} posix-вигляд шляху
|
|
32
|
+
*/
|
|
33
|
+
function toPosixRelPath(relPath) {
|
|
34
|
+
return relPath.split('\\').join('/')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Перевіряє, чи шлях має бути пропущений `docgen`.
|
|
39
|
+
* Для `kind = 'dir'` це працює і на піддерево каталогу, тож glob на кшталт
|
|
40
|
+
* `**\\/demo/**` спрацьовує на `demo/x` під час рекурсивного обходу.
|
|
41
|
+
* @param {string} relPath відносний шлях від кореня проєкту
|
|
42
|
+
* @param {'path'|'dir'} [kind='path'] тип перевірки
|
|
43
|
+
* @returns {boolean} `true`, якщо шлях ігнорується
|
|
44
|
+
*/
|
|
45
|
+
export function isDocgenIgnored(relPath, kind = 'path') {
|
|
46
|
+
if (typeof relPath !== 'string' || relPath.length === 0) {
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
const posixRelPath = toPosixRelPath(relPath)
|
|
50
|
+
if (kind === 'dir') {
|
|
51
|
+
return IGNORE_MATCHERS.some(match => match(posixRelPath) || match(`${posixRelPath}/__docgen__`))
|
|
52
|
+
}
|
|
53
|
+
return IGNORE_MATCHERS.some(match => match(posixRelPath))
|
|
54
|
+
}
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* docgen scanner — детермінований обхід проєкту для скілу `docgen`.
|
|
3
3
|
*
|
|
4
|
-
* Друкує JSON-список кодових файлів із
|
|
5
|
-
* джерелом). Рішення про overwrite/skip приймає скіл —
|
|
6
|
-
* прапор `exists`. LLM/мережі тут немає: уся
|
|
4
|
+
* Друкує JSON-список кодових файлів із відносними `sourcePath`/`docPath`
|
|
5
|
+
* (тека `docs/` поряд із джерелом). Рішення про overwrite/skip приймає скіл —
|
|
6
|
+
* scanner лише лістить і ставить прапор `exists`. LLM/мережі тут немає: уся
|
|
7
|
+
* генерація доки — у субагентах скілу.
|
|
7
8
|
*/
|
|
8
9
|
// eslint-disable-next-line unicorn/import-style
|
|
9
10
|
import path from 'node:path'
|
|
10
11
|
import { existsSync, readdirSync, statSync } from 'node:fs'
|
|
11
12
|
|
|
12
13
|
import { isRunAsCli } from '../../../scripts/cli-entry.mjs'
|
|
14
|
+
import { isDocgenIgnored } from './docgen-ignore.mjs'
|
|
13
15
|
|
|
14
16
|
/** Кодові розширення, для яких генеруємо документацію. */
|
|
15
17
|
const SOURCE_EXTENSIONS = new Set(['.js', '.mjs', '.ts', '.vue', '.py'])
|
|
16
18
|
|
|
17
|
-
/** Теки, які scanner ніколи не заходить (включно з самими `docs/`). */
|
|
18
|
-
const IGNORED_DIRS = new Set([
|
|
19
|
-
'node_modules', 'dist', '.git', '__pycache__', 'coverage', '.cursor', '.claude', 'docs'
|
|
20
|
-
])
|
|
21
|
-
|
|
22
19
|
/** `*.test.*`, `*.spec.*` — тести, документувати не треба. */
|
|
23
20
|
const TEST_FILE_RE = /\.(?:test|spec)\.[^.]+$/u
|
|
24
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Чи корінь має system-wide docs layout.
|
|
24
|
+
* Такий корінь зарезервований під репозиторні docs/adr, docs/explanation тощо,
|
|
25
|
+
* тому file-level docs у нього не пишемо.
|
|
26
|
+
* @param {string} root абсолютний корінь обходу
|
|
27
|
+
* @returns {boolean} true — корінь system-wide docs
|
|
28
|
+
*/
|
|
29
|
+
function isSystemWideDocsRoot(root) {
|
|
30
|
+
return existsSync(path.join(root, 'docs', 'adr')) || existsSync(path.join(root, 'docs', 'explanation'))
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
/**
|
|
26
34
|
* Чи є файл кодовим джерелом для документування.
|
|
27
35
|
* @param {string} fileName базове ім'я файлу
|
|
@@ -35,8 +43,9 @@ export function isSourceFile(fileName) {
|
|
|
35
43
|
|
|
36
44
|
/**
|
|
37
45
|
* Обчислює шлях md-документа для кодового файлу: тека `docs/` поряд із джерелом.
|
|
46
|
+
* Якщо `sourcePath` відносний, `docPath` теж відносний; якщо абсолютний — абсолютний.
|
|
38
47
|
* @param {string} sourcePath шлях до джерела (відносний або абсолютний)
|
|
39
|
-
* @returns {string} шлях до `<dir>/docs/<stem>.md`
|
|
48
|
+
* @returns {string} шлях до `<dir>/docs/<stem>.md` у тому ж просторі шляхів
|
|
40
49
|
*/
|
|
41
50
|
export function docPathForSource(sourcePath) {
|
|
42
51
|
const dir = path.dirname(sourcePath)
|
|
@@ -49,7 +58,7 @@ export function docPathForSource(sourcePath) {
|
|
|
49
58
|
* Синхронний `readdirSync` — детермінований порядок і простий рекурсивний обхід без
|
|
50
59
|
* гонок; обсяг дерева проєкту це дозволяє.
|
|
51
60
|
* @param {string} root абсолютний корінь обходу
|
|
52
|
-
* @returns {Array<{sourcePath:string,
|
|
61
|
+
* @returns {Array<{sourcePath:string, docPath:string, exists:boolean}>} список кандидатів з відносними шляхами
|
|
53
62
|
*/
|
|
54
63
|
export function scanForDocgen(root) {
|
|
55
64
|
const results = []
|
|
@@ -66,16 +75,19 @@ export function scanForDocgen(root) {
|
|
|
66
75
|
}
|
|
67
76
|
for (const entry of entries) {
|
|
68
77
|
const fullPath = path.join(dir, entry.name)
|
|
78
|
+
const relPath = path.relative(root, fullPath)
|
|
69
79
|
if (entry.isDirectory()) {
|
|
70
|
-
if (
|
|
80
|
+
if (isDocgenIgnored(relPath, 'dir')) continue
|
|
71
81
|
walk(fullPath)
|
|
72
82
|
} else if (entry.isFile() && isSourceFile(entry.name)) {
|
|
73
|
-
|
|
83
|
+
if (isSystemWideDocsRoot(root) && path.dirname(relPath) === '.') continue
|
|
84
|
+
const sourcePath = relPath.split(path.sep).join('/')
|
|
85
|
+
if (isDocgenIgnored(sourcePath)) continue
|
|
86
|
+
const docPath = docPathForSource(sourcePath)
|
|
74
87
|
results.push({
|
|
75
|
-
sourcePath
|
|
76
|
-
relSource: path.relative(root, fullPath),
|
|
88
|
+
sourcePath,
|
|
77
89
|
docPath,
|
|
78
|
-
exists: existsSync(docPath)
|
|
90
|
+
exists: existsSync(path.join(root, docPath))
|
|
79
91
|
})
|
|
80
92
|
}
|
|
81
93
|
}
|
|
@@ -95,12 +107,15 @@ export function slugForModule(root, moduleRoot) {
|
|
|
95
107
|
const rel = path.relative(root, moduleRoot)
|
|
96
108
|
// корінь репо: фіксований sentinel 'root'
|
|
97
109
|
if (rel === '') return 'root'
|
|
98
|
-
return rel
|
|
110
|
+
return rel
|
|
111
|
+
.split(path.sep)
|
|
112
|
+
.join('-')
|
|
113
|
+
.replaceAll(/[^\w-]+/gu, '-')
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
/**
|
|
102
117
|
* Знаходить корені модулів — теки з `package.json` (корінь завжди модуль).
|
|
103
|
-
* Ті ж
|
|
118
|
+
* Ті ж ignore-glob правила, тож `package.json` у службових деревах не враховується.
|
|
104
119
|
* @param {string} root абсолютний корінь обходу
|
|
105
120
|
* @returns {string[]} абсолютні шляхи коренів модулів
|
|
106
121
|
*/
|
|
@@ -117,8 +132,9 @@ export function findModuleRoots(root) {
|
|
|
117
132
|
}
|
|
118
133
|
for (const entry of entries) {
|
|
119
134
|
const fullPath = path.join(dir, entry.name)
|
|
135
|
+
const relPath = path.relative(root, fullPath)
|
|
120
136
|
if (entry.isDirectory()) {
|
|
121
|
-
if (
|
|
137
|
+
if (isDocgenIgnored(relPath, 'dir')) continue
|
|
122
138
|
walk(fullPath)
|
|
123
139
|
} else if (entry.isFile() && entry.name === 'package.json' && dir !== root) {
|
|
124
140
|
roots.push(dir)
|
|
@@ -150,17 +166,17 @@ export function nearestModuleRoot(filePath, moduleRoots) {
|
|
|
150
166
|
* Лістить логічні модулі проєкту з членами-файлами і docPath module-summary.
|
|
151
167
|
* Модулі без кодових файлів пропускаються.
|
|
152
168
|
* @param {string} root абсолютний корінь обходу
|
|
153
|
-
* @returns {Array<{moduleRoot:string, relRoot:string, slug:string, docPath:string, members:string[], exists:boolean}>} модулі (members —
|
|
169
|
+
* @returns {Array<{moduleRoot:string, relRoot:string, slug:string, docPath:string, members:string[], exists:boolean}>} модулі (members — sourcePath-и, відносні від root)
|
|
154
170
|
*/
|
|
155
171
|
export function scanForModules(root) {
|
|
156
172
|
const files = scanForDocgen(root)
|
|
157
173
|
const moduleRoots = findModuleRoots(root)
|
|
158
174
|
const byRoot = new Map()
|
|
159
175
|
for (const file of files) {
|
|
160
|
-
const moduleRoot = nearestModuleRoot(file.sourcePath, moduleRoots)
|
|
176
|
+
const moduleRoot = nearestModuleRoot(path.join(root, file.sourcePath), moduleRoots)
|
|
161
177
|
if (moduleRoot === null) continue
|
|
162
178
|
if (!byRoot.has(moduleRoot)) byRoot.set(moduleRoot, [])
|
|
163
|
-
byRoot.get(moduleRoot).push(file.
|
|
179
|
+
byRoot.get(moduleRoot).push(file.sourcePath)
|
|
164
180
|
}
|
|
165
181
|
|
|
166
182
|
const results = []
|
|
@@ -71,6 +71,14 @@ description: >-
|
|
|
71
71
|
з одним рядком пояснення кожна.
|
|
72
72
|
- **Реальні обмеження,** які не виводяться з коду: версії в репо-споживачі,
|
|
73
73
|
inflight-міграції, breaking-change політика, зовнішні залежності.
|
|
74
|
+
- **Change-file flow,** якщо завдання змінює файли у пакетному workspace (код,
|
|
75
|
+
правила, скіли, конфіги, тести — не лише `docs/`): промпт має вимагати
|
|
76
|
+
`npx @nitra/cursor change --bump <major|minor|patch> --section <Added|Changed|Fixed|Removed> --message "<опис>" [--ws <шлях>]`
|
|
77
|
+
і `npx @nitra/cursor fix changelog`. **Ніколи** не інструктуй ручне редагування
|
|
78
|
+
`CHANGELOG.md` чи bump `version` — це робить release flow / CI (деталь —
|
|
79
|
+
`.cursor/rules/n-changelog.mdc`, не дублюй її текст). Якщо потрібна реліз-нота —
|
|
80
|
+
це change-файл `<ws>/.changes/<timestamp>-<rand>.md` з `bump:` і `section:`,
|
|
81
|
+
який створює саме `change` CLI, а не редагування файлу вручну.
|
|
74
82
|
- **Як перевірити** — конкретні команди й специфічні до завдання сигнали
|
|
75
83
|
успіху.
|
|
76
84
|
|
|
@@ -185,6 +193,11 @@ description: >-
|
|
|
185
193
|
агенту**, не людині. Використовуй "зроби", "онови", "додай".
|
|
186
194
|
- **Без секцій-пустушок:** якщо немає `Обмежень` чи `Симптому` — пропусти
|
|
187
195
|
секцію цілком.
|
|
196
|
+
- **Без ручного changelog/version у промпті:** не формулюй у виводі інструкції
|
|
197
|
+
на кшталт "додати запис у `CHANGELOG.md`", "bump `version` вручну" чи
|
|
198
|
+
"оновити `package.json#version`". Зміни у workspace фіксуються винятково
|
|
199
|
+
через change-file flow (`npx @nitra/cursor change …` → `npx @nitra/cursor fix changelog`);
|
|
200
|
+
`version`/`CHANGELOG.md` формує CI.
|
|
188
201
|
- **Не вмикай у промпт:** секрети, `.env`, `node_modules`, бінарні файли,
|
|
189
202
|
довгі логи, дампи `tree`, повні JSON конфігів, цитати існуючих
|
|
190
203
|
helpers/функцій з CWD.
|
|
@@ -219,17 +232,25 @@ description: >-
|
|
|
219
232
|
# Точки правки
|
|
220
233
|
|
|
221
234
|
- `package.json:18` — `engines.node`
|
|
222
|
-
|
|
235
|
+
|
|
236
|
+
# Що треба зробити
|
|
237
|
+
|
|
238
|
+
- Підняти `engines.node` до `>=25`; якщо peer `eslint ^9` несумісний —
|
|
239
|
+
підняти range.
|
|
240
|
+
- Зафіксувати зміну change-файлом (НЕ редагувати `CHANGELOG.md` чи `version`
|
|
241
|
+
вручну): `npx @nitra/cursor change --bump minor --section Changed --message "engines.node >=25"`.
|
|
223
242
|
|
|
224
243
|
# Обмеження
|
|
225
244
|
|
|
226
|
-
- Дотриматись `.cursor/rules/n-js-lint.mdc`.
|
|
245
|
+
- Дотриматись `.cursor/rules/n-js-lint.mdc` і `.cursor/rules/n-changelog.mdc`
|
|
246
|
+
(зміни у workspace = change-файл, не ручний CHANGELOG/version bump).
|
|
227
247
|
- Якщо `eslint ^9` офіційно не підтримує Node 25 — підняти peer range.
|
|
228
248
|
|
|
229
249
|
# Як перевірити
|
|
230
250
|
|
|
231
251
|
- `bun test` — зелений
|
|
232
252
|
- `node -p "require('./package.json').engines.node"` → `>=25`
|
|
253
|
+
- `npx @nitra/cursor fix changelog` → exit `0`
|
|
233
254
|
```
|
|
234
255
|
````
|
|
235
256
|
|