@nitra/cursor 5.3.4 → 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 (151) 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 +11 -0
  4. package/bin/n-cursor.js +43 -22
  5. package/lib/docs/models.md +29 -18
  6. package/lib/docs/omlx-trace.md +51 -0
  7. package/lib/docs/omlx.md +31 -15
  8. package/lib/omlx.mjs +2 -5
  9. package/package.json +1 -1
  10. package/rules/abie/docs/fix.md +17 -11
  11. package/rules/adr/docs/fix.md +25 -140
  12. package/rules/bun/docs/fix.md +18 -151
  13. package/rules/capacitor/docs/fix.md +16 -13
  14. package/rules/capacitor/js/docs/platforms.md +31 -43
  15. package/rules/changelog/docs/fix.md +25 -169
  16. package/rules/ci4/docs/fix.md +11 -14
  17. package/rules/doc-files/doc-files.mdc +60 -0
  18. package/rules/doc-files/docs/fix.md +31 -0
  19. package/rules/doc-files/fix.mjs +19 -0
  20. package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
  21. package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
  22. package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
  23. package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
  24. package/{skills → rules}/doc-files/js/docs/docgen-extract-anchors.md +1 -1
  25. package/{skills → rules}/doc-files/js/docs/docgen-extract.md +2 -2
  26. package/{skills → rules}/doc-files/js/docs/docgen-files-batch.md +1 -1
  27. package/{skills → rules}/doc-files/js/docs/docgen-gen.md +1 -1
  28. package/{skills → rules}/doc-files/js/docs/docgen-ignore.md +4 -4
  29. package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
  30. package/rules/doc-files/js/docs/docgen-scan.md +54 -0
  31. package/rules/doc-files/js/docs/lint.md +36 -0
  32. package/rules/doc-files/js/docs/units-js.md +31 -0
  33. package/rules/doc-files/js/docs/units-rs.md +35 -0
  34. package/rules/doc-files/js/docs/units.md +30 -0
  35. package/rules/doc-files/js/lint.mjs +96 -0
  36. package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
  37. package/rules/doc-files/lint/docs/lint.md +37 -0
  38. package/rules/doc-files/lint/lint.mjs +105 -0
  39. package/rules/doc-files/meta.json +1 -0
  40. package/rules/docker/docs/fix.md +21 -161
  41. package/rules/efes/docs/fix.md +23 -194
  42. package/rules/feedback/docs/fix.md +10 -8
  43. package/rules/ga/docs/fix.md +10 -5
  44. package/rules/graphql/docs/fix.md +23 -119
  45. package/rules/hasura/docs/fix.md +19 -5
  46. package/rules/hasura/js/docs/internal_urls.md +34 -307
  47. package/rules/image-avif/docs/fix.md +16 -127
  48. package/rules/image-compress/docs/fix.md +20 -141
  49. package/rules/image-compress/js/docs/package_setup.md +22 -182
  50. package/rules/js-bun-db/docs/fix.md +23 -139
  51. package/rules/js-bun-db/js/docs/safety.md +33 -221
  52. package/rules/js-bun-redis/docs/fix.md +25 -114
  53. package/rules/js-bun-redis/js/docs/imports.md +18 -166
  54. package/rules/js-lint/docs/fix.md +30 -108
  55. package/rules/js-lint/js/docs/lint-findings.md +37 -17
  56. package/rules/js-lint/js/docs/lint.md +22 -238
  57. package/rules/js-lint/js/docs/tooling.md +34 -331
  58. package/rules/js-lint-ci/docs/fix.md +16 -149
  59. package/rules/js-lint-ci/js/docs/lint.md +16 -136
  60. package/rules/js-mssql/docs/fix.md +18 -123
  61. package/rules/js-mssql/js/docs/deps.md +28 -251
  62. package/rules/js-run/docs/fix.md +23 -138
  63. package/rules/js-run/js/docs/runtime.md +24 -378
  64. package/rules/k8s/docs/fix.md +18 -123
  65. package/rules/nginx-default-tpl/docs/fix.md +22 -118
  66. package/rules/nginx-default-tpl/js/docs/template.md +38 -360
  67. package/rules/npm-module/docs/fix.md +27 -89
  68. package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
  69. package/rules/npm-module/js/docs/package_structure.md +36 -258
  70. package/rules/npm-module/js/docs/rule_meta.md +25 -127
  71. package/rules/npm-module/js/docs/skill_meta.md +18 -180
  72. package/rules/php/docs/fix.md +21 -98
  73. package/rules/php/js/docs/tooling.md +20 -143
  74. package/rules/python/docs/fix.md +25 -157
  75. package/rules/python/js/docs/applies.md +20 -98
  76. package/rules/python/js/docs/tooling.md +27 -144
  77. package/rules/rego/docs/fix.md +24 -112
  78. package/rules/rego/js/docs/applies.md +20 -164
  79. package/rules/rego/js/docs/lint.md +15 -110
  80. package/rules/release/docs/fix.md +16 -114
  81. package/rules/rust/docs/fix.md +24 -119
  82. package/rules/rust/js/docs/applies.md +20 -129
  83. package/rules/security/docs/fix.md +21 -78
  84. package/rules/security/js/docs/sample_secret.md +23 -182
  85. package/rules/security/js/docs/trufflehog.md +19 -128
  86. package/rules/style-lint/docs/fix.md +16 -150
  87. package/rules/style-lint/js/docs/lint.md +21 -172
  88. package/rules/style-lint/js/docs/tooling.md +19 -184
  89. package/rules/tauri/docs/fix.md +26 -152
  90. package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
  91. package/rules/tauri/js/docs/tooling.md +20 -217
  92. package/rules/test/docs/fix.md +19 -127
  93. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
  94. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
  95. package/rules/test/js/docs/cargo_mutants_config.md +24 -164
  96. package/rules/test/js/docs/location.md +24 -126
  97. package/rules/test/js/docs/no-process-chdir.md +20 -151
  98. package/rules/test/js/docs/no-relative-fs-path.md +24 -261
  99. package/rules/test/js/docs/stryker_config.md +48 -148
  100. package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
  101. package/rules/text/docs/fix.md +25 -113
  102. package/rules/text/js/docs/forbidden-prettier.md +21 -132
  103. package/rules/text/js/docs/formatting.md +60 -251
  104. package/rules/text/js/docs/lint.md +17 -114
  105. package/rules/vue/docs/fix.md +25 -118
  106. package/rules/vue/js/docs/packages.md +25 -323
  107. package/rules/worktree/docs/fix.md +31 -150
  108. package/scripts/coverage-classify/docs/index.md +23 -209
  109. package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
  110. package/scripts/dispatcher/docs/trace.md +35 -0
  111. package/scripts/docs/auto-rules.md +37 -361
  112. package/scripts/docs/lint-cli.md +12 -13
  113. package/scripts/docs/post-tool-use-fix.md +16 -15
  114. package/scripts/docs/skills-cli.md +26 -23
  115. package/scripts/docs/sync-claude-config.md +94 -34
  116. package/scripts/docs/worktree-cli.md +11 -34
  117. package/scripts/lib/docs/assert-project-root.md +14 -16
  118. package/scripts/lib/docs/changed-files.md +24 -139
  119. package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
  120. package/scripts/lib/docs/rule-predicates.md +20 -17
  121. package/scripts/lib/docs/run-rule-cli.md +14 -18
  122. package/scripts/lib/docs/run-rule.md +13 -20
  123. package/scripts/lib/docs/run-standard-rule.md +12 -15
  124. package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
  125. package/scripts/lib/rule-predicates.mjs +1 -1
  126. package/scripts/sync-claude-config.mjs +4 -1
  127. package/scripts/utils/docs/with-lock.md +19 -12
  128. package/scripts/utils/with-lock.mjs +4 -2
  129. package/skills/doc-aggregate/SKILL.md +2 -2
  130. package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
  131. package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
  132. package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
  133. package/skills/doc-files/.changes/260612-0031.md +5 -0
  134. package/skills/doc-files/.changes/260612-0036.md +5 -0
  135. package/skills/doc-files/.changes/260612-0114.md +5 -0
  136. package/skills/doc-files/SKILL.md +6 -6
  137. package/skills/fix/js/docs/llm-worker.md +17 -15
  138. package/skills/fix/js/docs/orchestrator.md +30 -23
  139. package/skills/fix/js/docs/t0.md +26 -16
  140. package/skills/start-check/js/docs/check.md +26 -22
  141. package/skills/taze/js/docs/diff.md +44 -20
  142. package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
  143. package/skills/doc-files/js/docs/docgen-scan.md +0 -25
  144. package/skills/doc-files/js/docs/units-rs.md +0 -35
  145. /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
  146. /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
  147. /package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +0 -0
  148. /package/{skills → rules}/doc-files/js/docgen-gen.mjs +0 -0
  149. /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
  150. /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
  151. /package/{skills → rules}/doc-files/js/units.mjs +0 -0
