@nitra/cursor 5.3.3 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/.claude-template/settings.template.json +2 -2
  2. package/.pi-template/extensions/n-cursor-adr/docs/index.md +13 -24
  3. package/CHANGELOG.md +17 -0
  4. package/bin/n-cursor.js +43 -22
  5. package/lib/docs/llm.md +23 -12
  6. package/lib/docs/models.md +29 -18
  7. package/lib/docs/omlx-trace.md +51 -0
  8. package/lib/docs/omlx.md +31 -15
  9. package/lib/omlx.mjs +2 -5
  10. package/package.json +1 -1
  11. package/rules/abie/docs/fix.md +17 -11
  12. package/rules/adr/docs/fix.md +25 -140
  13. package/rules/bun/docs/fix.md +18 -151
  14. package/rules/capacitor/docs/fix.md +16 -13
  15. package/rules/capacitor/js/docs/platforms.md +31 -43
  16. package/rules/changelog/docs/fix.md +25 -169
  17. package/rules/ci4/docs/fix.md +11 -14
  18. package/rules/doc-files/doc-files.mdc +60 -0
  19. package/rules/doc-files/docs/fix.md +31 -0
  20. package/rules/doc-files/fix.mjs +19 -0
  21. package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
  22. package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
  23. package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
  24. package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
  25. package/rules/doc-files/js/docs/docgen-extract-anchors.md +45 -0
  26. package/rules/doc-files/js/docs/docgen-extract.md +39 -0
  27. package/rules/doc-files/js/docs/docgen-files-batch.md +35 -0
  28. package/rules/doc-files/js/docs/docgen-gen.md +46 -0
  29. package/rules/doc-files/js/docs/docgen-ignore.md +37 -0
  30. package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
  31. package/rules/doc-files/js/docs/docgen-scan.md +54 -0
  32. package/rules/doc-files/js/docs/lint.md +36 -0
  33. package/rules/doc-files/js/docs/units-js.md +31 -0
  34. package/rules/doc-files/js/docs/units-rs.md +35 -0
  35. package/rules/doc-files/js/docs/units.md +30 -0
  36. package/rules/doc-files/js/lint.mjs +96 -0
  37. package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
  38. package/rules/doc-files/lint/docs/lint.md +37 -0
  39. package/rules/doc-files/lint/lint.mjs +105 -0
  40. package/rules/doc-files/meta.json +1 -0
  41. package/rules/docker/docs/fix.md +21 -161
  42. package/rules/efes/docs/fix.md +23 -194
  43. package/rules/feedback/docs/fix.md +10 -8
  44. package/rules/ga/docs/fix.md +10 -5
  45. package/rules/graphql/docs/fix.md +23 -119
  46. package/rules/hasura/docs/fix.md +19 -5
  47. package/rules/hasura/js/docs/internal_urls.md +34 -307
  48. package/rules/image-avif/docs/fix.md +16 -127
  49. package/rules/image-compress/docs/fix.md +20 -141
  50. package/rules/image-compress/js/docs/package_setup.md +22 -182
  51. package/rules/js-bun-db/docs/fix.md +23 -139
  52. package/rules/js-bun-db/js/docs/safety.md +33 -221
  53. package/rules/js-bun-redis/docs/fix.md +25 -114
  54. package/rules/js-bun-redis/js/docs/imports.md +18 -166
  55. package/rules/js-lint/docs/fix.md +30 -108
  56. package/rules/js-lint/js/docs/lint-findings.md +37 -17
  57. package/rules/js-lint/js/docs/lint.md +22 -238
  58. package/rules/js-lint/js/docs/tooling.md +34 -331
  59. package/rules/js-lint-ci/docs/fix.md +16 -149
  60. package/rules/js-lint-ci/js/docs/lint.md +16 -136
  61. package/rules/js-mssql/docs/fix.md +18 -123
  62. package/rules/js-mssql/js/docs/deps.md +28 -251
  63. package/rules/js-run/docs/fix.md +23 -138
  64. package/rules/js-run/js/docs/runtime.md +24 -378
  65. package/rules/k8s/docs/fix.md +18 -123
  66. package/rules/nginx-default-tpl/docs/fix.md +22 -118
  67. package/rules/nginx-default-tpl/js/docs/template.md +38 -360
  68. package/rules/npm-module/docs/fix.md +27 -89
  69. package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
  70. package/rules/npm-module/js/docs/package_structure.md +36 -258
  71. package/rules/npm-module/js/docs/rule_meta.md +25 -127
  72. package/rules/npm-module/js/docs/skill_meta.md +18 -180
  73. package/rules/php/docs/fix.md +21 -98
  74. package/rules/php/js/docs/tooling.md +20 -143
  75. package/rules/python/docs/fix.md +25 -157
  76. package/rules/python/js/docs/applies.md +20 -98
  77. package/rules/python/js/docs/tooling.md +27 -144
  78. package/rules/rego/docs/fix.md +24 -112
  79. package/rules/rego/js/docs/applies.md +20 -164
  80. package/rules/rego/js/docs/lint.md +15 -110
  81. package/rules/release/docs/fix.md +16 -114
  82. package/rules/rust/docs/fix.md +24 -119
  83. package/rules/rust/js/docs/applies.md +20 -129
  84. package/rules/security/docs/fix.md +21 -78
  85. package/rules/security/js/docs/sample_secret.md +23 -182
  86. package/rules/security/js/docs/trufflehog.md +19 -128
  87. package/rules/style-lint/docs/fix.md +16 -150
  88. package/rules/style-lint/js/docs/lint.md +21 -172
  89. package/rules/style-lint/js/docs/tooling.md +19 -184
  90. package/rules/tauri/docs/fix.md +26 -152
  91. package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
  92. package/rules/tauri/js/docs/tooling.md +20 -217
  93. package/rules/test/docs/fix.md +19 -127
  94. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
  95. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
  96. package/rules/test/js/docs/cargo_mutants_config.md +24 -164
  97. package/rules/test/js/docs/location.md +24 -126
  98. package/rules/test/js/docs/no-process-chdir.md +20 -151
  99. package/rules/test/js/docs/no-relative-fs-path.md +24 -261
  100. package/rules/test/js/docs/stryker_config.md +48 -148
  101. package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
  102. package/rules/text/docs/fix.md +25 -113
  103. package/rules/text/js/docs/forbidden-prettier.md +21 -132
  104. package/rules/text/js/docs/formatting.md +60 -251
  105. package/rules/text/js/docs/lint.md +17 -114
  106. package/rules/vue/docs/fix.md +25 -118
  107. package/rules/vue/js/docs/packages.md +25 -323
  108. package/rules/worktree/docs/fix.md +31 -150
  109. package/scripts/coverage-classify/docs/index.md +23 -209
  110. package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
  111. package/scripts/dispatcher/docs/trace.md +35 -0
  112. package/scripts/docs/auto-rules.md +37 -361
  113. package/scripts/docs/lint-cli.md +12 -13
  114. package/scripts/docs/post-tool-use-fix.md +16 -15
  115. package/scripts/docs/skills-cli.md +26 -23
  116. package/scripts/docs/sync-claude-config.md +94 -34
  117. package/scripts/docs/worktree-cli.md +11 -34
  118. package/scripts/lib/docs/assert-project-root.md +14 -16
  119. package/scripts/lib/docs/changed-files.md +24 -139
  120. package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
  121. package/scripts/lib/docs/rule-predicates.md +20 -17
  122. package/scripts/lib/docs/run-rule-cli.md +14 -18
  123. package/scripts/lib/docs/run-rule.md +13 -20
  124. package/scripts/lib/docs/run-standard-rule.md +12 -15
  125. package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
  126. package/scripts/lib/rule-predicates.mjs +1 -1
  127. package/scripts/sync-claude-config.mjs +4 -1
  128. package/scripts/utils/docs/with-lock.md +19 -12
  129. package/scripts/utils/with-lock.mjs +4 -2
  130. package/skills/doc-aggregate/SKILL.md +2 -2
  131. package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
  132. package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
  133. package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
  134. package/skills/doc-files/.changes/260612-0012.md +5 -0
  135. package/skills/doc-files/.changes/260612-0031.md +5 -0
  136. package/skills/doc-files/.changes/260612-0036.md +5 -0
  137. package/skills/doc-files/.changes/260612-0114.md +5 -0
  138. package/skills/doc-files/SKILL.md +6 -6
  139. package/skills/fix/js/docs/llm-worker.md +17 -15
  140. package/skills/fix/js/docs/orchestrator.md +30 -23
  141. package/skills/fix/js/docs/t0.md +26 -16
  142. package/skills/start-check/js/docs/check.md +26 -22
  143. package/skills/taze/js/docs/diff.md +44 -20
  144. package/skills/doc-files/js/docs/docgen-extract-anchors.md +0 -27
  145. package/skills/doc-files/js/docs/docgen-extract.md +0 -29
  146. package/skills/doc-files/js/docs/docgen-files-batch.md +0 -25
  147. package/skills/doc-files/js/docs/docgen-gen.md +0 -30
  148. package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
  149. package/skills/doc-files/js/docs/docgen-scan.md +0 -25
  150. package/skills/doc-files/js/docs/units-rs.md +0 -35
  151. /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
  152. /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
  153. /package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +0 -0
  154. /package/{skills → rules}/doc-files/js/docgen-gen.mjs +0 -0
  155. /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
  156. /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
  157. /package/{skills → rules}/doc-files/js/units.mjs +0 -0
