@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.
Files changed (229) hide show
  1. package/.pi-template/extensions/n-cursor-adr/docs/index.md +181 -0
  2. package/AGENTS.template.md +4 -0
  3. package/CHANGELOG.md +37 -3
  4. package/bin/docs/n-cursor.md +636 -0
  5. package/bin/docs/rename-yaml-extensions.md +207 -0
  6. package/bin/n-cursor.js +30 -3
  7. package/package.json +1 -1
  8. package/rules/abie/docs/fix.md +18 -0
  9. package/rules/abie/js/docs/applies.md +26 -0
  10. package/rules/abie/js/docs/env_dns.md +32 -0
  11. package/rules/abie/js/docs/firebase_hosting.md +23 -0
  12. package/rules/abie/js/docs/hc_pairing.md +35 -0
  13. package/rules/abie/js/docs/ua_http_route.md +28 -0
  14. package/rules/abie/js/docs/ua_node_selector.md +28 -0
  15. package/rules/abie/lib/docs/enabled.md +29 -0
  16. package/rules/abie/lib/docs/env-dns.md +35 -0
  17. package/rules/abie/lib/docs/hc-yaml.md +33 -0
  18. package/rules/abie/lib/docs/http-route.md +44 -0
  19. package/rules/abie/lib/docs/k8s-tree.md +40 -0
  20. package/rules/abie/lib/docs/kustomization-patches.md +47 -0
  21. package/rules/abie/lib/docs/overlay-paths.md +38 -0
  22. package/rules/abie/lib/docs/yaml.md +29 -0
  23. package/rules/adr/docs/fix.md +148 -0
  24. package/rules/adr/js/docs/hooks.md +259 -0
  25. package/rules/bun/docs/fix.md +156 -0
  26. package/rules/bun/js/docs/layout.md +393 -0
  27. package/rules/capacitor/docs/fix.md +121 -0
  28. package/rules/capacitor/js/docs/platforms.md +295 -0
  29. package/rules/changelog/changelog.mdc +4 -2
  30. package/rules/changelog/docs/fix.md +174 -0
  31. package/rules/changelog/js/consistency.mjs +114 -13
  32. package/rules/changelog/js/docs/consistency.md +387 -0
  33. package/rules/changelog/lib/docs/package-manifest.md +210 -0
  34. package/rules/ci4/docs/fix.md +179 -0
  35. package/rules/ci4/js/docs/marksman_config.md +128 -0
  36. package/rules/docker/docker.mdc +8 -3
  37. package/rules/docker/docs/fix.md +171 -0
  38. package/rules/docker/js/docs/lint.md +258 -0
  39. package/rules/docker/lib/docs/docker-hadolint.md +184 -0
  40. package/rules/docker/lib/docs/docker-mirror.md +247 -0
  41. package/rules/docker/lib/docs/docker-native-addon.md +170 -0
  42. package/rules/docker/lib/docs/docker-nginx-user.md +219 -0
  43. package/rules/docker/lint/docs/lint.md +193 -0
  44. package/rules/efes/docs/fix.md +203 -0
  45. package/rules/feedback/docs/fix.md +140 -0
  46. package/rules/flow/docs/fix.md +152 -0
  47. package/rules/ga/docs/fix.md +158 -0
  48. package/rules/ga/js/docs/lint.md +100 -0
  49. package/rules/ga/js/docs/workflows.md +217 -0
  50. package/rules/ga/lint/docs/lint.md +209 -0
  51. package/rules/ga/policy/clean_merged_branch/clean_merged_branch.rego +11 -2
  52. package/rules/ga/policy/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml +3 -4
  53. package/rules/graphql/docs/fix.md +126 -0
  54. package/rules/graphql/js/docs/tooling.md +264 -0
  55. package/rules/graphql/lib/docs/graphql-gql-scan.md +219 -0
  56. package/rules/hasura/docs/fix.md +120 -0
  57. package/rules/hasura/hasura.mdc +14 -0
  58. package/rules/hasura/js/docs/internal_urls.md +326 -0
  59. package/rules/image-avif/docs/fix.md +132 -0
  60. package/rules/image-avif/js/docs/avif_generation.md +241 -0
  61. package/rules/image-compress/docs/fix.md +150 -0
  62. package/rules/image-compress/js/docs/package_setup.md +191 -0
  63. package/rules/js-bun-db/docs/fix.md +148 -0
  64. package/rules/js-bun-db/js/docs/safety.md +231 -0
  65. package/rules/js-bun-db/js-bun-db.mdc +42 -13
  66. package/rules/js-bun-db/lib/docs/bun-sql-scan.md +347 -0
  67. package/rules/js-bun-redis/docs/fix.md +123 -0
  68. package/rules/js-bun-redis/js/docs/imports.md +176 -0
  69. package/rules/js-bun-redis/lib/docs/redis-imports.md +223 -0
  70. package/rules/js-lint/docs/fix.md +117 -0
  71. package/rules/js-lint/js/docs/lint.md +250 -0
  72. package/rules/js-lint/js/docs/tooling.md +348 -0
  73. package/rules/js-lint/js/docs/utils_imports.md +207 -0
  74. package/rules/js-lint-ci/docs/fix.md +154 -0
  75. package/rules/js-lint-ci/js/docs/lint.md +144 -0
  76. package/rules/js-mssql/docs/fix.md +128 -0
  77. package/rules/js-mssql/js/docs/deps.md +263 -0
  78. package/rules/js-mssql/lib/docs/mssql-pool-scan.md +367 -0
  79. package/rules/js-run/docs/fix.md +144 -0
  80. package/rules/js-run/js/docs/runtime.md +388 -0
  81. package/rules/js-run/lib/docs/bunyan-imports.md +117 -0
  82. package/rules/js-run/lib/docs/check-env-scan.md +433 -0
  83. package/rules/js-run/lib/docs/conn-file-rules.md +300 -0
  84. package/rules/js-run/lib/docs/conn-imports-scan.md +204 -0
  85. package/rules/js-run/lib/docs/promise-settimeout-scan.md +326 -0
  86. package/rules/k8s/docs/fix.md +129 -0
  87. package/rules/k8s/js/docs/manifests.md +344 -0
  88. package/rules/k8s/js/manifests.mjs +6 -2
  89. package/rules/k8s/k8s.mdc +4 -2
  90. package/rules/k8s/lint/docs/lint.md +411 -0
  91. package/rules/k8s/policy/network_policy/template/deployment.snippet.yaml +2 -0
  92. package/rules/k8s/policy/network_policy/template/stateful-set.snippet.yaml +2 -0
  93. package/rules/nginx-default-tpl/docs/fix.md +124 -0
  94. package/rules/nginx-default-tpl/js/docs/template.md +378 -0
  95. package/rules/npm-module/docs/fix.md +98 -0
  96. package/rules/npm-module/js/docs/package_structure.md +274 -0
  97. package/rules/npm-module/js/docs/rule_meta.md +137 -0
  98. package/rules/npm-module/js/docs/skill_meta.md +190 -0
  99. package/rules/php/docs/fix.md +107 -0
  100. package/rules/php/js/docs/tooling.md +152 -0
  101. package/rules/php/lint/docs/lint.md +215 -0
  102. package/rules/python/docs/fix.md +163 -0
  103. package/rules/python/js/docs/applies.md +108 -0
  104. package/rules/python/js/docs/tooling.md +153 -0
  105. package/rules/python/lint/docs/lint.md +322 -0
  106. package/rules/rego/docs/fix.md +121 -0
  107. package/rules/rego/js/docs/applies.md +174 -0
  108. package/rules/rego/js/docs/lint.md +118 -0
  109. package/rules/rego/lint/docs/lint.md +204 -0
  110. package/rules/release/docs/change.md +185 -0
  111. package/rules/release/docs/fix.md +119 -0
  112. package/rules/release/docs/release.md +222 -0
  113. package/rules/release/lib/docs/aggregate.md +246 -0
  114. package/rules/release/lib/docs/change-file.md +200 -0
  115. package/rules/release/lib/docs/fallback.md +203 -0
  116. package/rules/rust/docs/fix.md +129 -0
  117. package/rules/rust/js/docs/applies.md +140 -0
  118. package/rules/rust/lib/docs/has-cargo-toml.md +130 -0
  119. package/rules/security/docs/fix.md +86 -0
  120. package/rules/security/js/docs/lint.md +171 -0
  121. package/rules/security/js/docs/sample_secret.md +190 -0
  122. package/rules/security/js/docs/trufflehog.md +137 -0
  123. package/rules/security/js/lint.mjs +9 -1
  124. package/rules/style-lint/docs/fix.md +155 -0
  125. package/rules/style-lint/js/docs/lint.md +184 -0
  126. package/rules/style-lint/js/docs/tooling.md +194 -0
  127. package/rules/tauri/docs/fix.md +158 -0
  128. package/rules/tauri/js/docs/cargo_mutants_config.md +168 -0
  129. package/rules/tauri/js/docs/tooling.md +228 -0
  130. package/rules/test/coverage/coverage.mjs +15 -3
  131. package/rules/test/docs/fix.md +132 -0
  132. package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +138 -0
  133. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +134 -0
  134. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +160 -0
  135. package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +195 -0
  136. package/rules/test/js/docs/cargo_mutants_config.md +173 -0
  137. package/rules/test/js/docs/location.md +136 -0
  138. package/rules/test/js/docs/no-process-chdir.md +160 -0
  139. package/rules/test/js/docs/no-relative-fs-path.md +271 -0
  140. package/rules/test/js/docs/stryker_config.md +152 -0
  141. package/rules/test/js/docs/vitest-config-pool-forks.md +174 -0
  142. package/rules/text/docs/fix.md +118 -0
  143. package/rules/text/js/docs/forbidden-prettier.md +143 -0
  144. package/rules/text/js/docs/formatting.md +256 -0
  145. package/rules/text/js/docs/lint.md +122 -0
  146. package/rules/text/lint/docs/lint.md +220 -0
  147. package/rules/text/lint/docs/run-dotenv-linter.md +157 -0
  148. package/rules/text/lint/docs/run-shellcheck.md +212 -0
  149. package/rules/text/lint/docs/run-v8r.md +197 -0
  150. package/rules/vue/docs/fix.md +127 -0
  151. package/rules/vue/js/docs/packages.md +335 -0
  152. package/rules/vue/lib/docs/vue-forbidden-imports.md +261 -0
  153. package/rules/worktree/docs/fix.md +161 -0
  154. package/schemas/rule-meta.json +5 -1
  155. package/scripts/auto-rules.mjs +7 -4
  156. package/scripts/coverage-classify/docs/apply.md +202 -0
  157. package/scripts/coverage-classify/docs/cache.md +203 -0
  158. package/scripts/coverage-classify/docs/index.md +218 -0
  159. package/scripts/coverage-classify/docs/prompt.md +132 -0
  160. package/scripts/coverage-classify/docs/verdict-schema.md +169 -0
  161. package/scripts/coverage-fix-extract.mjs +122 -0
  162. package/scripts/coverage-fix.mjs +1 -1
  163. package/scripts/dispatcher/docs/graph.md +346 -0
  164. package/scripts/dispatcher/docs/index.md +236 -0
  165. package/scripts/dispatcher/docs/trace.md +296 -0
  166. package/scripts/dispatcher/index.mjs +1 -1
  167. package/scripts/dispatcher/lib/active.mjs +4 -8
  168. package/scripts/dispatcher/lib/commands.mjs +7 -11
  169. package/scripts/dispatcher/lib/docs/active.md +348 -0
  170. package/scripts/dispatcher/lib/docs/artifact.md +232 -0
  171. package/scripts/dispatcher/lib/docs/budget.md +167 -0
  172. package/scripts/dispatcher/lib/docs/capability.md +196 -0
  173. package/scripts/dispatcher/lib/docs/commands.md +210 -0
  174. package/scripts/dispatcher/lib/docs/events.md +182 -0
  175. package/scripts/dispatcher/lib/docs/executor.md +190 -0
  176. package/scripts/dispatcher/lib/docs/flow-lock.md +161 -0
  177. package/scripts/dispatcher/lib/docs/flow-resolve.md +267 -0
  178. package/scripts/dispatcher/lib/docs/gate.md +231 -0
  179. package/scripts/dispatcher/lib/docs/level.md +335 -0
  180. package/scripts/dispatcher/lib/docs/plan-panel.md +181 -0
  181. package/scripts/dispatcher/lib/docs/plan.md +200 -0
  182. package/scripts/dispatcher/lib/docs/planner.md +269 -0
  183. package/scripts/dispatcher/lib/docs/review.md +255 -0
  184. package/scripts/dispatcher/lib/docs/reviewer.md +240 -0
  185. package/scripts/dispatcher/lib/docs/snapshot.md +247 -0
  186. package/scripts/dispatcher/lib/docs/spec.md +203 -0
  187. package/scripts/dispatcher/lib/docs/state-store.md +303 -0
  188. package/scripts/dispatcher/lib/docs/subagent-runner.md +173 -0
  189. package/scripts/dispatcher/lib/executor.mjs +6 -1
  190. package/scripts/dispatcher/lib/flow-resolve.mjs +3 -1
  191. package/scripts/dispatcher/lib/level.mjs +29 -3
  192. package/scripts/dispatcher/lib/review.mjs +1 -1
  193. package/scripts/dispatcher/lib/subagent-runner.mjs +5 -3
  194. package/scripts/docs/auto-rules.md +376 -0
  195. package/scripts/docs/auto-skills.md +173 -0
  196. package/scripts/docs/build-agents-commands.md +183 -0
  197. package/scripts/docs/cli-entry.md +153 -0
  198. package/scripts/docs/coverage-fix.md +177 -0
  199. package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +189 -0
  200. package/scripts/lib/changed-files.mjs +4 -1
  201. package/scripts/lib/docs/changed-files.md +149 -0
  202. package/scripts/lib/docs/check-mdc-template-refs.md +222 -0
  203. package/scripts/lib/docs/check-reporter.md +175 -0
  204. package/scripts/lib/docs/discover-check-rules-from-cursor.md +157 -0
  205. package/scripts/lib/docs/discover-checkable-rules.md +165 -0
  206. package/scripts/lib/docs/ensure-tool.md +254 -0
  207. package/scripts/lib/docs/generated-markdown.md +275 -0
  208. package/scripts/lib/docs/gha-workflow.md +326 -0
  209. package/scripts/lib/docs/inline-template-links.md +303 -0
  210. package/scripts/lib/docs/list-rule-ids.md +156 -0
  211. package/scripts/lib/docs/load-cursor-config.md +147 -0
  212. package/scripts/lib/docs/mirror-parity.md +167 -0
  213. package/scripts/lib/worktree.mjs +26 -0
  214. package/scripts/worktree-cli.mjs +12 -2
  215. package/skills/coverage-fix/SKILL.md +34 -45
  216. package/skills/docgen/SKILL.md +44 -23
  217. package/skills/docgen/bench/etalon/firebase_hosting.md +19 -0
  218. package/skills/docgen/bench/etalon/k8s-tree.md +24 -0
  219. package/skills/docgen/bench/etalon/overlay-paths.md +24 -0
  220. package/skills/docgen/js/docgen-ignore.mjs +54 -0
  221. package/skills/docgen/js/docgen-scan.mjs +37 -21
  222. package/skills/llm-patch/SKILL.md +23 -2
  223. package/skills/start-check/SKILL.md +26 -53
  224. package/skills/start-check/js/check.mjs +211 -0
  225. package/skills/taze/SKILL.md +9 -3
  226. package/skills/taze/js/diff.mjs +154 -0
  227. package/types/bin/n-cursor.d.ts +1 -1
  228. package/skills/fix-tests/SKILL.md +0 -119
  229. package/skills/fix-tests/meta.json +0 -1