@@ -1,167 +1,41 @@
1
1
  ---
2
2
  docgen:
3
3
  source: npm/rules/tauri/fix.mjs
4
- crc: 12fc1644
4
+ crc: 38cf876b
5
+ score: 100
5
6
  ---
6
7
 
7
- # fix.mjs — entry-point правила `tauri`
8
+ # fix.mjs
8
9
 
9
10
  ## Огляд
10
11
 
11
- Файл `npm/rules/tauri/fix.mjs` це тонкий **entry-point** (точка входу) правила `tauri` у системі правил `@nitra/cursor`. Файл виконує дві ролі одночасно:
12
+ Виконує застосування політики JS-занепокоєних та генерує посилання MDC. Повертає результат.
12
13
 
13
- 1. **Library mode** експортує функцію `run(ctx)`, яку оркестратор CLI (`@nitra/cursor`) викликає через динамічний `import`, передаючи спільний контекст прогону (`RuleContext`, наприклад, `walkCache` для повторного використання обходу файлової системи між правилами).
14
- 2. **Standalone mode** — якщо файл запущено напряму через `bun npm/rules/tauri/fix.mjs`, виконується повний еквівалент команди `npx @nitra/cursor fix tauri` (з підвантаженням конфігу, обробкою whitelist та виведенням summary), а процес завершується з відповідним exit-code для CI/IDE.
14
+ Виконується як еквівалент команди `npx @nitra/cursor fix <id>`. Завантажує конфігурацію, перевіряє дозволені записи, генерує зведену інформацію та визначає код виходу процесу.
15
15
 