@@ -1,376 +1,52 @@
1
+ ---
2
+ docgen:
3
+ source: npm/scripts/auto-rules.mjs
4
+ crc: 972b56fc
5
+ score: 90
6
+ ---
7
+
1
8
  # auto-rules.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль `npm/scripts/auto-rules.mjs` це **движок автодетекту правил** для конфігурації
6
- `.n-cursor.json`. Його задача — за метаданими з `npm/rules/<id>/meta.json` і за станом
7
- проєкту-користувача (вміст файлів та структура дерева) вирахувати, які правила слід
8
- автоматично активувати в конфізі CLI `n-cursor`.
9
-
10
- Архітектура data-driven: список правил, порядок і граф залежностей **не зашиваються в код**
11
- — вони виводяться з `meta.json` кожного правила в `npm/rules/<id>/`. Кожне правило в `meta.json`
12
- має поле `auto` з однією зі специфікацій активації (`always`, `glob`, `predicate`, `rules`).
13
-
14
- Основні відповідальності модуля:
15
-
16
- - **Discovery**: сканування `npm/rules/<id>/meta.json` і побудова мапи `RULE_AUTO_ACTIVATION`
17
- з нормалізованими spec-ами автоактивації (`discoverRuleAutoActivation`).
18
- - **Експорт стабільного порядку правил**: алфавітний `AUTO_RULE_ORDER` замість хардкод-масиву.
19
- - **Експорт графа залежностей**: `AUTO_RULE_DEPENDENCIES` із spec-ів типу `rules`.
20
- - **Збір content-фактів**: обхід дерева репо й збір ознак (`hasBunSqlImport`,
21
- `hasGqlTaggedTemplates`, `hasHasuraConfig`, `hasRegoFile`, `hasTempoDir`)
22
- через `collectAutoRuleFacts` — для зворотної сумісності з прямими читачами та для
23
- предикатів типу `gqlTaggedTemplate`/`hasuraConfigMarker`/`jsBunDbSignal`.
24
- - **Збір relative-posix-шляхів**: `collectRepoPaths` (повертає і файли, і каталоги — для
25
- glob-матчингу, який може цілитися в порожні директорії типу `npm`, `k8s`, `.github/workflows`).
26
- - **Обчислення активних правил**: `detectAutoRules` запускає `specMatches` для кожного
27
- правила (з пропуском типу `rules`), потім транзитивно розгортає залежності через
28
- `resolveRuleDependencies` і повертає id у стабільному порядку.
29
- - **Злиття з конфігом**: `mergeConfigWithAutoDetected` лише **додає** в `rules`/`skills`
30
- виявлені id, поважаючи `disable-rules`/`disable-skills` й нормалізацію legacy-id
31
- через `migrateRuleIds`.
32
-
33
- Автодетект **скілів** (не правил) — у сусідньому модулі `./auto-skills.mjs`; цей файл
34
- лише приймає вже виявлені `detectedSkills` у `mergeConfigWithAutoDetected`.
35
-
36
- ## Експорти / API
37
-
38
- Реекспорти з `./lib/rule-meta-helpers.mjs` (для одного публічного entry-point):
39
-
40
- - `detectLegacyRuleIds`
41
- - `getRepositoryUrl`
42
- - `isMonorepoPackage`
43
- - `migrateRuleIds`
44
- - `normalizeIdList`
45
- - `RULE_MIGRATIONS`
46
-
47
- Власні експорти модуля:
48
-
49
- | Експорт | Тип | Призначення |
50
- | ----------------------------- | ------------------------------------------- | ---------------------------------------------------------------------- |
51
- | `discoverRuleAutoActivation` | `function` | Скан `npm/rules/<id>/meta.json` → мапа id → `RuleAutoSpec`. |
52
- | `AUTO_RULE_ORDER` | `readonly string[]` (frozen) | Алфавітний порядок усіх правил із розпізнаним `auto`. |
53
- | `AUTO_RULE_DEPENDENCIES` | `readonly Record<string,string[]>` (frozen) | Граф залежностей із spec-ів типу `rules`. |
54
- | `collectAutoRuleFacts` | `async function` | Обхід дерева й збір content-фактів. |
55
- | `detectAutoRules` | `async function` | Головна функція: повертає `{ rules: string[] }` за `meta.json` правил. |
56
- | `mergeConfigWithAutoDetected` | `function` | Зливає виявлені rules+skills у конфіг із поправкою на legacy-id. |
57
-
58
- Внутрішні (не експортовані):
59
-
60
- - `sourceContentHasBunSqlImport`
61
- - `shouldScanFileForGql`, `updateGqlFactFromFile`
62
- - `shouldScanFileForBunSql`, `updateBunSqlFactFromFile`
63
- - `updateHasuraFactFromFile`
64
- - `processFileEntry`
65
- - `collectRepoPaths`
66
- - `resolveRuleDependencies`
67
- - `specMatches`
68
-
69
- Внутрішні константи:
70
-
71
- - `PACKAGE_ROOT` — корінь пакету (`dirname(dirname(fileURLToPath(import.meta.url)))`).
72
- - `RULES_DIR` — `${PACKAGE_ROOT}/rules`.
73
- - `RULE_AUTO_ACTIVATION` — результат `discoverRuleAutoActivation()`, обчислюється на load-time.
74
- - `HASURA_CONFIG_MARKER = 'metadata_directory: metadata'`.
75
- - `REGO_RE = /\.rego$/iu`.
76
- - `IGNORED_DIR_NAMES = new Set(['node_modules', '.git', '.next', '.turbo'])`.
77
- - `DEFAULT_DISABLED_LIST = Object.freeze([])`.
78
-
79
- ## Функції
80
-
81
- ### `discoverRuleAutoActivation(rulesDir = RULES_DIR)`
82
-
83
- - **Сигнатура**: `(rulesDir?: string) => Record<string, RuleAutoSpec>`
84
- - **Параметри**:
85
- - `rulesDir` — override кореня `rules/` (для тестів). За замовчуванням — `RULES_DIR`.
86
- - **Повертає**: мапу `id → RuleAutoSpec` (лише правила, де `parseRuleAutoSpec(raw.auto)`
87
- повернув не-null).
88
- - **Side effects**: синхронне читання `readdirSync` й читання `meta.json` кожного підкаталогу
89
- через `readRuleMetaRaw`. Не модифікує файли.
90
- - **Обробка помилок**: якщо `rulesDir` недоступний — повертає порожній обʼєкт. Пропускає
91
- директорії з імʼям, що починається на `.`, і не-директорії.
92
-
93
- ### `AUTO_RULE_ORDER` / `AUTO_RULE_DEPENDENCIES`
94
-
95
- Не функції — обчислюються одноразово на load-time:
96
-
97
- - `AUTO_RULE_ORDER = Object.freeze(Object.keys(RULE_AUTO_ACTIVATION).toSorted(localeCompare))`
98
- - `AUTO_RULE_DEPENDENCIES = Object.freeze(Object.fromEntries(...))` — будується з
99
- entries, де `'rules' in spec` (тобто spec типу C — звичайне посилання на залежні правила).
100
- Значення кожного ключа — заморожений масив id залежностей.
101
-
102
- ### `sourceContentHasBunSqlImport(content, relativePath)`
103
-
104
- - **Сигнатура**: `(content: string, relativePath: string) => boolean`
105
- - **Параметри**:
106
- - `content` — повний вміст файлу.
107
- - `relativePath` — шлях posix відносно кореня репо.
108
- - **Повертає**: `true`, якщо в тексті є `import { sql }` або `import { SQL }` з `"bun"`.
109
- - **Side effects**: жодних.
110
- - **Логіка**: викликає `contentForVueImportScan(content, relativePath)` (витягує `<script>`
111
- для `.vue`) і передає в `textHasBunSqlImport`.
112
-
113
- ### `shouldScanFileForGql(relPath, facts)`
114
-
115
- - **Сигнатура**: `(relPath: string, facts: { hasGqlTaggedTemplates: boolean }) => boolean`
116
- - **Повертає**: `true`, лише якщо факт ще не встановлено і файл — підходяще джерело
117
- (`isGqlScanSourceFile`) та не входить у виключення (`shouldSkipFileForGqlScan`).
118
- - **Side effects**: жодних.
119
-
120
- ### `updateGqlFactFromFile(absPath, relPath, facts)`
121
-
122
- - **Сигнатура**: `async (absPath: string, relPath: string, facts: { hasGqlTaggedTemplates: boolean }) => Promise<void>`
123
- - **Side effects**: читає файл (`readFile utf8`), мутує `facts.hasGqlTaggedTemplates = true`,
124
- якщо `sourceFileHasGqlTaggedTemplate` дав true.
125
- - **Обробка помилок**: `try/catch` — пошкоджені/недоступні файли мовчки ігноруються.
126
-
127
- ### `shouldScanFileForBunSql(relPath, facts)`
128
-
129
- - **Сигнатура**: `(relPath: string, facts: { hasBunSqlImport: boolean }) => boolean`
130
- - **Повертає**: `true`, якщо факт ще не встановлено і файл-кандидат (ті самі правила,
131
- що для gql: `isGqlScanSourceFile` + `!shouldSkipFileForGqlScan`).
132
- - **Side effects**: жодних.
133
-
134
- ### `updateBunSqlFactFromFile(absPath, relPath, facts)`
135
-
136
- - **Сигнатура**: `async (absPath: string, relPath: string, facts: { hasBunSqlImport: boolean }) => Promise<void>`
137
- - **Side effects**: читає файл, мутує `facts.hasBunSqlImport = true` за позитивної відповіді
138
- `sourceContentHasBunSqlImport`.
139
- - **Обробка помилок**: `try/catch` — мовчки ігнорує помилки I/O.
140
-
141
- ### `updateHasuraFactFromFile(absPath, fileName, facts)`
142
-
143
- - **Сигнатура**: `async (absPath: string, fileName: string, facts: { hasHasuraConfig: boolean }) => Promise<void>`
144
- - **Логіка**: якщо факт уже встановлений або `fileName !== 'config.yaml'` — ранній вихід.
145
- Інакше читає файл і мутує `facts.hasHasuraConfig = true`, якщо вміст містить
146
- підрядок `'metadata_directory: metadata'` (`HASURA_CONFIG_MARKER`).
147
- - **Side effects**: один `readFile`, мутація `facts`.
148
- - **Обробка помилок**: `try/catch` — мовчки ігнорує.
149
-
150
- ### `processFileEntry(absPath, root, facts)`
151
-
152
- - **Сигнатура**: `async (absPath: string, root: string, facts: AutoRuleFacts) => Promise<void>`
153
- - **Параметри**:
154
- - `absPath` — абсолютний шлях файлу.
155
- - `root` — абсолютний корінь репо.
156
- - `facts` — обʼєкт `{ hasBunSqlImport, hasGqlTaggedTemplates, hasHasuraConfig, hasRegoFile }`.
157
- - **Логіка** для одного файлу:
158
- 1. Обчислює `rel = relative(root, absPath)` з нормалізацією `\\` → `/`.
159
- 2. Якщо шлях матчить `\.rego$` — встановлює `facts.hasRegoFile = true`.
160
- 3. Якщо `shouldScanFileForGql` — викликає `updateGqlFactFromFile`.
161
- 4. Якщо `shouldScanFileForBunSql` — викликає `updateBunSqlFactFromFile`.
162
- 5. Завжди викликає `updateHasuraFactFromFile` (вона сама перевірить `fileName`).
163
- - **Side effects**: до 3 потенційних `readFile` + мутації `facts`.
164
-
165
- ### `collectAutoRuleFacts(root)` — **експортована**
166
-
167
- - **Сигнатура**: `async (root: string) => Promise<{ hasBunSqlImport: boolean, hasGqlTaggedTemplates: boolean, hasHasuraConfig: boolean, hasRegoFile: boolean, hasTempoDir: boolean }>`
168
- - **Параметри**: `root` — абсолютний шлях кореня репо.
169
- - **Повертає**: Promise з обʼєктом content-фактів.
170
- - **Логіка**:
171
- 1. Ініціалізує `facts` усіма `false`.
172
- 2. Внутрішня рекурсія `walk(dir)` через `readdir({ withFileTypes: true })`:
173
- - якщо `entry.isDirectory()` і імʼя не в `IGNORED_DIR_NAMES`:
174
- - якщо `entry.name === 'tempo'` — встановлює `facts.hasTempoDir = true`;
175
- - рекурсивний `await walk(absPath)`;
176
- - якщо `entry.isFile()` — `await processFileEntry(absPath, root, facts)`.
177
- 3. Помилки `readdir` мовчки призводять до `return` (пропускаємо каталог).
178
- - **Side effects**: рекурсивний обхід FS, читання вмісту файлів-кандидатів.
179
- - **Зворотна сумісність**: `hasRegoFile`/`hasTempoDir` лишаються для прямих читачів
180
- (тести, зовнішній код), хоча активація відповідних правил уже data-driven.
181
-
182
- ### `collectRepoPaths(root)` — внутрішня
183
-
184
- - **Сигнатура**: `async (root: string) => Promise<string[]>`
185
- - **Повертає**: масив relative-posix-шляхів **і файлів, і каталогів**.
186
- - **Чому й каталоги**: частина glob-спеків указує на самі директорії (`npm`, `k8s`,
187
- `.github/workflows`), які можуть бути порожніми — без цього правила `npm-module`, `k8s`,
188
- `ga` не активовувалися б на дереві без файлів усередині.
189
- - **Логіка**: внутрішня `walk(dir)` через `readdir({ withFileTypes: true })`. На директорії
190
- (не в `IGNORED_DIR_NAMES`) — пушить шлях і рекурсує. На файл — пушить шлях. Помилки
191
- `readdir` мовчки повертають з гілки.
192
-
193
- ### `resolveRuleDependencies(detectedRules, addRule)`
194
-
195
- - **Сигнатура**: `(detectedRules: string[], addRule: (ruleId: string) => void) => void`
196
- - **Параметри**:
197
- - `detectedRules` — мутабельний список вже зібраних id (мутується через `addRule`).
198
- - `addRule` — callback з фабрики, що поважає `disable-rules` й дублі.
199
- - **Логіка**: fixed-point loop — повторно проходить усіма парами `[ruleId, deps]` з
200
- `AUTO_RULE_DEPENDENCIES`. На кожному проході: якщо правило ще не в детекті й **усі**
201
- залежності вже в детекті — викликає `addRule(ruleId)` і, якщо довжина зросла,
202
- встановлює `changed = true` для наступної ітерації.
203
- - **Гарантія**: дозволяє транзитивні ланцюги `a → b → c` незалежно від порядку оголошення
204
- в meta-файлах.
205
- - **Side effects**: викликає переданий `addRule` (який мутує `detectedRules`).
206
-
207
- ### `specMatches(spec, ctx)`
208
-
209
- - **Сигнатура**: `async (spec: RuleAutoSpec, ctx: { root: string, facts: object, paths: string[], packageJsonParsed: unknown }) => Promise<boolean>`
210
- - **Логіка** — диспетчинг за дискримінантним ключем spec:
211
- - `'always' in spec` → `true` безумовно.
212
- - `'glob' in spec` → конвертує кожен glob у regex через `globToRegex`; повертає `true`,
213
- якщо **будь-який** шлях у `ctx.paths` матчить **будь-який** regex.
214
- - `'predicate' in spec` → шукає функцію `RULE_PREDICATES[spec.predicate]`. Якщо не знайдено
215
- — `false`. Інакше викликає за іменем предиката з різними сигнатурами:
216
- - `repoUrlMarker` → `fn(ctx.packageJsonParsed, spec.arg)` — читає корений `package.json`
217
- - arg-маркер.
218
- - `gqlTaggedTemplate` або `hasuraConfigMarker` → `fn(ctx.facts)` — content-факти.
219
- - `jsBunDbSignal` → `fn(ctx.root, ctx.facts)` — комбінований сигнал.
220
- - інші (`depInAnyPackageJson`, `nestedPackageWithoutVite`) → `fn(ctx.root, spec.arg)`.
221
- - Якщо жодна гілка не спрацювала — `false`.
222
- - **Side effects**: залежать від конкретного предиката (можуть читати FS).
223
-
224
- ### `detectAutoRules({ root, availableRules, packageJsonParsed, disableRules })` — **експортована**
225
-
226
- - **Сигнатура**: `async (params: { root: string, availableRules: string[], packageJsonParsed: unknown, disableRules?: string[] }) => Promise<{ rules: string[] }>`
227
- - **Параметри**:
228
- - `root` — абсолютний корінь репо-аналізованого проєкту.
229
- - `availableRules` — перелік доступних правил із пакету `n-cursor`.
230
- - `packageJsonParsed` — розпарсений кореневий `package.json` користувача (або `null`).
231
- - `disableRules` — список з конфігу (за замовчуванням `DEFAULT_DISABLED_LIST = []`).
232
- - **Повертає**: `{ rules: string[] }` — id у стабільному порядку `AUTO_RULE_ORDER`.
233
- - **Логіка**:
234
- 1. `facts = await collectAutoRuleFacts(root)` — content-факти.
235
- 2. `paths = await collectRepoPaths(root)` — relative-posix-шляхи для glob.
236
- 3. `normalizedRules` — `Set` доступних id (lower-case, trim) — для перевірки доступності.
237
- 4. `disableRulesSet` — `Set` з `disableRules`.
238
- 5. `detectedRules: string[] = []` + локальна функція `addRule(ruleId)`:
239
- - пропускає id, якщо його **немає в `normalizedRules`**, або є в `disableRulesSet`,
240
- або вже в `detectedRules`;
241
- - інакше пушить.
242
- 6. Перший прохід — над `Object.entries(RULE_AUTO_ACTIVATION)`:
243
- - пропускає spec-и типу `rules` (вони обробляються в наступному кроці);
244
- - для решти — `await specMatches(spec, { root, facts, paths, packageJsonParsed })`;
245
- - якщо true — `addRule(ruleId)`.
246
- 7. `resolveRuleDependencies(detectedRules, addRule)` — транзитивне розгортання.
247
- 8. Фінальне `rules = AUTO_RULE_ORDER.filter(r => detectedRules.includes(r))` — стабільний порядок.
248
- - **Side effects**: повний обхід дерева репо (двічі — у `collectAutoRuleFacts` і
249
- `collectRepoPaths`) + читання вмісту файлів-кандидатів + потенційні читання з боку
250
- предикатів.
251
-
252
- ### `mergeConfigWithAutoDetected({ config, detectedRules, detectedSkills })` — **експортована**
253
-
254
- - **Сигнатура**: `(params: { config: { rules: unknown, skills?: unknown, ['disable-rules']?: unknown, ['disable-skills']?: unknown }, detectedRules: string[], detectedSkills: string[] }) => { rules: string[], skills: string[] } & Record<string, unknown>`
255
- - **Логіка**:
256
- 1. `existingRules = migrateRuleIds(normalizeIdList(config.rules))` — нормалізує і
257
- мігрує legacy-id.
258
- 2. `existingSkills = normalizeIdList(config.skills)`.
259
- 3. `disableRules = migrateRuleIds(normalizeIdList(config['disable-rules']))`.
260
- 4. `disableSkills = normalizeIdList(config['disable-skills'])`.
261
- 5. Будує `rules = [...existingRules]`, додає кожен `detectedRules[i]`, якщо його ще
262
- немає в `rules` **і** він не в `disableRules`.
263
- 6. Аналогічно для `skills` (з `disableSkills`).
264
- 7. `normalized = { rules, skills }`. Додає `'disable-rules'`/`'disable-skills'` лише
265
- якщо вони не порожні.
266
- - **Семантика**: **не прибирає** елементи, що були в конфізі вручну (idempotent додавання).
267
- - **Side effects**: жодних — pure-функція над переданим конфігом.
268
-
269
- ## Залежності
270
-
271
- ### Сторонні / Node.js (stdlib)
272
-
273
- - `node:fs` → `readdirSync` (для синхронного скану `rules/` на load-time).
274
- - `node:fs/promises` → `readdir`, `readFile` (асинхронний обхід проєкту й читання вмісту).
275
- - `node:path` → `basename`, `dirname`, `join`, `relative` (нормалізація шляхів).
276
- - `node:url` → `fileURLToPath` (резолв `PACKAGE_ROOT` з `import.meta.url`).
277
-
278
- ### Внутрішні модулі пакету
279
-
280
- - `../rules/npm-module/js/package_structure.mjs` → `globToRegex` — конвертація glob у regex
281
- для spec типу `glob`.
282
- - `../rules/js-bun-db/lib/bun-sql-scan.mjs` → `textHasBunSqlImport` — детекція `import { sql }`
283
- з `"bun"` у текстовому вмісті.
284
- - `../rules/graphql/lib/graphql-gql-scan.mjs` → `isGqlScanSourceFile`,
285
- `shouldSkipFileForGqlScan`, `sourceFileHasGqlTaggedTemplate` — політика сканування для gql.
286
- - `../rules/vue/lib/vue-forbidden-imports.mjs` → `contentForVueImportScan` — витягування
287
- `<script>` для `.vue` перед сканом імпортів.
288
- - `./lib/rule-meta.mjs` → `parseRuleAutoSpec`, `readRuleMetaRaw` — парсинг `meta.json` правил.
289
- - `./lib/rule-meta-helpers.mjs` → `migrateRuleIds`, `normalizeIdList` (використання) +
290
- реекспорти `detectLegacyRuleIds`, `getRepositoryUrl`, `isMonorepoPackage`, `RULE_MIGRATIONS`.
291
- - `./lib/rule-predicates.mjs` → `RULE_PREDICATES` — реєстр незводимих предикатів за іменами.
292
-
293
- ### Дотичні (не імпортуються прямо, але семантично повʼязані)
294
-
295
- - `./auto-skills.mjs` — автодетект скілів; результати приймає `mergeConfigWithAutoDetected`
296
- через `detectedSkills`.
297
- - `npm/rules/<id>/meta.json` — джерело даних для `discoverRuleAutoActivation`.
298
-
299
- ## Потік виконання / Використання
300
-
301
- ### Сценарій 1: автогенерація `.n-cursor.json`
302
-
303
- Очікувана послідовність викликача (наприклад, CLI `n-cursor init`):
304
-
305
- 1. Зчитати поточний `.n-cursor.json` користувача (або порожній обʼєкт).
306
- 2. Зчитати кореневий `package.json` користувача (parse → `packageJsonParsed`).
307
- 3. Отримати список доступних правил із пакету (наприклад, із `npm/rules/*/`).
308
- 4. Викликати `const { rules } = await detectAutoRules({ root, availableRules, packageJsonParsed, disableRules })`.
309
- 5. Викликати `detectAutoSkills(...)` з `./auto-skills.mjs` (поза цим файлом) → `detectedSkills`.
310
- 6. `const normalized = mergeConfigWithAutoDetected({ config, detectedRules: rules, detectedSkills })`.
311
- 7. Записати `normalized` назад у `.n-cursor.json`.
12
+ Файл читає метадані з `npm/rules/<id>/meta.json` для автоматичного визначення порядку та залежностей правил. Він обчислює spec активації для кожного правила, використовуючи дані з `RULE_PREDICATES` з `lib/rule-predicates.mjs`, визначає активні правила, обчислює залежності та об'єднує конфігурацію з виявленими правилами та поправками на legacy-id. Код спирається на конфіги `.n-cursor.json`, `meta.json` та `package.json`.
312
13
 