@@ -0,0 +1,138 @@
1
+ # stryker-vue-macros-ignorer.mjs
2
+
3
+ ## Огляд
4
+
5
+ Файл `stryker-vue-macros-ignorer.mjs` — це Stryker `Ignore`-plugin (мутаційне тестування), який інструктує Stryker не мутувати виклики Vue `<script setup>`-макросів: `defineProps`, `defineEmits`, `defineModel`, `defineSlots`, `defineExpose`, `defineOptions`.
6
+
7
+ Контекст проблеми:
8
+
9
+ - Stryker інструментує код тестового проєкту, обгортаючи вирази у тернарне покриттєве вираження виду `stryMutAct_9fa48(...) ? {} : (stryCov_9fa48(...), {...})`.
10
+ - Vue компайлер `@vue/compiler-sfc` вимагає, щоб аргументи макросів у `<script setup>` (наприклад `defineProps({...})`) були **статично-аналізованими** на етапі compile-sfc — макрос не може посилатися на локально оголошені змінні чи знаходитися всередині умовних виразів.
11
+ - Без цього ignorer-плагіна Stryker-інструментація створює саме такий «динамічний» вираз і `@vue/compiler-sfc` падає з помилкою:
12
+
13
+ ```
14
+ defineProps() in <script setup> cannot reference locally declared variables
15
+ ```
16
+
17
+ Розв'язання: цей плагін під час обходу AST повертає Stryker'у не-порожнє повідомлення для будь-якого `CallExpression`, у якого `callee` — `Identifier` з ім'ям одного з шести Vue-макросів. Stryker, отримавши непорожнє значення з `shouldIgnore(path)`, **пропускає мутацію цілого піддерева** виклику і залишає оригінальний код незмінним. Як наслідок — згенерований інструментований код залишається сумісним з вимогами `@vue/compiler-sfc`.
18
+
19
+ Файл є частиною fixture-конфігурації для тестування правил у `npm/rules/test/js/data/stryker_config/` і вмикається в Stryker'і у двох місцях `stryker.config.mjs` поряд: у масиві `plugins: ['./stryker-vue-macros-ignorer.mjs']` (завантаження плагіна) і `ignorers: ['vue-macros']` (активація конкретного ignorer'а за ім'ям).
20
+
21
+ ## Експорти / API
22
+
23
+ Модуль експортує два публічних символи (обидва — named exports, ESM):
24
+
25
+ | Символ | Тип | Призначення |
26
+ | ---------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | `shouldIgnore` | `(path) => string \| undefined` | Predicate-функція, яку Stryker-інструментер викликає для кожного вузла AST. Повертає повідомлення-причину, якщо мутацію треба пропустити. |
28
+ | `strykerPlugins` | `Array<{kind, name, value}>` | Стандартний експорт, який очікує plugin-loader зі Stryker (`@stryker-mutator/core/.../plugin-loader.js`). Містить один запис типу `Ignore`. |
29
+
30
+ Жодних default-експортів модуль не має.
31
+
32
+ ### `strykerPlugins`
33
+
34
+ ```js
35
+ export const strykerPlugins = [
36
+ {
37
+ kind: 'Ignore',
38
+ name: 'vue-macros',
39
+ value: { shouldIgnore }
40
+ }
41
+ ]
42
+ ```
43
+
44
+ Поля:
45
+
46
+ - `kind: 'Ignore'` — категорія плагіна для Stryker; саме така категорія дозволяє пропускати мутації за рішенням `shouldIgnore`.
47
+ - `name: 'vue-macros'` — ім'я плагіна; саме це значення треба вказати у `ignorers: ['vue-macros']` у `stryker.config.mjs`, щоб увімкнути плагін.
48
+ - `value: { shouldIgnore }` — об'єкт-реалізація з єдиним методом `shouldIgnore`.
49
+
50
+ ## Функції
51
+
52
+ ### `shouldIgnore(path)`
53
+
54
+ ```js
55
+ export function shouldIgnore(path)
56
+ ```
57
+
58
+ **Призначення:** вирішити, чи треба пропустити мутацію поточного AST-вузла. Викликається Stryker-інструментером під час обходу AST-дерева коду, який інструментується для мутаційного тестування.
59
+
60
+ **Параметри:**
61
+
62
+ | Ім'я | Тип | Опис |
63
+ | ------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | `path` | `NodePath` (Babel-сумісний) | Об'єкт-обгортка над вузлом AST, який Stryker передає для перевірки. Очікувані поля/методи: `path.isCallExpression(): boolean` та `path.node.callee: { type: string, name?: string }`. |
65
+
66
+ **Повертає:**
67
+
68
+ - `string` (не-порожній) — повідомлення-причина, чому мутацію треба пропустити. Stryker, отримавши такий рядок, **не мутує** всеце піддерево виклику.
69
+ - `undefined` — продовжити стандартний процес: дозволити Stryker мутувати цей вузол.
70
+
71
+ **Алгоритм (послідовно):**
72
+
73
+ 1. Якщо `path.isCallExpression()` повертає `false` — це не виклик функції, виходимо з `undefined` (нічого не пропускаємо).
74
+ 2. Беремо `callee = path.node.callee`.
75
+ 3. Якщо `callee.type !== 'Identifier'` — це не простий ідентифікатор (наприклад, `obj.method()` або `(fn)()`), виходимо з `undefined`.
76
+ 4. Якщо `callee.name` відсутній у наборі `VUE_SETUP_MACROS` — це не Vue-макрос, виходимо з `undefined`.
77
+ 5. Інакше повертаємо рядок `IGNORE_MESSAGE` — Stryker пропускає мутацію піддерева цього виклику.
78
+
79
+ **Side effects:** немає. Функція чиста (pure): не змінює `path`, не пише в зовнішній стан, не робить I/O.
80
+
81
+ **Граничні випадки:**
82
+
83
+ - Виклик через member-expression (`Vue.defineProps(...)`) **не** збігається, бо `callee.type === 'MemberExpression'`, а не `'Identifier'` — реальні Vue макроси завжди викликаються як вільні ідентифікатори у `<script setup>`, тому це коректно.
84
+ - Перейменовані імпорти (`import { defineProps as dp } from 'vue'`) не збігаються — це теж відповідає реальній семантиці Vue-макросів, які працюють лише з канонічними іменами.
85
+ - Локальні функції з тими самими іменами у звичайному коді (не `<script setup>`) теж будуть пропускатися — це навмисне послаблення в межах fixture'и; не вважається проблемою, оскільки такий код у проєкті дуже рідкісний.
86
+
87
+ ## Внутрішні константи
88
+
89
+ | Ім'я | Тип | Значення |
90
+ | ------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | `VUE_SETUP_MACROS` | `Set<string>` | `{'defineProps', 'defineEmits', 'defineModel', 'defineSlots', 'defineExpose', 'defineOptions'}` — повний канонічний набір Vue 3 `<script setup>` макросів. `Set` обрано для O(1) перевірки `has(name)`. |
92
+ | `IGNORE_MESSAGE` | `string` | `'Vue <script setup> macro call cannot be mutated (defineProps/defineEmits/etc. must be statically analyzable for @vue/compiler-sfc).'` — повідомлення, яке потрапляє до Stryker-звіту як причина пропуску мутації. |
93
+
94
+ Обидві константи приватні для модуля (не експортуються).
95
+
96
+ ## Залежності
97
+
98
+ - **Stryker (runtime контракт):** модуль не імпортує жодних бібліотек, але неявно покладається на API Stryker'а:
99
+ - `@stryker-mutator/core` plugin-loader (`.../plugin-loader.js`) — шукає named export `strykerPlugins`.
100
+ - Stryker-інструментер передає у `shouldIgnore` Babel-NodePath-подібний об'єкт із методом `isCallExpression()` та полем `node.callee`.
101
+ - **Vue:** модуль не імпортує `vue`, але семантика всіх шести макросів та обмеження «cannot reference locally declared variables» — це частина контракту `@vue/compiler-sfc`.
102
+ - **Babel AST shape:** покладається на стандартну структуру вузлів Babel (`CallExpression`, `Identifier`).
103
+ - **Імпорти:** жодних `import`-инструкцій. Модуль самодостатній.
104
+
105
+ ## Потік виконання / Використання
106
+
107
+ Очікуване підключення у `stryker.config.mjs` (поряд із цим файлом):
108
+
109
+ ```js
110
+ // stryker.config.mjs
111
+ export default {
112
+ // ...решта Stryker-конфігурації
113
+ plugins: ['./stryker-vue-macros-ignorer.mjs'],
114
+ ignorers: ['vue-macros']
115
+ // ...
116
+ }
117
+ ```
118
+
119
+ Послідовність роботи в одному прогоні Stryker:
120
+
121
+ 1. **Bootstrap.** Stryker читає `stryker.config.mjs`, бачить шлях `'./stryker-vue-macros-ignorer.mjs'` у `plugins` і динамічно імпортує модуль.
122
+ 2. **Plugin registration.** Plugin-loader дістає named export `strykerPlugins`, ітерує його і реєструє запис `{kind: 'Ignore', name: 'vue-macros', value: {shouldIgnore}}` у внутрішньому реєстрі плагінів-ігнорерів.
123
+ 3. **Activation.** Stryker звіряє реєстр з конфігураційним полем `ignorers: ['vue-macros']` і активує цей плагін за ім'ям. Якщо `name` у `ignorers` відсутній — плагін зареєстрований, але не використовується.
124
+ 4. **AST traversal.** Stryker-інструментер обходить AST кожного файлу-кандидата на мутацію. Для кожного вузла, який є потенційним кандидатом на мутацію, викликає `shouldIgnore(path)` усіх активних `Ignore`-плагінів.
125
+ 5. **Decision.** Якщо `shouldIgnore` повертає рядок — Stryker позначає цю мутацію як **Ignored**, не вставляє в неї `stryMutAct_*`/`stryCov_*`-обгортки і записує `IGNORE_MESSAGE` у звіт як причину.
126
+ 6. **Codegen.** Для виклику Vue-макроса в інструментованому файлі залишається оригінальний код `defineProps({...})` без тернарного покриттєвого виразу — `@vue/compiler-sfc` успішно компілює `<script setup>`.
127
+ 7. **Mutation testing run.** Тести виконуються над інструментованим кодом; мутації решти коду перевіряються нормально, а Vue-макроси не псуються.
128
+
129
+ Якщо плагін **не активувати** (або зареєструвати без рядка `'vue-macros'` у `ignorers`) — Stryker почне інструментувати макроси, і Vue компайлер впаде з помилкою «defineProps() in &lt;script setup&gt; cannot reference locally declared variables» ще до виконання тестів.
130
+
131
+ ## Особливості та обмеження
132
+
133
+ - Покриває **всі шість** Vue 3 `<script setup>` макросів станом на актуальну версію Vue 3 — нові макроси (якщо з'являться) треба буде додавати у `VUE_SETUP_MACROS` вручну.
134
+ - Не розпізнає виклики через member-expression (`Vue.defineProps`) та перейменовані ідентифікатори — це відповідає реальним обмеженням Vue-макросів, тому є коректним.
135
+ - Працює з рівнем гранулярності «весь виклик» — Stryker пропускає мутацію всього піддерева `CallExpression`, включно з його аргументами; це навмисна поведінка, бо мутувати аргумент `defineProps({...})` теж зламає compile-sfc.
136
+ - Функція чиста — її легко тестувати ізольовано, передаючи власні mock'и `NodePath`-подібних об'єктів.
137
+
138
+ Rebuild Test.
@@ -0,0 +1,134 @@
1
+ # stryker.config.baseline.mjs
2
+
3
+ ## Огляд
4
+
5
+ Файл `stryker.config.baseline.mjs` — це еталонна (baseline) конфігурація для інструмента mutation testing **Stryker Mutator** (`@stryker-mutator/core`). Він являє собою тестову/довідкову фікстуру, розміщену в директорії з даними для перевірочного правила (`npm/rules/test/js/data/stryker_config/`), і слугує канонічним зразком того, як має виглядати «правильна» Stryker-конфігурація у проєкті.
6
+
7
+ Файл написаний у форматі ES Module (`.mjs`) і експортує єдиний дефолтний об'єкт із набором опцій, що повністю задають поведінку Stryker-у:
8
+
9
+ - запуск через **Vitest** test-runner (замість commandRunner);
10
+ - `perTest` coverage analysis для максимального прискорення;
11
+ - ввімкнений **incremental** режим зі збереженням стану між запусками;
12
+ - два репортери (`json` для машинного парсингу та `clear-text` для людиночитного виводу в консоль);
13
+ - усі артефакти (тимчасові файли, JSON-репорт, incremental-state) розміщуються під теками `reports/stryker/...`.
14
+
15
+ Об'єкт типізовано через JSDoc-анотацію `@type {import('@stryker-mutator/core').PartialStrykerOptions}`, що дає TypeScript-сумісну валідацію в IDE без переходу на `.ts`.
16
+
17
+ ## Експорти / API
18
+
19
+ Файл має один експорт — **default export**.
20
+
21
+ | Експорт | Тип | Опис |
22
+ | --------- | --------------------------------------------------- | ---------------------------- |
23
+ | `default` | `PartialStrykerOptions` (з `@stryker-mutator/core`) | Об'єкт конфігурації Stryker. |
24
+
25
+ ### Структура експортованого об'єкта
26
+
27
+ | Ключ | Тип | Значення | Призначення |
28
+ | ------------------ | ---------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
29
+ | `testRunner` | `string` | `'vitest'` | Test-runner-плагін, через який Stryker виконує тести проти мутантів. |
30
+ | `vitest` | `object` | `{ configFile: 'vitest.config.js' }` | Налаштування Vitest-runner-а. Поле `configFile` вказує шлях до конфігурації Vitest, яку Stryker реюзає. |
31
+ | `coverageAnalysis` | `string` | `'perTest'` | Режим аналізу покриття. `perTest` — Stryker для кожного мутанта запускає лише ті тести, що покривають мутовану лінію коду. |
32
+ | `tempDirName` | `string` | `'reports/stryker/.tmp'` | Тимчасова директорія для проміжних файлів Stryker під час прогону. |
33
+ | `reporters` | `string[]` | `['json', 'clear-text']` | Список увімкнених репортерів. `json` пише машинно-читний звіт, `clear-text` виводить у термінал. |
34
+ | `jsonReporter` | `object` | `{ fileName: 'reports/stryker/mutation.json' }` | Налаштування JSON-репортера; `fileName` — шлях для запису підсумкового звіту. |
35
+ | `incremental` | `boolean` | `true` | Вмикає incremental-режим: Stryker зберігає результати між запусками й перевикористовує їх. |
36
+ | `incrementalFile` | `string` | `'reports/stryker/incremental.json'` | Шлях до файлу зі станом incremental-режиму (попередні результати мутацій). |
37
+
38
+ ## Функції
39
+
40
+ Файл **не містить функцій, класів чи виконуваного коду** — це чисто декларативний конфігураційний модуль. Він лише експортує літерал-об'єкт.
41
+
42
+ ### Side effects
43
+
44
+ Side effects на рівні модуля **відсутні**:
45
+
46
+ - немає звернень до файлової системи в момент імпорту;
47
+ - немає викликів зовнішніх API;
48
+ - немає мутацій глобальних об'єктів;
49
+ - немає динамічних `import()` чи `require`.
50
+
51
+ Усі ефекти виникають **пізніше** — коли Stryker CLI читає цей модуль і застосовує його опції під час запуску mutation-тестування.
52
+
53
+ ## Залежності
54
+
55
+ ### Runtime-залежності
56
+
57
+ Файл **не імпортує** жодних модулів і не має runtime-залежностей.
58
+
59
+ ### Type-only залежності (через JSDoc)
60
+
61
+ | Пакет | Імпортований символ | Призначення |
62
+ | ----------------------- | ----------------------- | -------------------------------------------------------------------------------------------------- |
63
+ | `@stryker-mutator/core` | `PartialStrykerOptions` | Тип для type-checking структури об'єкта конфігурації в IDE/TypeScript. На runtime не підтягується. |
64
+
65
+ ### Опосередковані залежності (потрібні Stryker-у під час прогону)
66
+
67
+ Хоча файл їх не імпортує, для виконання конфігурації в робочому проєкті мають бути встановлені:
68
+
69
+ | Пакет | Роль |
70
+ | -------------------------------- | -------------------------------------------------------------------------------------- |
71
+ | `@stryker-mutator/core` | Ядро Stryker. |
72
+ | `@stryker-mutator/vitest-runner` | Плагін test-runner-а для Vitest (підвантажується за значенням `testRunner: 'vitest'`). |
73
+ | `vitest` | Сам Vitest з конфігом `vitest.config.js` у корені проєкту. |
74
+
75
+ ### Файлові залежності
76
+
77
+ - `vitest.config.js` (відносний шлях від робочого каталогу запуску Stryker-у) — Vitest-конфіг, який Stryker реюзає.
78
+
79
+ ### Вихідні артефакти (створюються Stryker-ом)
80
+
81
+ | Шлях | Що містить |
82
+ | ---------------------------------- | -------------------------------------------------------------- |
83
+ | `reports/stryker/.tmp/` | Тимчасові файли під час прогону (видаляються/перезаписуються). |
84
+ | `reports/stryker/mutation.json` | Підсумковий JSON-звіт із результатами всіх мутантів. |
85
+ | `reports/stryker/incremental.json` | Стан incremental-режиму для прискорення наступних прогонів. |
86
+
87
+ ## Потік виконання / Використання
88
+
89
+ ### Як файл використовується
90
+
91
+ Файл розміщений у тестовій директорії `npm/rules/test/js/data/stryker_config/` і призначений як **тестова фікстура / еталон** для перевірочних правил (rule-checks), що валідують Stryker-конфіги в реальних воркспейсах монорепо. Тобто rule-checker може:
92
+
93
+ 1. читати цей файл як «known good» приклад;
94
+ 2. порівнювати з ним конфіги воркспейсів;
95
+ 3. виявляти відхилення (відсутність `incremental`, неправильний `coverageAnalysis`, неправильний `testRunner` тощо).
96
+
97
+ ### Якби файл застосовувався як справжній Stryker-конфіг
98
+
99
+ Якщо покласти його в корінь воркспейсу під ім'ям `stryker.config.mjs`, Stryker CLI підхопить його автоматично. Запуск:
100
+
101
+ ```bash
102
+ bunx stryker run
103
+ ```
104
+
105
+ Потік виконання:
106
+
107
+ 1. **Завантаження конфігу.** Stryker CLI читає `stryker.config.mjs`, бере дефолтний експорт як `PartialStrykerOptions`.
108
+ 2. **Розв'язання test-runner-а.** За значенням `testRunner: 'vitest'` Stryker динамічно підвантажує `@stryker-mutator/vitest-runner`.
109
+ 3. **Ініціалізація Vitest.** Vitest-runner читає `vitest.config.js` (поле `vitest.configFile`) і налаштовує Vitest-інстанс.
110
+ 4. **Перевірка incremental-стану.** Якщо файл `reports/stryker/incremental.json` існує (`incremental: true`), Stryker завантажує попередні результати й пропускає ті мутанти, що не змінилися (дає **~262×** прискорення на noop-прогонах згідно коментаря в коді, з посиланням на `benchmarks/runner-comparison/SPIKE.md`).
111
+ 5. **Coverage analysis.** Stryker генерує coverage-карту й для кожного мутанта (`perTest`) обирає лише підмножину тестів, що покривають мутовану лінію, замість прогону всього test-suite.
112
+ 6. **Прогон мутантів.** Concurrency за замовчуванням — `os.cpus().length - 1` (як зазначено в коментарях; явно в конфізі не задано). vitest-runner ізолює мутантів **у пам'яті через AST-patching** — не копіює `node_modules` у sandbox, що було проблемою command-runner-а в Bun-монорепо.
113
+ 7. **Тимчасові артефакти.** Усе проміжне пишеться у `reports/stryker/.tmp/`.
114
+ 8. **Звітування.** Після завершення:
115
+ - `clear-text` репортер друкує підсумок у термінал;
116
+ - `jsonReporter` пише машинний звіт у `reports/stryker/mutation.json`;
117
+ - оновлюється `reports/stryker/incremental.json` для майбутніх прогонів.
118
+
119
+ ### Ключові архітектурні рішення (з коментарів у файлі)
120
+
121
+ - **`perTest` замість `all` / `off`** — головний приріст швидкості проти `commandRunner`, де треба ганяти весь test-suite на кожного мутанта.
122
+ - **Без `inPlace`** — vitest-runner ізолює мутантів через AST-patching у пам'яті, тому копіювання робочої директорії не потрібне (стара проблема command-runner-а у Bun monorepo).
123
+ - **`incremental: true`** — критично для CI/локальних повторних прогонів: відновлює стан після крашу/kill і дає ~262× прискорення на noop-прогонах.
124
+
125
+ ### Передумови запуску (контракт середовища)
126
+
127
+ - існує `vitest.config.js` у CWD;
128
+ - встановлені `@stryker-mutator/core`, `@stryker-mutator/vitest-runner`, `vitest`;
129
+ - тека `reports/stryker/` доступна для запису (Stryker створює її автоматично);
130
+ - наявні тести під Vitest, що покривають кодову базу, яку планується мутувати.
131
+
132
+ ### Інтеграція з правилами проєкту
133
+
134
+ Через шлях `npm/rules/test/js/data/...` файл є вхідними даними для тестів rule-чекерів (див. `.cursor/rules/n-test.mdc`, `.cursor/rules/n-bun.mdc`). Ці чекери, ймовірно, валідують Stryker-конфіги воркспейсів на відповідність цьому baseline (наприклад, що `testRunner === 'vitest'`, `coverageAnalysis === 'perTest'`, `incremental === true`).
@@ -0,0 +1,160 @@
1
+ # stryker.config.vue.baseline.mjs
2
+
3
+ ## Огляд
4
+
5
+ Файл `stryker.config.vue.baseline.mjs` — це **базова (еталонна) конфігурація Stryker** для мутаційного тестування Vue-проєктів, яка використовується як тестові дані (fixture) в наборі тестів правил `npm/rules/test/js/data/stryker_config/`. Розташований у директорії `data/stryker_config/` каталогу тестів пакета `npm/rules`, файл слугує канонічним зразком "як має виглядати правильно налаштований `stryker.config.mjs`" для проєкту з Vue Single-File Components.
6
+
7
+ Файл є простим ES-модулем без логіки: він експортує об'єкт конфігурації за замовчуванням (`export default`). Цей об'єкт повністю описує параметри запуску Stryker mutator-а для Vue-стека (Vitest як test runner, кастомний ignorer для Vue-макросів, increment-кешування, JSON-репортер).
8
+
9
+ Контекст використання:
10
+
11
+ - як **очікуваний baseline** (еталон) у тестах правил, що перевіряють або генерують `stryker.config.mjs` для Vue-проєктів;
12
+ - як **довідковий шаблон** для команд `n-coverage` / `n-cursor coverage`, які запускають мутаційне тестування у Vue-воркспейсах;
13
+ - як **документація-приклад** оптимальних налаштувань (perTest coverage, vitest-runner, incremental, local Vue-macros ignorer plugin).
14
+
15
+ ## Експорти / API
16
+
17
+ Файл має **єдиний експорт** — `default`.
18
+
19
+ | Експорт | Тип | Опис |
20
+ | --------- | --------------------------------------------------- | ------------------------------------------------------------------- |
21
+ | `default` | `PartialStrykerOptions` (з `@stryker-mutator/core`) | Об'єкт конфігурації Stryker для Vue-проєкту з Vitest test runner-ом |
22
+
23
+ JSDoc-анотація `/** @type {import('@stryker-mutator/core').PartialStrykerOptions} */` встановлює тип об'єкта згідно з офіційним TS-типом Stryker, що дає IDE/TS-серверу повну валідацію полів та автодоповнення.
24
+
25
+ ### Структура експортованого об'єкта
26
+
27
+ | Ключ | Значення | Призначення |
28
+ | ----------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
29
+ | `testRunner` | `'vitest'` | Обирає Vitest як тест-раннер для запуску мутантів |
30
+ | `vitest.configFile` | `'vitest.config.js'` | Шлях до конфігурації Vitest, яку має підхопити vitest-runner |
31
+ | `coverageAnalysis` | `'perTest'` | Аналіз покриття на рівні окремих тестів — для кожного мутанта запускаються лише ті тести, що покривають відповідний рядок коду |
32
+ | `tempDirName` | `'reports/stryker/.tmp'` | Тимчасова директорія Stryker (зберігається всередині `reports/`, а не в корені) |
33
+ | `reporters` | `['json', 'clear-text']` | Активні репортери: машинно-читабельний JSON + текстовий вивід у термінал |
34
+ | `jsonReporter.fileName` | `'reports/stryker/mutation.json'` | Куди писати JSON-звіт мутацій |
35
+ | `incremental` | `true` | Вмикає інкрементальний режим: зберігає попередні результати між запусками |
36
+ | `incrementalFile` | `'reports/stryker/incremental.json'` | Файл-кеш для incremental-режиму |
37
+ | `plugins` | `['@stryker-mutator/vitest-runner', './stryker-vue-macros-ignorer.mjs']` | Підключені Stryker-плагіни: офіційний vitest-runner і локальний ignorer для Vue compiler-macros |
38
+ | `ignorers` | `['vue-macros']` | Активні ignorer-плагіни — ім'я `vue-macros` походить з локального плагіна `./stryker-vue-macros-ignorer.mjs` |
39
+
40
+ ## Функції
41
+
42
+ Файл **не містить функцій** — це чисто декларативний конфіг-модуль, що експортує статичний об'єкт. Жодних викликів, фабрик, factory-функцій чи hook-ів немає.
43
+
44
+ ### Side effects
45
+
46
+ Side effects на рівні модуля **відсутні**:
47
+
48
+ - немає `import`-ів (окрім JSDoc type-import у коментарі, який не виконується);
49
+ - немає викликів функцій верхнього рівня;
50
+ - немає мутацій глобального стану;
51
+ - немає I/O.
52
+
53
+ Файл при `import`-уванні просто повертає літерал об'єкта.
54
+
55
+ ## Залежності
56
+
57
+ ### Прямі імпорти
58
+
59
+ **Жодних `import`-операторів немає.** Файл самодостатній на рівні JS-завантаження.
60
+
61
+ ### Тип-залежності (лише через JSDoc)
62
+
63
+ | Пакет | Призначення | Спосіб використання |
64
+ | ----------------------- | ---------------------------------------------------------- | ----------------------------------------------------------- |
65
+ | `@stryker-mutator/core` | Базовий тип `PartialStrykerOptions` для типізації експорту | Через JSDoc `@type {import('...')}` — не впливає на рантайм |
66
+
67
+ ### Імпліцитні runtime-залежності (за іменами рядків)
68
+
69
+ Конфіг **посилається на зовнішні модулі та файли через рядкові ідентифікатори**, які підвантажує сам Stryker під час виконання:
70
+
71
+ | Залежність | Тип | Опис |
72
+ | -------------------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
73
+ | `'vitest'` (значення `testRunner`) | npm-плагін Stryker | Ім'я раннера — Stryker шукає `@stryker-mutator/vitest-runner` у `node_modules` |
74
+ | `'@stryker-mutator/vitest-runner'` (елемент `plugins`) | npm-пакет | Власне реалізація vitest-runner, мусить бути встановленою як devDependency |
75
+ | `'./stryker-vue-macros-ignorer.mjs'` (елемент `plugins`) | локальний модуль | Кастомний Stryker-плагін у тій самій директорії, що пропускає мутацію Vue compiler-macros (`defineProps`, `defineEmits`, `defineModel`, `defineSlots`, `defineExpose`, `defineOptions`) |
76
+ | `'vitest.config.js'` (значення `vitest.configFile`) | файл воркспейсу | Конфігурація Vitest у корені тестованого Vue-воркспейсу |
77
+ | `'vue-macros'` (елемент `ignorers`) | ім'я ignorer-а | Внутрішнє ім'я ignorer-а, яке експортує `./stryker-vue-macros-ignorer.mjs` |
78
+
79
+ ## Потік виконання / Використання
80
+
81
+ ### Як файл використовується
82
+
83
+ 1. **Як test-fixture (eталон)** — тестовий код у `npm/rules/test/js/` читає цей файл як еталонний baseline і порівнює з реальним `stryker.config.mjs` у проєктах, що перевіряються правилом.
84
+ 2. **Як шаблон для генератора** — правило, що автоматично створює/нормалізує `stryker.config.mjs` для Vue-воркспейсів, може використовувати цей файл як вихідну форму.
85
+ 3. **Як приклад у документації** — для розробників, що налаштовують мутаційне тестування Vue вручну.
86
+
87
+ ### Як цей конфіг виконує Stryker (якщо запустити проти Vue-воркспейсу)
88
+
89
+ При виклику `bunx stryker run` (чи через `n-cursor coverage`) Stryker:
90
+
91
+ 1. читає експортований об'єкт як `PartialStrykerOptions`;
92
+ 2. завантажує плагіни зі списку `plugins`:
93
+ - офіційний `@stryker-mutator/vitest-runner` — для запуску мутантів через Vitest;
94
+ - локальний `./stryker-vue-macros-ignorer.mjs` — реєструє ignorer з іменем `'vue-macros'`;
95
+ 3. активує ignorer-и зі списку `ignorers` — у цьому випадку `'vue-macros'` пропускає мутацію аргументів `defineProps` / `defineEmits` / `defineModel` / `defineSlots` / `defineExpose` / `defineOptions`, оскільки інакше Stryker огортав би їх у coverage-тернарник, який `@vue/compiler-sfc` не зміг би статично проаналізувати, і компіляція SFC падала б;
96
+ 4. встановлює `testRunner: 'vitest'` і передає йому `vitest.configFile`;
97
+ 5. виконує **perTest coverage analysis** — заздалегідь запускає тести один раз, фіксує мапу "який тест покриває який рядок", і потім для кожного мутанта виконує лише релевантний підмножину тестів (значно швидше за `command` runner, де довелось би ганяти весь test-suite на кожен мутант);
98
+ 6. використовує `reports/stryker/.tmp` як тимчасову директорію (всередині `reports/`, щоб не засмічувати корінь);
99
+ 7. зберігає звіт у `reports/stryker/mutation.json` через `json`-репортер, паралельно друкує `clear-text` у термінал;
100
+ 8. при `incremental: true` після першого прогону зберігає стан у `reports/stryker/incremental.json`; наступні запуски (особливо noop-прогони, коли код не змінився) виконуються в ~262× швидше (за результатами `benchmarks/runner-comparison/SPIKE.md`, на який посилається коментар у файлі).
101
+
102
+ ### Архітектурні рішення (з коментарів у файлі)
103
+
104
+ - **`coverageAnalysis: 'perTest'`** — головний приріст швидкості проти `command` runner-а, де довелось би запускати весь test-suite на кожен мутант.
105
+ - **Відсутність `inPlace`** — vitest-runner ізолює мутантів у пам'яті через AST-patching, без копіювання `node_modules` у sandbox (стара проблема command runner у Bun monorepo).
106
+ - **`concurrency` не задано** — Stryker за замовчуванням обирає `os.cpus().length - 1`, що оптимально для більшості машин.
107
+ - **Локальний `vue-macros` ignorer** — обов'язковий для Vue-проєктів, інакше Stryker зламає компіляцію SFC при мутації compiler-macros у блоках `<script setup>`.
108
+
109
+ ### Типовий life-cycle конфіга
110
+
111
+ ```text
112
+ import default з stryker.config.vue.baseline.mjs
113
+ |
114
+ v
115
+ PartialStrykerOptions → передається в @stryker-mutator/core
116
+ |
117
+ v
118
+ плагіни підвантажуються: vitest-runner + локальний ignorer
119
+ |
120
+ v
121
+ testRunner='vitest' стартує з vitest.config.js
122
+ |
123
+ v
124
+ perTest coverage map будується
125
+ |
126
+ v
127
+ для кожного мутанта запускається підмножина тестів,
128
+ ignorer 'vue-macros' пропускає Vue compiler-macros
129
+ |
130
+ v
131
+ звіт → reports/stryker/mutation.json (+ clear-text у термінал)
132
+ |
133
+ v
134
+ incremental.json зберігає стан для наступного запуску
135
+ ```
136
+
137
+ ## Rebuild Test
138
+
139
+ Перевірка, що документація відображає реальний вміст файлу:
140
+
141
+ 1. **Експорт**: файл містить **рівно один** `export default` зі статичним об'єктом — підтверджено.
142
+ 2. **Ключі об'єкта**: рівно 10 ключів верхнього рівня: `testRunner`, `vitest`, `coverageAnalysis`, `tempDirName`, `reporters`, `jsonReporter`, `incremental`, `incrementalFile`, `plugins`, `ignorers` — підтверджено.
143
+ 3. **Значення**:
144
+ - `testRunner === 'vitest'`
145
+ - `vitest.configFile === 'vitest.config.js'`
146
+ - `coverageAnalysis === 'perTest'`
147
+ - `tempDirName === 'reports/stryker/.tmp'`
148
+ - `reporters` — масив з двох рядків `['json', 'clear-text']`
149
+ - `jsonReporter.fileName === 'reports/stryker/mutation.json'`
150
+ - `incremental === true`
151
+ - `incrementalFile === 'reports/stryker/incremental.json'`
152
+ - `plugins` — масив з двох рядків: `'@stryker-mutator/vitest-runner'` та `'./stryker-vue-macros-ignorer.mjs'`
153
+ - `ignorers` — масив з одного рядка `['vue-macros']`
154
+ 4. **JSDoc-тип**: `/** @type {import('@stryker-mutator/core').PartialStrykerOptions} */` присутній над `export default` — підтверджено.
155
+ 5. **Імпорти**: жодного `import`-оператора немає — підтверджено.
156
+ 6. **Функції**: жодних оголошень функцій (ні `function`, ні стрілкових) — підтверджено.
157
+ 7. **Side effects на рівні модуля**: відсутні — підтверджено.
158
+ 8. **Коментарі**: усі ключові рішення (`perTest`, відсутність `inPlace`, `incremental` із посиланням на `benchmarks/runner-comparison/SPIKE.md`, призначення локального `vue-macros` ignorer-а) задокументовані inline-коментарями у вихідному файлі — відображено в розділах "Архітектурні рішення" та "Залежності".
159
+
160
+ Документація сумісна з вмістом файла і не містить вигаданих фактів.