16
- Сам файл **не містить жодної доменної логіки правила** `tauri` — уся робота (steps `applies → JS-concerns → policy → mdc-refs`) делегується у бібліотечну функцію `runStandardRule()`. Цей файл лише підключає стандартний раннер до конкретної директорії правила (`import.meta.dirname`) і опціонально запускає CLI-обгортку.
16
+ ## Поведінка
17
17
 
18
- Файл є **типовим шаблоном `fix.mjs`** для будь-якого правила в `npm/rules/<id>/`: майже всі правила в цій директорії мають ідентичний за структурою `fix.mjs`, що відрізняється лише доменом (`tauri`, `vue`, `python` тощо), який неявно визначається через шлях `import.meta.dirname`.
18
+ 1. Запуск правила.
19
+ * Приймає контекст прогону.
20
+ * Виконує застосування JS-занепокоєних.
21
+ * Застосовує політику.
22
+ * Генерує посилання MDC.
23
+ * Повертає результат прогону.
24
+ 2. Запуск правила у режимі CLI.
25
+ * Виконується як повний еквівалент команди `npx @nitra/cursor fix <id>`.
26
+ * Виконує завантаження конфігурації.
27
+ * Виконує перевірку дозволених записів.
28
+ * Генерує зведену інформацію.
29
+ * Виконує перевірку.
30
+ * Визначає код виходу процесу.
19
31
 
20
- ## Експорти / API
32
+ ## Публічний API
21
33
 
22
- | Експорт | Тип | Опис |
23
- | ------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
- | `run` | `(ctx?: RuleContext) => Promise<number>` | Іменований експорт. Запускає стандартний пайплайн правила (`applies → JS-concerns → policy → mdc-refs`) для директорії, у якій знаходиться `fix.mjs`. Повертає `0` при відсутності порушень і `1` (або інший ненульовий код) у разі порушень. |
34
+ run запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
35
+ Library mode викликається CLI orchestration через `import + run`.
25
36
 
26
- Файл **не має** `default`-експорту. Side-effect на верхньому рівні: якщо модуль завантажено як CLI-entry (`isRunAsCli(import.meta.url) === true`), виконується `await runRuleCli(...)` і `process.exit(...)`.
37
+ ## Гарантії поведінки
27
38
 