313
- ### Сценарій 2: програмне читання фактів
14
+ ## Поведінка
314
15
 
315
- Якщо потрібно лише сирі content-факти (наприклад, для іншого скрипта):
16
+ discoverRuleAutoActivation
17
+ Читає meta-дані з файлів npm/rules/<id>/meta.json для визначення автоактивації правил.
316
18
 
317
- ```
318
- import { collectAutoRuleFacts } from 'n-cursor/scripts/auto-rules.mjs'
319
- const facts = await collectAutoRuleFacts(process.cwd())
320
- // facts.hasBunSqlImport, facts.hasGqlTaggedTemplates, facts.hasHasuraConfig,
321
- // facts.hasRegoFile, facts.hasTempoDir
322
- ```
19
+ AUTO_RULE_ORDER
20
+ Повертає алфавітний порядок для правил.
323
21
 
324
- ### Сценарій 3: інспекція реєстру правил
22
+ AUTO_RULE_DEPENDENCIES
23
+ Повертає граф залежностей між правилами.
325
24
 
326
- ```
327
- import { discoverRuleAutoActivation, AUTO_RULE_ORDER, AUTO_RULE_DEPENDENCIES } from 'n-cursor/scripts/auto-rules.mjs'
328
- const reg = discoverRuleAutoActivation() // мапа id → spec
329
- const order = AUTO_RULE_ORDER // алфавітний список усіх правил із auto
330
- const deps = AUTO_RULE_DEPENDENCIES // граф залежностей (frozen)
331
- ```
25
+ collectAutoRuleFacts
26
+ Збирає контент-факти для предикатів, включаючи сканування GQL, Bun SQL та налаштувань Hasura.
332
27
 
333
- ### Послідовність всередині `detectAutoRules`
28
+ detectAutoRules
29
+ Визначає активні правила на основі spec, перевіряючи їх проти згенерованих фактів.
334
30
 
335
- ```
336
- collectAutoRuleFacts(root) ──┐
337
- ├─→ ctx = { root, facts, paths, packageJsonParsed }
338
- collectRepoPaths(root) ──────┘
339
-
340
-
341
- для кожного [ruleId, spec] у RULE_AUTO_ACTIVATION (крім spec типу 'rules'):
342
- specMatches(spec, ctx) → addRule(ruleId)
343
-
344
-
345
- resolveRuleDependencies(detectedRules, addRule) // fixed-point loop
346
-
347
-
348
- rules = AUTO_RULE_ORDER.filter(r => detectedRules.includes(r))
349
-
350
-
351
- return { rules }
352
- ```
31
+ mergeConfigWithAutoDetected
32
+ Доповнює конфігурацію, додаючи визначені автоправила та налаштування, з урахуванням legacy-ID.
353
33
 
354
- ### Інваріанти
34
+ ## Публічний API
355
35
 
356
- - **Стабільний порядок**: фінальний `rules` завжди впорядкований за `AUTO_RULE_ORDER`
357
- (алфавіт). Це гарантує детермінованість для diff-ів конфігу.
358
- - **Поважання `disable-rules`**: правило, явно вимкнене користувачем, не зʼявиться навіть
359
- якщо його spec матчить фільтр у `addRule`.
360
- - **Тільки додавання**: `mergeConfigWithAutoDetected` ніколи не видаляє вручну задані
361
- елементи (idempotent).
362
- - **Зворотна сумісність**: `hasRegoFile`/`hasTempoDir` лишаються в експортуваному
363
- обʼєкті `collectAutoRuleFacts` навіть якщо вже не використовуються у власному
364
- диспетчингудля прямих читачів.
365
- - **Тиха толерантність до помилок FS**: `try/catch` навколо `readFile`/`readdir` —
366
- пошкоджені/недоступні файли не валять детект.
36
+ discoverRuleAutoActivation Скан `npm/rules/<id>/meta.json` мапа id → RuleAutoSpec (лише правила з розпізнаним auto).
37
+ AUTO_RULE_ORDER Стабільний алфавітний порядок (замість хардкод-масиву).
38
+ AUTO_RULE_DEPENDENCIES Граф залежностей із meta (Type C) замість хардкод-константи.
39
+ collectAutoRuleFacts Обходить дерево проєкту, збираючи content-факти для предикатів автоувімкнення.
40
+ hasRegoFile Флаг наявності файлу Rego.
41
+ hasTempoDir — Флаг наявності директорії Tempo.
42
+ hasBunSqlImport Булеве значення про імпорт BunSQL.
43
+ hasGqlTaggedTemplates Булеве значення про наявність GQL-тегів.
44
+ hasHasuraConfigБулеве значення про конфігурацію Hasura.
367
45
 