28
- ### Тип `RuleContext`
29
-
30
- Тип параметра `ctx` імпортується (через JSDoc `@typedef`) з `../../scripts/lib/run-standard-rule.mjs`. Зазвичай містить:
31
-
32
- - `walkCache` — кеш обходу файлової системи, щоб не сканувати дерево повторно для кожного правила.
33
- - Інші поля, специфічні для оркестрації (логер, прапорці `dryRun`, тощо).
34
-
35
- Параметр `ctx` опціональний: якщо файл запущено окремо (standalone), `ctx` буде `undefined`, і `runStandardRule()` сам створить локальний контекст.
36
-
37
- ## Функції
38
-
39
- ### `run(ctx)`
40
-
41
- ```js
42
- /**
43
- *
44
- */
45
- export function run(ctx) {
46
- return runStandardRule(import.meta.dirname, ctx)
47
- }
48
- ```
49
-
50
- - **Сигнатура:** `function run(ctx?: RuleContext): Promise<number>`
51
- - **Параметри:**
52
- - `ctx` _(опціональний, `RuleContext`)_ — контекст прогону, який зазвичай передає оркестратор `@nitra/cursor`. У ньому, серед іншого, може бути `walkCache` для уникнення повторного сканування файлової системи між різними правилами.
53
- - **Повертає:** `Promise<number>` — асинхронний код виходу:
54
- - `0` — правило відпрацювало без порушень (OK);
55
- - `1` (або інший ненульовий код, який повертає `runStandardRule`) — знайдено порушення.
56
- - **Side effects:**
57
- - Викликає `runStandardRule()`, яка послідовно виконує етапи `applies → JS-concerns → policy → mdc-refs`. Ці етапи можуть:
58
- - читати файли у репозиторії;
59
- - запускати JS-перевірки (наприклад, статичні правила з директорії `js/`);
60
- - виконувати policy-перевірки (наприклад, `policy/`-перевірки правила `tauri`);
61
- - порівнювати посилання у `.mdc`-файлах (`mdc-refs`).
62
- - Сам по собі `run()` **не змінює** файли (правило `fix`-типу може здійснювати автозаміни всередині `runStandardRule`, якщо це закладено у бібліотеці; у самому `fix.mjs` цієї логіки немає).
63
- - **Як використовується:** оркестратор CLI імпортує `fix.mjs` правила і викликає `await run(ctx)`. Результат складається у загальний summary прогону.
64
-
65
- ### Standalone-блок (top-level)
66
-
67
- ```js
68
- if (isRunAsCli(import.meta.url)) {
69
- // eslint-disable-next-line n/no-process-exit -- standalone entry-point має повертати exit-code для CI/IDE
70
- process.exit(await runRuleCli(import.meta.dirname))
71
- }
72
- ```
73
-
74
- - **Призначення:** дозволяє запускати правило напряму, без проходження через головний CLI `@nitra/cursor`. Команда `bun npm/rules/tauri/fix.mjs` стає повним еквівалентом `npx @nitra/cursor fix tauri`.
75
- - **Логіка:**
76
- - `isRunAsCli(import.meta.url)` повертає `true`, якщо поточний модуль є точкою входу процесу (а не imported-модулем). Це класична перевірка ESM-еквівалента `require.main === module`.
77
- - Якщо `true`, викликається `runRuleCli(import.meta.dirname)`, яка обгортає `runStandardRule` додатковою CLI-логікою: завантаження конфігу проєкту, обробка whitelist (виключень), виведення summary у консоль.
78
- - `process.exit(...)` із цим кодом — обов’язковий для CI/IDE: процес має повернути ненульовий код у разі порушень, щоб pipeline (наприклад, у `n-cursor` чи у GitHub Actions) міг це задетектити. Тому ESLint-правила `n/no-process-exit` і `unicorn/no-process-exit` навмисно вимкнено через inline-коментар.
79
- - **Side effects:**
80
- - Може писати у `stdout`/`stderr` (summary, помилки).
81
- - Завершує процес викликом `process.exit(...)` — після цього рядка код не виконується.
82
- - **Не виконується** у library mode (коли файл імпортовано іншим скриптом).
83
-
84
- ## Залежності
85
-
86
- ### Внутрішні (relative imports)
87
-
88
- | Імпорт | Шлях | Призначення |
89
- | ----------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
90
- | `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Утиліта-перевірка: чи запущено файл як головний модуль (entry-point), а не як `import`. |
91
- | `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Standalone-обгортка над `runStandardRule`: завантаження конфігу, whitelist, summary, exit-code. |
92
- | `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Бібліотечна функція, що виконує стандартний пайплайн правила: `applies → JS-concerns → policy → mdc-refs`. |
93
-
94
- Усі шляхи відносні: `../../scripts/lib/` → `npm/scripts/lib/`.
95
-
96
- ### Зовнішні
97
-
98
- Файл **не має** прямих залежностей від npm-пакетів. Усі npm-залежності, якщо такі є, прихилені всередині бібліотечних функцій (`runStandardRule`, `runRuleCli`).
99
-
100
- ### Контекст домену
101
-
102
- Директорія `npm/rules/tauri/` містить також:
103
-
104
- - `tauri.mdc` — людиночитна специфікація правила (формат Cursor `.mdc`);
105
- - `meta.json` — метадані правила (наприклад, прапорці `worktree`, опис);
106
- - `js/` — JS-частина перевірок правила (запускається на етапі JS-concerns);
107
- - `policy/` — policy-перевірки (rego/інші) на етапі policy.
108
-
109
- `runStandardRule` неявно «знає», як обробити кожен з цих артефактів, через переданий `import.meta.dirname`.
110
-
111
- ## Потік виконання / Використання
112
-
113
- ### Library mode (типовий, через оркестратор)
114
-
115
- 1. Користувач запускає `npx @nitra/cursor fix` (або підкоманду, що зачіпає правило `tauri`).
116
- 2. Оркестратор `@nitra/cursor`:
117
- 1. Знаходить директорію `npm/rules/tauri/`.
118
- 2. Виконує `const mod = await import('npm/rules/tauri/fix.mjs')`.
119
- 3. Перевірка `isRunAsCli(import.meta.url)` повертає `false` (бо це import, а не entry-point) — standalone-блок **не виконується**.
120
- 4. Викликає `await mod.run(ctx)`, передаючи спільний контекст (з `walkCache` тощо).
121
- 3. `run(ctx)` → `runStandardRule(import.meta.dirname, ctx)` → послідовно виконуються етапи:
122
- - **applies** — фільтрація: чи правило взагалі застосовне до поточного репозиторію/файлів.
123
- - **JS-concerns** — JS-перевірки з директорії `js/` правила.
124
- - **policy** — policy-перевірки з директорії `policy/` правила.
125
- - **mdc-refs** — перевірка посилань у `.mdc` файлах правила.
126
- 4. Повертається `Promise<number>` із кодом виходу для цього правила, який оркестратор агрегує у summary всіх правил.
127
-
128
- ### Standalone mode (debug / прямий запуск)
129
-
130
- ```bash
131
- bun npm/rules/tauri/fix.mjs
132
- ```
133
-
134
- 1. Bun завантажує файл як головний модуль.
135
- 2. `import { isRunAsCli, runRuleCli, runStandardRule }` — підвантажуються залежності.
136
- 3. Експорт `run` стає доступним (але ніхто його не викликає у цьому режимі).
137
- 4. Виконується top-level `if (isRunAsCli(import.meta.url))`:
138
- - `isRunAsCli(...) === true`.
139
- - `await runRuleCli(import.meta.dirname)`:
140
- - завантажує конфіг проєкту;
141
- - застосовує whitelist;
142
- - всередині викликає `runStandardRule(dir, ctx)` (з локально-створеним контекстом);
143
- - виводить summary у консоль.
144
- - `process.exit(<code>)` — процес завершується з кодом `0` (OK) або `1` (порушення).
145
-
146
- ### Дві ролі одного файлу
147
-
148
- Архітектурний прийом — **«library + main» в одному файлі** — закладений у коментарі коду:
149
-
150
- > Дві ролі fix.mjs: library (run) + standalone (main).
151
-
152
- Це дозволяє:
153
-
154
- - розробнику швидко налагоджувати правило окремо (`bun rules/tauri/fix.mjs`);
155
- - оркестратору повторно використовувати кеш обходу (`walkCache`) між правилами під час масового прогону.
156
-
157
- ## Rebuild Test
158
-
159
- Файл є **тонким адаптером** і не містить доменної логіки — його можна повністю відтворити за цією документацією. Структура:
160
-
161
- 1. Два іменовані імпорти з `../../scripts/lib/run-rule-cli.mjs`: `isRunAsCli`, `runRuleCli`.
162
- 2. Один іменований імпорт з `../../scripts/lib/run-standard-rule.mjs`: `runStandardRule`.
163
- 3. JSDoc-блок із описом, типом параметра `ctx` (через `@param {import('...')...}`) і типом результату (`Promise<number>`).
164
- 4. `export function run(ctx) { return runStandardRule(import.meta.dirname, ctx) }`.
165
- 5. Top-level `if (isRunAsCli(import.meta.url))` з викликом `process.exit(await runRuleCli(import.meta.dirname))` і inline-коментарем-вимкненням ESLint-правил `n/no-process-exit` та `unicorn/no-process-exit`.
166
-
167
- Жодних інших артефактів (інших експортів, констант, побічних `console.log`, мутації глобального стану) у файлі немає.
39
+ - Read-only: файл не виконує операцій запису у файлову систему.
40
+ - Кешує результати в межах одного прогону.
41
+ - Не звертається до мережі.
@@ -1,168 +1,30 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/tauri/js/cargo_mutants_config.mjs
4
+ crc: 7dc410ce
5
+ score: 80
6
+ ---
7
+
1
8
  # cargo_mutants_config.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Модуль реалізує концерн `cargo_mutants_config` правила `tauri.mdc`. Його завдання — гарантувати, що для кожного workspace-пакета монорепо, у якому існує `<workspace>/src-tauri/Cargo.toml`, поряд лежить канонічний Tauri-специфічний конфіг `cargo-mutants` за шляхом `<workspace>/src-tauri/.cargo/mutants.toml`. Конфіг забороняє повторну збірку бінарників (`--bins`) і doc-tests (`--doc`) під кожного мутанта (це перетворює секунди на хвилини) і виключає з mutation-testing platform-bridge файли, які тестуються smoke/e2e, а не unit-тестами.
6
-
7
- Семантика виключень фіксована для всіх Tauri-проєктів:
8
-
9
- - `src/main.rs` — binary shell entrypoint (smoke/e2e, не mutation unit);
10
- - `src/lib.rs` — Tauri `pub fn run`, runtime entrypoint, який запускає увесь app shell (один мутант там тримає увесь Tauri runtime і ділить sandbox-fail з `src/main.rs`);
11
- - `src/**/{android,ios,mobile}.rs` — mobile plugin bridge / platform glue;
12
- - `src/**/{macos,windows,linux,desktop}.rs` — desktop platform bridge / OS integration glue.
13
-
14
- Файл побудований за патерном concern-checker у репо: експортує одну функцію `check(cwd)`, яка:
15
-
16
- - self-gates (тихо пропускає, якщо у монорепо немає жодного `src-tauri/Cargo.toml` — нейтральний baseline за потреби створить test rule);
17
- - ідемпотентна — створює файл лише за відсутності, інакше дописує лише ті top-level ключі, яких бракує, не змінюючи існуючих значень користувача;
18
- - репортує результат через спільний `createCheckReporter` і повертає process exit code (`0` — OK або skip, `1` — порушення).
19
-
20
- ## Експорти / API
21
-
22
- | Експорт | Тип | Опис |
23
- | ------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
- | `check(cwd?)` | `async function` | Єдиний публічний експорт. Запускає концерн над переданим або поточним коренем проєкту. Повертає `Promise<number>` — exit code, сумісний з CLI-обгорткою. |
25
-
26
- Внутрішні (не експортуються) допоміжні функції: `findSrcTauriDirs`, `detectMissingKeys`, `buildAppended`, `buildBaseline`, `processOneSrcTauri`.
27
-
28
- Внутрішні константи модульного рівня:
29
-
30
- - `TAURI_BASELINE_HEADER` — рядковий заголовок (коментар) для нового файла з посиланням на `tauri.mdc` і поясненням, чому виключаються `--bins` та `--doc`.
31
- - `TAURI_KEY_SNIPPETS` — заморожений (`Object.freeze`) словник `{ ключ → канонічний TOML-сніпет з блоковими коментарями }` для двох канонічних top-level ключів: `additional_cargo_test_args` і `exclude_globs`.
32
- - `TAURI_CANONICAL_KEYS` — заморожений масив ключів `TAURI_KEY_SNIPPETS` зі збереженим порядком (`Object.keys(TAURI_KEY_SNIPPETS)`); використовується для впорядкованого детектування відсутніх ключів і генерації baseline.
33
-
34
- Канонічний вміст сніпетів:
35
-
36
- - `additional_cargo_test_args = ["--lib", "--tests"]` — `cargo mutants` під час прогону тестів обмежується library + integration tests, без бінарників і doc-tests.
37
- - `exclude_globs = [...]` — список glob-патернів, які виключаються з mutation-testing (див. розділ «Огляд»).
38
-
39
- ## Функції
40
-
41
- ### `check(cwd = process.cwd())`
42
-
43
- - **Сигнатура:** `async function check(cwd?: string): Promise<number>`.
44
- - **Параметри:**
45
- - `cwd` _(string, опційний, default `process.cwd()`)_ — абсолютний шлях до кореня монорепо. Дефолт забезпечує CLI-сумісність (виклик без аргументів з-під будь-якого `bin`).
46
- - **Повертає:** `Promise<number>` — exit code від `reporter.getExitCode()` (`0` — успіх або self-skip, `1` — є зафіксовані `reporter.fail(...)`).
47
- - **Алгоритм:**
48
- 1. Створює інстанс репортера через `createCheckReporter()`.
49
- 2. Знаходить усі `src-tauri/` директорії через `findSrcTauriDirs(cwd)`.
50
- 3. Якщо їх немає — повертає `reporter.getExitCode()` без жодних змін (self-gate / silent skip).
51
- 4. Інакше — послідовно обробляє кожен каталог через `processOneSrcTauri(dir, cwd, reporter)`.
52
- 5. Повертає підсумковий exit code від репортера.
53
- - **Side effects:** може створювати теку `<src-tauri>/.cargo/` і записувати в `<src-tauri>/.cargo/mutants.toml`; пише повідомлення (`pass`/`fail`) у спільний репортер.
54
-
55
- ### `findSrcTauriDirs(cwd)`
56
-
57
- - **Сигнатура:** `async function findSrcTauriDirs(cwd: string): Promise<string[]>`.
58
- - **Параметри:** `cwd` — корінь проєкту.
59
- - **Повертає:** масив абсолютних шляхів до `src-tauri/` каталогів, які мають власний `Cargo.toml`.
60
- - **Алгоритм:**
61
- 1. Запитує всі workspace-пакети через `getMonorepoPackageRootDirs(cwd)` (включно з самим коренем).
62
- 2. Для кожного `root` перевіряє наявність `join(cwd, root, 'src-tauri', 'Cargo.toml')` через `existsSync`.
63
- 3. Якщо файл існує — додає `join(cwd, root, 'src-tauri')` до результату.
64
- - **Side effects:** немає (read-only через `existsSync` і виклик util-функції монорепо-обходу).
65
-
66
- ### `detectMissingKeys(targetPath)`
67
-
68
- - **Сигнатура:** `async function detectMissingKeys(targetPath: string): Promise<string[]>`.
69
- - **Параметри:** `targetPath` — абсолютний шлях до існуючого `.cargo/mutants.toml`.
70
- - **Повертає:** масив канонічних ключів (з `TAURI_CANONICAL_KEYS`), яких немає на top-level у вже існуючому TOML, зі збереженим порядком.
71
- - **Алгоритм:**
72
- 1. Читає файл як UTF-8.
73
- 2. Парсить його через `parseToml` зі `smol-toml`.
74
- 3. Фільтрує `TAURI_CANONICAL_KEYS`, лишаючи лише ті, яких немає в розпарсеному об'єкті (`!(k in parsed)`).
75
- - **Side effects:** read-only (читання файла).
76
-
77
- ### `buildAppended(existing, missingKeys)`
78
-
79
- - **Сигнатура:** `function buildAppended(existing: string, missingKeys: string[]): string`.
80
- - **Параметри:**
81
- - `existing` — поточний текстовий вміст `.cargo/mutants.toml`;
82
- - `missingKeys` — ключі, які треба дописати.
83
- - **Повертає:** новий вміст файла (`string`) — оригінал + хвостовий блок з коментарем-маркером `# Tauri canonical cargo-mutants additions (tauri.mdc)` і конкатенованими TOML-сніпетами для всіх `missingKeys` у порядку, наданому викликачем.
84
- - **Алгоритм:**
85
- 1. Нормалізує хвіст оригіналу: гарантує trailing `\n`.
86
- 2. Будує блок: порожній рядок-розділювач, заголовок-коментар, далі для кожного ключа з `missingKeys` — відповідний сніпет з `TAURI_KEY_SNIPPETS[key]`.
87
- 3. Конкатенує хвіст з блоком.
88
- - **Side effects:** немає (чиста функція).
89
-
90
- ### `buildBaseline()`
91
-
92
- - **Сигнатура:** `function buildBaseline(): string`.
93
- - **Параметри:** немає.
94
- - **Повертає:** повний текст канонічного `.cargo/mutants.toml` — `TAURI_BASELINE_HEADER`, після нього сніпети всіх `TAURI_CANONICAL_KEYS` (`additional_cargo_test_args`, `exclude_globs`), з'єднані через `'\n'`.
95
- - **Side effects:** немає (чиста функція).
96
-
97
- ### `processOneSrcTauri(srcTauriDir, cwd, reporter)`
98
-
99
- - **Сигнатура:** `async function processOneSrcTauri(srcTauriDir: string, cwd: string, reporter: { pass(msg): void, fail(msg): void }): Promise<void>`.
100
- - **Параметри:**
101
- - `srcTauriDir` — абсолютний шлях до `src-tauri/` каталогу;
102
- - `cwd` — корінь проєкту (потрібен для красивого relative-шляху в репорт-повідомленнях);
103
- - `reporter` — інстанс репортера з методами `pass(msg)`/`fail(msg)`.
104
- - **Повертає:** `Promise<void>`.
105
- - **Алгоритм / гілки:**
106
- 1. Формує `target = join(srcTauriDir, '.cargo', 'mutants.toml')` і `rel = relative(cwd, target)`.
107
- 2. **Файла немає:** створює директорію `<src-tauri>/.cargo/` (`mkdir … { recursive: true }`), записує повний `buildBaseline()`, репортує `pass`: `.cargo/mutants.toml створено з Tauri canonical baseline (<rel>) (tauri.mdc)`; вихід.
108
- 3. **Файл є:** викликає `detectMissingKeys(target)`.
109
- - Якщо `missing.length === 0` — репортує `pass`: `.cargo/mutants.toml: manual cargo-mutants config preserved (<rel>)`; вихід.
110
- - Інакше — читає поточний вміст, обчислює новий через `buildAppended(existing, missing)`, записує файл, репортує `pass`: `.cargo/mutants.toml: додано відсутні Tauri-ключі [<key1>, <key2>] (<rel>) (tauri.mdc)`.
111
- - **Side effects:** створює директорії, записує/перезаписує файл `mutants.toml`, додає `pass`-повідомлення в репортер. У поточній реалізації функція не викликає `reporter.fail` — концерн є строго ідемпотентно-fix-овим (немає сценарію «порушення»).
112
-
113
- ## Залежності
114
-
115
- ### Node.js core (вбудовані)
116
-
117
- - `node:fs` — `existsSync` для check'у наявності `Cargo.toml` / `mutants.toml`;
118
- - `node:fs/promises` — `mkdir`, `readFile`, `writeFile` (промісована I/O для запису конфіга);
119
- - `node:path` — `dirname`, `join`, `relative` (побудова цільового шляху та relative-вивід у репорт).
120
-
121
- ### External
122
-
123
- - `smol-toml` (іменований імпорт `parse as parseToml`) — лояльний TOML-парсер для детекції наявних top-level ключів у існуючому `mutants.toml`.
124
-
125
- ### Internal (workspace utilities)
126
-
127
- - `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter()` — спільний reporter pass/fail/exit-code для concern-checker'ів.
128
- - `../../../scripts/lib/workspaces.mjs` → `getMonorepoPackageRootDirs(cwd)` — повертає корінь + усі workspace-пакети монорепо.
129
-
130
- ## Потік виконання / Використання
131
-
132
- ### Типовий виклик з CLI / rule-runner
133
-
134
- Модуль — частина правила `tauri.mdc`, його `check`-функцію викликає rule-runner (як один з концернів). Приблизний псевдо-виклик:
135
-
136
- ```js
137
- import { check } from './cargo_mutants_config.mjs'
138
-
139
- const exitCode = await check(process.cwd())
140
- process.exit(exitCode)
141
- ```
142
-
143
- ### Послідовність дій усередині одного запуску
144
-
145
- 1. `check(cwd)` створює репортер.
146
- 2. `findSrcTauriDirs(cwd)` обходить пакети монорепо й збирає всі `src-tauri/` з `Cargo.toml`.
147
- 3. Якщо пусто — `return reporter.getExitCode()` (тихий skip, нічого не пишемо).
148
- 4. Для кожного знайденого `src-tauri/`:
149
- - якщо `.cargo/mutants.toml` відсутній → `mkdir -p` + запис canonical baseline;
150
- - якщо файл існує + усі канонічні ключі присутні → нічого не змінює, репорт `manual cargo-mutants config preserved`;
151
- - якщо файл існує, але деякі канонічні ключі відсутні → дописує лише відсутні ключі окремим блоком у кінці файла.
152
- 5. Повертає підсумковий exit code.
153
-
154
- ### Гарантії
12
+ Огляд
155
13
 
156
- - **Self-gating:** концерн нічого не робить, якщо в репо немає Tauri-пакетів це не помилка.
157
- - **Ідемпотентність:** повторні прогони на чистому/повному canonical файлі не змінюють вмісту.
158
- - **Non-destructive:** ані наявні значення `additional_cargo_test_args`/`exclude_globs`, ані сторонні top-level ключі користувача не перезаписуються — додавання відсутніх ключів відбувається окремим append-блоком в кінці файла з коментарем-маркером.
159
- - **Read-once-write-once на один каталог:** при append-сценарії файл читається повторно (один раз для парсу через `detectMissingKeys`, ще раз як текст для конкатенації), що гарантує запис рівно одного фінального вмісту.
14
+ Файл виконує пошук пакетів у монорепо, які містять директорії `src-tauri/`. Обробляється конфігураційні файли цих пакетів. Створюється або оновлюється файл `.cargo/mutants.toml` для забезпечення наявності певних ключів у конфігурації. (tauri.mdc)
160
15
 
161
- ### Точки розширення
16
+ ## Поведінка
162
17
 
163
- - Додати новий канонічний top-level ключ: додати пару `key → snippet\n` у `TAURI_KEY_SNIPPETS`; `TAURI_CANONICAL_KEYS` та логіка `buildBaseline`/`buildAppended`/`detectMissingKeys` підхоплять його автоматично, зі збереженим порядком вставки.
164
- - Змінити список platform-bridge файлів: відредагувати `exclude_globs` сніпет у `TAURI_KEY_SNIPPETS`.
18
+ 1. Знайти всі каталоги з `src-tauri/` та власним `Cargo.toml` у монорепо через `getMonorepoPackageRootDirs`.
19
+ 2. Для кожного знайденого каталогу обробити `processOneSrcTauri`.
20
+ 3. У `processOneSrcTauri` визначити цільовий файл `.cargo/mutants.toml` у каталозі `src-tauri/`.
21
+ 4. Перевірити наявність файлу `.cargo/mutants.toml`.
22
+ 5. Якщо файл відсутній, створити його з базовим конфігураційним блоком.
23
+ 6. Якщо файл існує, зчитати його вміст і визначити відсутні ключі.
24
+ 7. Додати визначені канонічні ключі до існуючого вмісту.
25
+ 8. Повідомити про успішне створення або збереження конфігурації з маркуванням (tauri.mdc).
26
+ 9. Повертати код виходу репортера для фінального результату.
165
27
 
166
- ### Rebuild Test
28
+ ## Гарантії поведінки
167
29
 
168
- Файл містить достатню інформацію, щоб реконструювати правило з нуля: визначені вхідні точки виявлення Tauri-пакетів, перелік канонічних top-level ключів конфіга, форма заголовка/коментарів у згенерованому файлі, точні повідомлення репортера, гарантії ідемпотентності та non-destructive append, повний контракт експортованої функції `check(cwd)` (включно з дефолтом і поверненим типом).
30
+ - Не звертається до мережі.