368
- ### Архітектурні нотатки
46
+ ## Гарантії поведінки
369
47
 
370
- - **Load-time скан**: `RULE_AUTO_ACTIVATION = discoverRuleAutoActivation()` виконується
371
- **при імпорті модуля** (синхронно через `readdirSync`). Це означає, що зміни в
372
- `npm/rules/<id>/meta.json` після старту процесу не підхопляться без перезавантаження.
373
- - **Подвійний обхід дерева**: `collectAutoRuleFacts` і `collectRepoPaths` йдуть по дереву
374
- окремо це навмисно: різні задачі (content-факти vs glob-paths) і різні фільтри.
375
- - **Type C spec (`rules`)** обробляється виключно в `resolveRuleDependencies` — у першому
376
- проході над `RULE_AUTO_ACTIVATION` ці spec-и пропускаються (`if ('rules' in spec) continue`).
48
+ - Read-only: файл не виконує операцій запису у файлову систему.
49
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
50
+ - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
51
+ - Свідомо пропускає шляхи: `.git`, `node_modules`.
52
+ - Не звертається до мережі.
@@ -1,31 +1,30 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/scripts/lint-cli.mjs
4
- crc: 3724b90c
4
+ crc: d4a7562d
5
+ score: 100
5
6
  ---
6
7
 
7
8
  # lint-cli.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Файл забезпечує оркестрацію виконання правил лінтингу для проєкту. Він сканує правила, визначені в файлах `meta.json`, та викликає відповідні файли `lint.mjs` для перевірки коду. Це дозволяє автоматично виявляти та повідомляти про помилки в коді на основі набору визначених правил.
12
+ Файл оркеструє запуск `n-cursor lint` (quick) або `n-cursor lint-ci` (full). Він збирає налаштування правил з файлів `meta.json` і послідовно виконує перевірку відповідно до визначених режимів.
12
13
 
13
14
  ## Поведінка
14
15
 
15
- selectLintRules: Вибирає id правил для фази, алфавітно.
16
- runLint: Запускає lint-оркестрацію. Збирає змінені файли, якщо потрібно, та запускає lint для кожного правила, яке відповідає вибраній фазі.
16
+ selectLintRules
17
+ Вибирає id правил для фази алфавітним порядком
18
+
19
+ runLint
20
+ Запускає lint-оркестрацію
17
21
 
18
22
  ## Публічний API
19
23
 
20
- - selectLintRules — Вибирає набір правил для перевірки.
21
- - runLint — Запускає процес перевірки.
24
+ selectLintRules — Вибирає ідеальну послідовність правил для фази, упорядковуючи їх за алфавітом.
25
+ runLint — Запускає повний процес перевірки (lint-оркестрацію).
22
26
 
23
27
  ## Гарантії поведінки
24
28
 
25
- - Оркестратор запускає правила лінтингу, визначені в файлах `rules/<id>/meta.json`.
26
- - Для режиму `quick` оркестратор обробляє лише змінені файли, визначені за допомогою `git diff`.
27
- - Для режиму `ci` оркестратор обробляє весь проєкт.
28
- - Порядок виконання правил визначається алфавітним порядком імен файлів `rules/<id>/js/lint.mjs`.
29
- - Перший виклик функції `lint` повертає ненульове значення, що призводить до зупинки виконання.
30
- - Режим `quick` не використовує кешування.
31
- - Режим `ci` не використовує кешування.
29
+ - Read-only: файл не виконує операцій запису у файлову систему.
30
+ - Не звертається до мережі.
@@ -1,33 +1,34 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/scripts/post-tool-use-fix.mjs
4
- crc: 50bf19e1
4
+ crc: f40e8a8b
5
+ score: 95
5
6
  ---
6
7
 
7
8
  # post-tool-use-fix.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Файл забезпечує точкову маршрутизацію `npx @nitra/cursor fix` для конкретних файлів, що були змінені. Він запускає цей процес після редагування, щоб уникнути затримки, спричиненої попереднім синхронним хуком. Це дозволяє швидко та ефективно виправляти правила стилю коду для змінених файлів.
12
+ Файл забезпечує точкова маршрутизацію шляху до правил для виправлення коду через хук PostToolUse. Він ініціює запуск команди `npx @nitra/cursor fix` для виправлення коду після зміни файлу.
12
13
 
13
14
  ## Поведінка
14
15
 
15
- `routeFilePathToRules`: повертає список ID правил `npm/rules/<id>`, які слід застосувати до вказаного шляху файлу, використовуючи відповідні шаблони glob.
16
- `runPostToolUseFixCli`: запускає `npx @nitra/cursor fix` з переліченими правилами, отримуючи вхідні дані з stdin, та повертає exit-код запущеного процесу. Якщо не вдається запустити `fix`, повертає 1.
17
- `readStdin`: зчитує вміст stdin до EOF, повертаючи рядок UTF-8. Якщо stdin TTY, повертає порожній рядок.
16
+ routeFilePathToRules
17
+ Визначає список правил для пропугу на основі шляху до файлу
18
+
19
+ runPostToolUseFixCli
20
+ Виконує маршрутизацію шляху до правил та запускає команду для виправлення коду
18
21
 
19
22
  ## Публічний API
20
23
 
21
- - routeFilePathToRules — Знаходить правила, які відповідають шляху файлу, та повертає їх. Якщо жодного правила не знайдено, повертає порожній масив.
22
- - runPostToolUseFixCli — Запускає інструмент для виправлення помилок, викликаний з `bin/n-cursor.js` при певних умовах. Дозволяє передавати дані для тестування та замінити стандартну функцію запуску процесу.
24
+ routeFilePathToRules — повертає список правил для обробки зміненого шляху. Перший збіг із ROUTES переможець; невідомі шляхи або некоректні входи повертають порожній масив.
25
+
26
+ runPostToolUseFixCli — точка входу. Викликається з `bin/n-cursor.js` при передачі аргументу `post-tool-use-fix`. Параметри доступні для ін'єкції для тестування: `stdinJson` замінює зчитування з `process.stdin`, `spawnFn` замінює `node:child_process.spawn` на об'єкт, сумісний з EventEmitter.
23
27
 
24
28
  ## Гарантії поведінки
25
29
 
26
- - Приймає JSON із шляхом файлу як вхідні дані.
27
- - Якщо файл не має маршруту, повертає `true`.
28
- - Інакше запускає `npx --no @nitra/cursor fix` з переданими правилами.
29
- - Не блокує потік (turn).
30
- - Повертає `false` у разі невдачі запуску `npx`.
31
- - Не кидає винятків.
32
- - Ігнорує шляхи `.github` та `.git`.
33
- - Не використовує кешування.
30
+ - Read-only: файл не виконує операцій запису у файлову систему.
31
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
32
+ - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
33
+ - Свідомо пропускає шляхи: `.github`, `.git`.
34
+ - Не звертається до мережі.
@@ -1,41 +1,44 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/scripts/skills-cli.mjs
4
- crc: 11ba0be9
4
+ crc: 85da573a
5
+ score: 100
5
6
  ---
6
7
 
7
8
  # skills-cli.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Це інструмент для запуску скілів з пакету `@nitra/cursor` без синхронізації правил. Він збирає інструкції скілу та контекст проєкту для генерації промптів, які потім можуть бути використані для отримання відповідей від Claude або інших агентів. Інструмент забезпечує зручний інтерфейс командного рядка для взаємодії з скілами.
12
+ Файл надає інструменти для запуску скілів пакета `@nitra/cursor` без синку правил у проєкт. Він зчитує інструкції скілів з файлів `SKILL.md` та збирає контекст з `package.json`, `tsconfig.json` та `.n-cursor.json` для формування промпту. Зібраний промпт делегується в `cursor-agent` або `claude` для виконання необхідних дій.
12
13
 
13
14
  ## Поведінка
14
15
 
15
- - `normalizeSkillId`: Перетворює вхідний `name` скілу (можливо з префіксом `n-`) в нормалізований `id` каталогу.
16
- - `listSkillIds`: Повертає відсортований список `id` каталогів скілів у каталозі `skills/` пакета, фільтруючи лише ті, що мають файл `SKILL.md`.
17
- - `getSkillMdPath`: Створює повний шлях до файлу `SKILL.md` скілу на основі `skillsRoot` та `skillId`.
18
- - `readIfExists`: Перевіряє існування файлу за шляхом `path` та повертає його вміст, якщо файл існує, інакше повертає `null`.
19
- - `buildSkillPrompt`: Збирає промпт для LLM, включаючи інструкції скілу, текст завдання, та контекст проєкту (package.json, tsconfig.json, .n-cursor.json).
20
- - `runLlmCli`: Запускає LLM CLI (`claude` або `cursor-agent`) з наданим промптом та робочим каталогом проєкту.
21
- - `resolveBundledPackageRoot`: Визначає абсолютний шлях до кореня пакета `@nitra/cursor`, використовуючи `import.meta.url` для визначення кореня.
22
- - `runSkillsCli`: Обробляє аргументи командного рядка для запуску скілів, викликає відповідні функції для збору промптів та запуску LLM CLI.
16
+ normalizeSkillId
17
+ Перетворює ім'я скілу на ідентифікатор, видаляючи префікс n-
18
+
19
+ listSkillIds
20
+ Отримує відсортований список ідентифікаторів скілів, що мають файл SKILL.md
21
+
22
+ buildSkillPrompt
23
+ Створює промпт, збираючи інструкцію скілу та контекст поточного проєкту з файлів package.json, tsconfig.json та .n-cursor.json
24
+
25
+ resolveBundledPackageRoot
26
+ Визначає абсолютний шлях до кореня пакета з урахуванням модуля
27
+
28
+ runSkillsCli
29
+ Запускає CLI для виконання скілів, збираючи промпт та контекст проєкту, та делегує виконання в `cursor-agent` або `claude`
23
30
 
24
31
  ## Публічний API
25
32
 
26
- - normalizeSkillId: Перетворює ID на стандартний формат.
27
- - listSkillIds: Повертає список ID навичок.
28
- - buildSkillPrompt: Створює запит для навички.
29
- - resolveBundledPackageRoot: Знаходить базову директорію пакета `@nitra/cursor`.
30
- - runSkillsCli: Запускає CLI для навичок.
33
+ normalizeSkillId перетворює ідентифікатор навички.
34
+ listSkillIds отримує список ідентифікаторів навичок.
35
+ buildSkillPrompt створює запит для навички.
36
+ resolveBundledPackageRoot визначає основний каталог пакета.
37
+ runSkillsCli запускає клієнт для навичок.
31
38
 
32
39
  ## Гарантії поведінки
33
40
 
34
- - Запускає скіли пакета `@nitra/cursor` без синхронізації правил.
35
- - Читає скіли з файлів `npm/skills/<id>/SKILL.md` або кешу `npx`.
36
- - Збирає інструкцію скілу та контекст проєкту (package.json, tsconfig.json, .n-cursor.json) для створення промпту.
37
- - Використовує промпт для генерації відповіді, яка може бути виведена в stdout або делегована `cursor-agent` / `claude`.
38
- - Підтримує команди `skill list`, `skill taze`, `skill cursor taze`, `skill cursor taze "онови залежності"`, `skill claude taze`.
39
- - Повертає `false` або `null` у разі невдачі виконання.
40
- - Не кидає винятки.
41
- - Не використовує кешування.
41
+ - Read-only: файл не виконує операцій запису у файлову систему.
42
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
43
+ - За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
44
+ - Не звертається до мережі.