gennady 0.6.0 → 0.7.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 (319) hide show
  1. package/README.md +2 -15
  2. package/ai/agents/agent-resolve-conflicts.xml +6 -0
  3. package/ai/agents/agent-review-verifier.xml +6 -0
  4. package/ai/directives/architecture/README.md +21 -0
  5. package/ai/directives/coding/README.md +23 -0
  6. package/ai/directives/coding/result-conventions.xml +55 -0
  7. package/ai/directives/coding/svelte5-runes.xml +248 -0
  8. package/ai/directives/coding/sveltekit-rules.xml +247 -0
  9. package/ai/directives/coding/typescript-rules.xml +589 -0
  10. package/ai/directives/coding/uikit-component-storybook.xml +347 -0
  11. package/ai/directives/coding/uikit-component-svelte.xml +344 -0
  12. package/ai/directives/coding/uikit-spec-drafting.xml +243 -0
  13. package/ai/directives/dbc-audit.directive.xml +131 -0
  14. package/ai/directives/dev-review.directive.xml +148 -0
  15. package/ai/directives/infra/README.md +11 -0
  16. package/ai/directives/infra/eslint-setup.xml +467 -0
  17. package/ai/directives/infra/git-setup.xml +261 -0
  18. package/ai/directives/infra/nodejs-npm-setup.xml +354 -0
  19. package/ai/directives/infra/storybook-setup.xml +153 -0
  20. package/ai/directives/knowledge.xml +206 -0
  21. package/ai/directives/perf-auditor/perf-auditor.directive.xml +75 -0
  22. package/ai/directives/perf-auditor/rules/async-latency.xml +101 -0
  23. package/ai/directives/perf-auditor/rules/data-structures.xml +103 -0
  24. package/ai/directives/perf-auditor/rules/iteration-fusion.xml +96 -0
  25. package/ai/directives/perf-auditor/rules/memory-gc.xml +102 -0
  26. package/ai/directives/sdd/README.md +49 -0
  27. package/ai/directives/sdd/audit.directive.xml +543 -0
  28. package/ai/directives/sdd/discovery.directive.xml +824 -0
  29. package/ai/directives/sdd/fix.directive.xml +249 -0
  30. package/ai/directives/sdd/module-decomposition.directive.xml +666 -0
  31. package/ai/directives/sdd/phase-execution-protocol.xml +339 -0
  32. package/ai/directives/sdd/scaffold.directive.xml +717 -0
  33. package/ai/directives/sdd/setup.directive.xml +213 -0
  34. package/ai/directives/sdd/svelte-ui-discovery.directive.xml +263 -0
  35. package/ai/directives/semantic-change-extractor.directive.xml +99 -0
  36. package/ai/directives/testing/README.md +25 -0
  37. package/ai/directives/testing/common.xml +234 -0
  38. package/ai/directives/testing/node-test.xml +288 -0
  39. package/ai/directives/testing/playwright-cli.xml +199 -0
  40. package/ai/directives/testing/playwright-e2e.xml +292 -0
  41. package/ai/directives/testing/storybook-usage.xml +173 -0
  42. package/ai/directives/testing/svelte-testing.xml +237 -0
  43. package/ai/directives/testing/vitest-rules.xml +326 -0
  44. package/ai/docs/README.md +17 -0
  45. package/ai/docs/ai-icl.md +538 -0
  46. package/ai/docs/ai-priming.md +548 -0
  47. package/ai/docs/ai-prompt-formats.md +406 -0
  48. package/ai/docs/ai-promting.md +572 -0
  49. package/ai/drafts/DRAFT.md +120 -0
  50. package/ai/drafts/agent-devgen-class-from-description.rules.xml +123 -0
  51. package/ai/drafts/agent-typescript-devgen.v1.xml +303 -0
  52. package/ai/drafts/d.md +65 -0
  53. package/ai/drafts/music-posts.md +105 -0
  54. package/ai/fw/v1/architecture/blueprint-factory.xml +77 -0
  55. package/ai/fw/v1/core/mental-model.xml +50 -0
  56. package/ai/fw/v1/discovery/intent-reactor.xml +92 -0
  57. package/ai/fw/v1/production/swarm-protocol.xml +122 -0
  58. package/ai/fw/v1/review/quality-pipeline.xml +102 -0
  59. package/ai/fw/v2/arch-universal.xml +73 -0
  60. package/ai/fw-draft/README.md +79 -0
  61. package/ai/fw-draft/bin/discovery.sh +116 -0
  62. package/ai/fw-draft/gennady.xml +58 -0
  63. package/ai/fw-draft/provider/claude.xml +16 -0
  64. package/ai/fw-draft/provider/cursor.xml +23 -0
  65. package/ai/fw-draft/provider/default.xml +12 -0
  66. package/ai/fw-draft/roles/developer.xml +18 -0
  67. package/ai/fw-draft/router.xml +39 -0
  68. package/ai/fw-draft/routes/development.xml +32 -0
  69. package/ai/fw-draft/routes/universal.xml +58 -0
  70. package/ai/fw-draft/rules/dev/base/file-structure-rules.xml +89 -0
  71. package/ai/fw-draft/rules/dev/typescript/contacts.xml +194 -0
  72. package/dist/ai/agents/agent-resolve-conflicts.xml +6 -0
  73. package/dist/ai/agents/agent-review-verifier.xml +6 -0
  74. package/dist/ai/directives/architecture/README.md +21 -0
  75. package/dist/ai/directives/coding/README.md +23 -0
  76. package/dist/ai/directives/coding/result-conventions.xml +55 -0
  77. package/dist/ai/directives/coding/svelte5-runes.xml +248 -0
  78. package/dist/ai/directives/coding/sveltekit-rules.xml +247 -0
  79. package/dist/ai/directives/coding/typescript-rules.xml +589 -0
  80. package/dist/ai/directives/coding/uikit-component-storybook.xml +347 -0
  81. package/dist/ai/directives/coding/uikit-component-svelte.xml +344 -0
  82. package/dist/ai/directives/coding/uikit-spec-drafting.xml +243 -0
  83. package/dist/ai/directives/dbc-audit.directive.xml +131 -0
  84. package/dist/ai/directives/dev-review.directive.xml +148 -0
  85. package/dist/ai/directives/infra/README.md +11 -0
  86. package/dist/ai/directives/infra/eslint-setup.xml +467 -0
  87. package/dist/ai/directives/infra/git-setup.xml +261 -0
  88. package/dist/ai/directives/infra/nodejs-npm-setup.xml +354 -0
  89. package/dist/ai/directives/infra/storybook-setup.xml +153 -0
  90. package/dist/ai/directives/knowledge.xml +206 -0
  91. package/dist/ai/directives/perf-auditor/perf-auditor.directive.xml +75 -0
  92. package/dist/ai/directives/perf-auditor/rules/async-latency.xml +101 -0
  93. package/dist/ai/directives/perf-auditor/rules/data-structures.xml +103 -0
  94. package/dist/ai/directives/perf-auditor/rules/iteration-fusion.xml +96 -0
  95. package/dist/ai/directives/perf-auditor/rules/memory-gc.xml +102 -0
  96. package/dist/ai/directives/sdd/README.md +49 -0
  97. package/dist/ai/directives/sdd/audit.directive.xml +543 -0
  98. package/dist/ai/directives/sdd/discovery.directive.xml +824 -0
  99. package/dist/ai/directives/sdd/fix.directive.xml +249 -0
  100. package/dist/ai/directives/sdd/module-decomposition.directive.xml +666 -0
  101. package/dist/ai/directives/sdd/phase-execution-protocol.xml +339 -0
  102. package/dist/ai/directives/sdd/scaffold.directive.xml +717 -0
  103. package/dist/ai/directives/sdd/setup.directive.xml +213 -0
  104. package/dist/ai/directives/sdd/svelte-ui-discovery.directive.xml +263 -0
  105. package/dist/ai/directives/semantic-change-extractor.directive.xml +99 -0
  106. package/dist/ai/directives/testing/README.md +25 -0
  107. package/dist/ai/directives/testing/common.xml +234 -0
  108. package/dist/ai/directives/testing/node-test.xml +288 -0
  109. package/dist/ai/directives/testing/playwright-cli.xml +199 -0
  110. package/dist/ai/directives/testing/playwright-e2e.xml +292 -0
  111. package/dist/ai/directives/testing/storybook-usage.xml +173 -0
  112. package/dist/ai/directives/testing/svelte-testing.xml +237 -0
  113. package/dist/ai/directives/testing/vitest-rules.xml +326 -0
  114. package/dist/ai/docs/README.md +17 -0
  115. package/dist/ai/docs/ai-icl.md +538 -0
  116. package/dist/ai/docs/ai-priming.md +548 -0
  117. package/dist/ai/docs/ai-prompt-formats.md +406 -0
  118. package/dist/ai/docs/ai-promting.md +572 -0
  119. package/dist/ai/drafts/DRAFT.md +120 -0
  120. package/dist/ai/drafts/agent-devgen-class-from-description.rules.xml +123 -0
  121. package/dist/ai/drafts/agent-typescript-devgen.v1.xml +303 -0
  122. package/dist/ai/drafts/d.md +65 -0
  123. package/dist/ai/drafts/music-posts.md +105 -0
  124. package/dist/ai/fw/v1/architecture/blueprint-factory.xml +77 -0
  125. package/dist/ai/fw/v1/core/mental-model.xml +50 -0
  126. package/dist/ai/fw/v1/discovery/intent-reactor.xml +92 -0
  127. package/dist/ai/fw/v1/production/swarm-protocol.xml +122 -0
  128. package/dist/ai/fw/v1/review/quality-pipeline.xml +102 -0
  129. package/dist/ai/fw/v2/arch-universal.xml +73 -0
  130. package/dist/ai/fw-draft/README.md +79 -0
  131. package/dist/ai/fw-draft/bin/discovery.sh +116 -0
  132. package/dist/ai/fw-draft/gennady.xml +58 -0
  133. package/dist/ai/fw-draft/provider/claude.xml +16 -0
  134. package/dist/ai/fw-draft/provider/cursor.xml +23 -0
  135. package/dist/ai/fw-draft/provider/default.xml +12 -0
  136. package/dist/ai/fw-draft/roles/developer.xml +18 -0
  137. package/dist/ai/fw-draft/router.xml +39 -0
  138. package/dist/ai/fw-draft/routes/development.xml +32 -0
  139. package/dist/ai/fw-draft/routes/universal.xml +58 -0
  140. package/dist/ai/fw-draft/rules/dev/base/file-structure-rules.xml +89 -0
  141. package/dist/ai/fw-draft/rules/dev/typescript/contacts.xml +194 -0
  142. package/dist/chunks/devtools-B-7ugZhF.js +79 -0
  143. package/dist/chunks/{help.cmd-CWasx25o.js → help.cmd-B_G7EWzF.js} +9 -2
  144. package/dist/chunks/{index-B63fYXL2.js → index-BeL1Zcbg.js} +1 -1
  145. package/dist/chunks/index-CVR66voe.js +26963 -0
  146. package/dist/chunks/index-CXuhZzS3.js +16979 -0
  147. package/dist/chunks/{index-B5bA2T7A.js → index-CaahtXiM.js} +33 -9
  148. package/dist/chunks/{index-iqg0w_pE.js → index-CiEM-8nJ.js} +35 -19
  149. package/dist/chunks/{index-B4m0-PAT.js → index-D1qsi0Uc.js} +57 -33
  150. package/dist/chunks/index-D9ceRUyB.js +443 -0
  151. package/dist/chunks/index-DJpVmyp2.js +176 -0
  152. package/dist/chunks/{index-C0andxna.js → index-DU6jD7SS.js} +1 -1
  153. package/dist/chunks/index-KxSZKmZn.js +540 -0
  154. package/dist/chunks/{index-Dqe1TdW4.js → index-UbHoePfr.js} +12 -12
  155. package/dist/chunks/{index-5xIgwwKx.js → index-g1LXlp77.js} +2 -2
  156. package/dist/chunks/index-zBnnuvLA.js +3788 -0
  157. package/dist/chunks/{run-review-command.logic-a_M3CkeZ.js → run-review-command.logic-DpkRoEi8.js} +2 -2
  158. package/dist/chunks/services-CaLOhuLV.js +2889 -0
  159. package/dist/chunks/shared-Bjy30TeM.js +665 -0
  160. package/dist/cli/cmd/_shared/prompt/io/load-agent-template.io.d.ts +3 -3
  161. package/dist/cli/cmd/_shared/prompt/logic/build-ai-first-knowledge-block.logic.d.ts +3 -3
  162. package/dist/cli/cmd/_shared/prompt/logic/build-ai-verify-placeholders.logic.d.ts +7 -4
  163. package/dist/cli/cmd/_shared/prompt/logic/verify-commands/resolve-verify-commands.logic.d.ts +5 -0
  164. package/dist/cli/cmd/_shared/update-check-worker.d.ts +1 -0
  165. package/dist/cli/cmd/_shared/update-check.d.ts +38 -0
  166. package/dist/cli/cmd/agent-mon/cmd/create-providers.d.ts +15 -0
  167. package/dist/cli/cmd/agent-mon/cmd/index.d.ts +1 -0
  168. package/dist/cli/cmd/agent-mon/cmd/run.d.ts +12 -0
  169. package/dist/cli/cmd/agent-mon/state/create-state-manager.d.ts +32 -0
  170. package/dist/cli/cmd/agent-mon/state/group-by-provider.d.ts +14 -0
  171. package/dist/cli/cmd/agent-mon/state/index.d.ts +5 -0
  172. package/dist/cli/cmd/agent-mon/state/is-waiting.d.ts +9 -0
  173. package/dist/cli/cmd/agent-mon/state/view-model.type.d.ts +74 -0
  174. package/dist/cli/cmd/agent-mon/ui/app.d.ts +16 -0
  175. package/dist/cli/cmd/agent-mon/ui/column-view.d.ts +14 -0
  176. package/dist/cli/cmd/agent-mon/ui/index.d.ts +10 -0
  177. package/dist/cli/cmd/agent-mon/ui/provider-column.d.ts +14 -0
  178. package/dist/cli/cmd/agent-mon/ui/session-card.d.ts +12 -0
  179. package/dist/cli/cmd/agent-mon/ui/status-badge.d.ts +10 -0
  180. package/dist/cli/cmd/alt-opinion/alt-opinion-parser.d.ts +18 -0
  181. package/dist/cli/cmd/alt-opinion/alt-opinion-runner.d.ts +32 -0
  182. package/dist/cli/cmd/alt-opinion/alt-opinion.cmd.d.ts +34 -0
  183. package/dist/cli/cmd/alt-opinion/alt-opinion.types.d.ts +88 -0
  184. package/dist/cli/cmd/alt-opinion/index.d.ts +1 -0
  185. package/dist/cli/cmd/cat/cat-url.fn.d.ts +19 -0
  186. package/dist/cli/cmd/lint/checks/anchor.check.d.ts +11 -0
  187. package/dist/cli/cmd/lint/checks/dbc-contract.check.d.ts +16 -0
  188. package/dist/cli/cmd/lint/checks/disables.check.d.ts +12 -0
  189. package/dist/cli/cmd/lint/checks/file-header.check.d.ts +10 -0
  190. package/dist/cli/cmd/lint/checks/language.check.d.ts +11 -0
  191. package/dist/cli/cmd/lint/index.d.ts +1 -0
  192. package/dist/cli/cmd/lint/lint.cmd.d.ts +18 -0
  193. package/dist/cli/cmd/lint/lint.types.d.ts +72 -0
  194. package/dist/cli/cmd/lint/utils/resolve-references.fn.d.ts +32 -0
  195. package/dist/cli/cmd/remote-console/index.d.ts +2 -0
  196. package/dist/cli/cmd/remote-console/remote-console.cmd.d.ts +55 -0
  197. package/dist/cli/cmd/resolve-conflicts/_core/io/resolve-conflicts-template-load.io.d.ts +2 -2
  198. package/dist/cli/cmd/resolve-conflicts/_core/logic/resolve-conflicts-command-args-parse.logic.d.ts +3 -3
  199. package/dist/cli/cmd/resolve-conflicts/_core/logic/resolve-conflicts-command-run.logic.d.ts +3 -3
  200. package/dist/cli/cmd/resolve-conflicts/_core/logic/resolve-conflicts-context-git-build.logic.d.ts +4 -4
  201. package/dist/cli/cmd/resolve-conflicts/_core/types/resolve-conflicts-artifact.type.d.ts +3 -1
  202. package/dist/cli/cmd/resolve-conflicts/_core/types/resolve-conflicts-command-args.type.d.ts +3 -1
  203. package/dist/cli/cmd/resolve-conflicts/_core/types/resolve-conflicts-command-result.type.d.ts +5 -1
  204. package/dist/cli/cmd/resolve-conflicts/_core/types/resolve-conflicts-context-git.type.d.ts +18 -2
  205. package/dist/cli/cmd/resolve-conflicts/_core/xml/resolve-conflicts-artifact-build.xml.d.ts +6 -6
  206. package/dist/cli/cmd/resolve-conflicts/_core/xml/resolve-conflicts-render.xml.d.ts +4 -4
  207. package/dist/cli/cmd/review/_core/io/load-review-verify-template.io.d.ts +2 -2
  208. package/dist/cli/cmd/review/_core/logic/build-review-context-git.logic.d.ts +3 -3
  209. package/dist/cli/cmd/review/_core/logic/build-review-context-vcs.logic.d.ts +2 -2
  210. package/dist/cli/cmd/review/_core/logic/load-review-context-mr.logic.d.ts +5 -5
  211. package/dist/cli/cmd/review/_core/logic/parse-review-command-args.logic.d.ts +3 -3
  212. package/dist/cli/cmd/review/_core/logic/resolve-review-intent.logic.d.ts +3 -3
  213. package/dist/cli/cmd/review/_core/logic/run-review-command.logic.d.ts +3 -3
  214. package/dist/cli/cmd/review/_core/types/review-artifact.type.d.ts +4 -1
  215. package/dist/cli/cmd/review/_core/types/review-command-args.type.d.ts +7 -1
  216. package/dist/cli/cmd/review/_core/types/review-command-mode.type.d.ts +1 -1
  217. package/dist/cli/cmd/review/_core/types/review-command-options.type.d.ts +3 -1
  218. package/dist/cli/cmd/review/_core/types/review-command-result.type.d.ts +5 -1
  219. package/dist/cli/cmd/review/_core/types/review-context-git.type.d.ts +3 -1
  220. package/dist/cli/cmd/review/_core/types/review-context-mr.type.d.ts +22 -3
  221. package/dist/cli/cmd/review/_core/types/review-context-vcs.type.d.ts +4 -1
  222. package/dist/cli/cmd/review/_core/types/review-intent.type.d.ts +1 -1
  223. package/dist/cli/cmd/review/_core/xml/build-review-artifact.xml.d.ts +10 -10
  224. package/dist/cli/cmd/review/_core/xml/render-review-issues.xml.d.ts +3 -3
  225. package/dist/cli/cmd/review/_core/xml/render-review-verify.xml.d.ts +4 -4
  226. package/dist/cli/cmd/sync/index.d.ts +1 -0
  227. package/dist/cli/cmd/sync/sync-core.d.ts +65 -0
  228. package/dist/cli/cmd/sync/sync-formatter.d.ts +12 -0
  229. package/dist/cli/cmd/sync/sync.cmd.d.ts +33 -0
  230. package/dist/cli/cmd/sync/sync.types.d.ts +50 -0
  231. package/dist/cli/cmd/vcs-reply/vcs-reply.cmd.d.ts +4 -4
  232. package/dist/cli/utils/ai-legacy/ai-legacy-agent.d.ts +12 -11
  233. package/dist/cli/utils/ai-legacy/ai-legacy-core.d.ts +33 -17
  234. package/dist/cli/utils/ai-legacy/ai-legacy-model.d.ts +42 -23
  235. package/dist/cli/utils/cat-gen/cat-gen.d.ts +19 -8
  236. package/dist/cli/utils/commit-gen/commit-gen.d.ts +39 -15
  237. package/dist/cli/utils/prompts/index.d.ts +6 -6
  238. package/dist/cli/utils/review-gen/review-gen.d.ts +33 -9
  239. package/dist/gennady.js +30 -10
  240. package/dist/index.d.ts +1 -0
  241. package/dist/index.js +44 -23
  242. package/dist/services/agent-mon/diff/diff.d.ts +9 -0
  243. package/dist/services/agent-mon/diff/index.d.ts +1 -0
  244. package/dist/services/agent-mon/index.d.ts +10 -0
  245. package/dist/services/agent-mon/model/agent-provider.type.d.ts +20 -0
  246. package/dist/services/agent-mon/model/agent-session.type.d.ts +49 -0
  247. package/dist/services/agent-mon/model/errors.d.ts +20 -0
  248. package/dist/services/agent-mon/model/index.d.ts +7 -0
  249. package/dist/services/agent-mon/model/observe-opts.type.d.ts +7 -0
  250. package/dist/services/agent-mon/model/scan-opts.type.d.ts +7 -0
  251. package/dist/services/agent-mon/model/session-changes.type.d.ts +10 -0
  252. package/dist/services/agent-mon/monitor/agent-monitor.d.ts +44 -0
  253. package/dist/services/agent-mon/monitor/create-monitor.d.ts +6 -0
  254. package/dist/services/agent-mon/monitor/index.d.ts +2 -0
  255. package/dist/services/agent-mon/observe/index.d.ts +1 -0
  256. package/dist/services/agent-mon/observe/observe.d.ts +12 -0
  257. package/dist/services/agent-mon/providers/claude/claude-provider.d.ts +50 -0
  258. package/dist/services/agent-mon/providers/claude/index.d.ts +5 -0
  259. package/dist/services/agent-mon/providers/claude/ps.d.ts +36 -0
  260. package/dist/services/agent-mon/providers/claude/session-json.d.ts +37 -0
  261. package/dist/services/agent-mon/providers/opencode/db.d.ts +41 -0
  262. package/dist/services/agent-mon/providers/opencode/index.d.ts +3 -0
  263. package/dist/services/agent-mon/providers/opencode/model-parser.d.ts +6 -0
  264. package/dist/services/agent-mon/providers/opencode/opencode-provider.d.ts +45 -0
  265. package/dist/services/ai-client/providers/ai-model.type.d.ts +14 -0
  266. package/dist/services/ai-client/providers/open-router/open-router-model.type.d.ts +1 -4
  267. package/dist/services/ai-client/providers/open-router/open-router-provider.d.ts +17 -0
  268. package/dist/services/ai-client/providers/openai-like-provider.d.ts +1 -0
  269. package/dist/services/data-ore/telegram/telegram-data-ore.d.ts +17 -0
  270. package/dist/services/data-ore/telegram/telegram-data-ore.types.d.ts +4 -0
  271. package/dist/services/data-ore/telegram/telegram-demo-music-helper.d.ts +1 -0
  272. package/dist/services/data-ore/telegram/telegram-demo.d.ts +1 -0
  273. package/dist/services/dbc/linter/dbc-ast-adapter.types.d.ts +82 -0
  274. package/dist/services/dbc/linter/dbc-linter.types.d.ts +95 -0
  275. package/dist/services/dbc/linter/implementations/ts/dbc-ts-ast-adapter.d.ts +183 -0
  276. package/dist/services/dbc/linter/implementations/ts/dbc-ts-linter.d.ts +152 -0
  277. package/dist/services/dbc/parser/dbc-parser.types.d.ts +16 -16
  278. package/dist/services/dbc/parser/implementations/jsdoc/dbc-jsdoc-parser.d.ts +14 -4
  279. package/dist/services/logger/logger.d.ts +26 -6
  280. package/dist/services/remote-console/client/remote-console-client-serializer.d.ts +7 -0
  281. package/dist/services/remote-console/client/remote-console-client.d.ts +20 -0
  282. package/dist/services/remote-console/client/remote-console-client.types.d.ts +88 -0
  283. package/dist/services/remote-console/remote-console.d.ts +6 -0
  284. package/dist/services/remote-console/server/remote-console-server.d.ts +10 -0
  285. package/dist/services/remote-console/server/remote-console-server.types.d.ts +44 -0
  286. package/dist/services/remote-console/server/remote-console-stdout-writer.d.ts +26 -0
  287. package/dist/services/vcs-client/abstract/vcs-client-merge-discussions.d.ts +22 -14
  288. package/dist/services/vcs-client/abstract/vcs-client-merge-requests.d.ts +31 -14
  289. package/dist/services/vcs-client/abstract/vcs-client-repository-files.d.ts +16 -0
  290. package/dist/services/vcs-client/abstract/vcs-client.d.ts +9 -5
  291. package/dist/services/vcs-client/entities/vcs-file-content.type.d.ts +24 -0
  292. package/dist/services/vcs-client/entities/vcs-merge-request-changes.type.d.ts +32 -0
  293. package/dist/services/vcs-client/entities/vcs-url.type.d.ts +14 -0
  294. package/dist/services/vcs-client/entities/vcs-user.type.d.ts +3 -0
  295. package/dist/services/vcs-client/github/vcs-github-client.d.ts +31 -0
  296. package/dist/services/vcs-client/github/vcs-github-merge-requests.d.ts +40 -0
  297. package/dist/services/vcs-client/github/vcs-github-repository-files.d.ts +27 -0
  298. package/dist/services/vcs-client/gitlab/vcs-gitlab-client.d.ts +13 -4
  299. package/dist/services/vcs-client/gitlab/vcs-gitlab-merge-discussions.d.ts +16 -5
  300. package/dist/services/vcs-client/gitlab/vcs-gitlab-merge-requests.d.ts +24 -5
  301. package/dist/services/vcs-client/gitlab/vcs-gitlab-repository-files.d.ts +27 -0
  302. package/dist/services/vcs-client/parse-vcs-url.d.ts +3 -0
  303. package/dist/shared/backend/git/git-core.d.ts +24 -22
  304. package/dist/shared/backend/git/git-diff.d.ts +16 -5
  305. package/dist/shared/backend/rc/rc-config.d.ts +27 -15
  306. package/dist/shared/common/exec.d.ts +4 -6
  307. package/dist/shared/common/files.d.ts +1 -3
  308. package/dist/shared/common/language.d.ts +3 -6
  309. package/dist/shared/common/parse-args.d.ts +1 -4
  310. package/dist/shared/common/style.d.ts +3 -3
  311. package/dist/shared/common/think.d.ts +1 -5
  312. package/dist/shared/common/tokens.d.ts +1 -5
  313. package/dist/shared/common/unguard.d.ts +4 -8
  314. package/dist/shared/common/xml.d.ts +16 -12
  315. package/package.json +20 -4
  316. package/dist/.ai/agents/agent-review-verifier.xml +0 -181
  317. package/dist/chunks/index-CNbmXK8M.js +0 -3548
  318. package/dist/chunks/services-Sb7TwLxt.js +0 -122
  319. package/dist/chunks/shared-BgLzFWMH.js +0 -577
@@ -0,0 +1,173 @@
1
+ <StorybookUsageRules keywords="storybook, mcp, component-development, stories, play-function, ai-generated, self-verify" type="testing-rules" ver="2.0">
2
+ <Mission>
3
+ Canonical rules for using an installed Storybook instance to develop and test UI components. Every execution-agent MUST use the MCP integration as the primary source for component documentation, stories, and tests. Hand-written guesses about component props are forbidden — the prop surface comes from `get-documentation` (or its current MCP equivalent), not from memory.
4
+
5
+ **Base axiom:** Storybook is the project's executable component spec. A story IS the contract; running a story IS the verification step. Authoring without consulting the MCP-exposed spec produces stories that compile but fail at first render — the self-healing loop then chases its own tail. So the order is fixed: read spec → write story → run story tests → fix → re-run.
6
+
7
+ Companion (one-time installation): `ai/directives/infra/storybook-setup.xml`.
8
+ </Mission>
9
+
10
+ <Belief_State>
11
+ <Axiom id="AX_SB_USE_NEVER_HALLUCINATE_PROPS">
12
+ Component props, slot/snippet names, exported events, and tags ALWAYS come from the MCP documentation channel before a story is written or edited. Inferring props from name, by analogy with another component, or from chat history is forbidden — hallucinated props pass TypeScript narrowing if the type is loose and fail silently at story render time, burning the self-healing loop on a problem the MCP would have answered immediately.
13
+ </Axiom>
14
+
15
+ <Axiom id="AX_SB_USE_MCP_FIRST">
16
+ MCP tools are the primary source for everything Storybook-related: discovering documentation, reading component props, reading existing stories, executing story tests. Source-code reading is a FALLBACK reserved for when MCP returns an explicit «not available» or incomplete data. Falling back to source must be acknowledged in a story comment naming the MCP gap.
17
+ </Axiom>
18
+
19
+ <Axiom id="AX_SB_USE_ONE_STORY_ONE_CONCEPT">
20
+ Each story exposes ONE concept: one variant, one state, one interaction flow. Combining «logged-in user opens modal AND submits form AND sees error» into a single story collapses three contracts into one diff. When tests fail, the failure cannot be attributed; when the contract shifts, three concepts get tangled in one edit.
21
+ </Axiom>
22
+
23
+ <Axiom id="AX_SB_USE_PLAY_FOR_INTERACTION">
24
+ Any story that exercises user behaviour (click, type, drag, navigation) MUST attach a `play` function asserting the resulting state. A story without `play` for an interactive scenario is documentation only — it provides no executable contract and the self-verification loop has nothing to assert against. `play` uses the project's chosen interaction API (`userEvent`, `step`, framework-provided utilities) consistently.
25
+ </Axiom>
26
+
27
+ <Axiom id="AX_SB_USE_AI_GENERATED_TAG">
28
+ Every agent-authored story carries the reserved tag (project canonical: `'ai-generated'`) in its `tags` array. This separates machine-authored from human-authored stories so human curators can audit, batch-update, or selectively re-test the agent output without scanning every file. Stripping or omitting the tag from an agent-authored story is forbidden.
29
+ </Axiom>
30
+
31
+ <Axiom id="AX_SB_USE_COMPOSE_EXISTING_FIRST">
32
+ When an existing story already covers the base variant the new scenario extends, the new story composes its args from the existing one (`args: { ...ExistingStory.args, fieldToChange: newValue }`) rather than restating the full argument map. Restating duplicates a structure that should drift in only one place; the duplicate becomes the source of truth-drift on the first prop rename.
33
+ </Axiom>
34
+
35
+ <Axiom id="AX_SB_USE_SELF_VERIFY_BEFORE_HANDOFF">
36
+ A story task is not complete until `run-story-tests` (the project's MCP-exposed runner) passes for every story in the affected component file — not just the new one. A new story may break an existing one through a shared mock or a shared decorator; running only the new story hides those breakages.
37
+
38
+ `run-story-tests` failure is NEVER silenced by deleting the failing story or by adding `.skip` — the failure is fixed (component or story), surfaced as a real blocker, or paired with a tracked deferred-ownership reference.
39
+ </Axiom>
40
+
41
+ <Axiom id="AX_SB_USE_COMPONENT_CHANGE_TRIGGERS_STORY_RUN">
42
+ A component edit MUST be followed by `run-story-tests` on every story owned by that component. A story failure after a component edit is, by definition, a regression — either the component contract changed (story must be updated and the change documented) or the edit broke the contract unintentionally (component must be fixed). Either path is acceptable; ignoring the failure is not.
43
+ </Axiom>
44
+
45
+ <Axiom id="AX_SB_USE_NO_PARALLEL_RENDER_HARNESS">
46
+ Component rendering for testing goes through the project's chosen Storybook harness, not through a parallel render path (custom Vitest project mounting the component bypassing the addon, ad-hoc puppet scripts). Parallel harnesses duplicate the render contract and drift the first time a decorator is added; the drift surfaces as «works in Storybook, fails in tests» (or vice versa) with no audit trail.
47
+ </Axiom>
48
+ </Belief_State>
49
+
50
+ <Definitions>
51
+ <Definition id="DEF_SB_MCP_TOOLS">
52
+ MCP tools exposed by the Storybook integration (canonical naming subject to addon version): `list-all-documentation`, `get-documentation`, `get-documentation-for-story`, `get-storybook-story-instructions`, `preview-stories`, `run-story-tests`. Exact names live in `AGENTS.md` per `storybook-setup`.
53
+ </Definition>
54
+ <Definition id="DEF_SB_STORY_CANONICAL_FORM">
55
+ Canonical agent-authored story: `export const VariantName: Story = { args: { ...ExistingStory.args, ...overrides }, tags: ['ai-generated', ...domainTags], play: async ({ canvasElement, step }) => { ... } }`. `play` is required when the story exercises any user interaction.
56
+ </Definition>
57
+ </Definitions>
58
+
59
+ <Code_Patterns>
60
+ <Pattern id="PT_SB_COMPOSED_STORY_WITH_PLAY">
61
+ <Intent>New variant composes args from an existing story, carries the `ai-generated` tag, and asserts behaviour through `play`.</Intent>
62
+ <Snippet language="typescript">
63
+ ```typescript
64
+ import type { Meta, StoryObj } from '@storybook/svelte';
65
+ import { expect, userEvent, within } from '@storybook/test';
66
+ import Button from './Button.svelte';
67
+
68
+ const meta: Meta<typeof Button> = {
69
+ component: Button,
70
+ tags: ['autodocs'],
71
+ };
72
+ export default meta;
73
+
74
+ type Story = StoryObj<typeof meta>;
75
+
76
+ export const Primary: Story = {
77
+ args: { label: 'Submit', variant: 'primary' },
78
+ };
79
+
80
+ export const DisabledClickDoesNothing: Story = {
81
+ args: { ...Primary.args, disabled: true },
82
+ tags: ['ai-generated'],
83
+ play: async ({ canvasElement, step }) => {
84
+ const canvas = within(canvasElement);
85
+ const button = canvas.getByRole('button', { name: 'Submit' });
86
+ await step('Click is a no-op when disabled', async () => {
87
+ await userEvent.click(button);
88
+ await expect(button).toBeDisabled();
89
+ });
90
+ },
91
+ };
92
+ ```
93
+ </Snippet>
94
+ <Why>One concept (disabled-click no-op); args composed from `Primary.args`; `ai-generated` tag present; `play` asserts the contract through role-based query.</Why>
95
+ </Pattern>
96
+ </Code_Patterns>
97
+
98
+ <Anti_Patterns>
99
+ <Anti_Pattern id="AP_SB_HALLUCINATED_PROPS">
100
+ <Bad>Agent writes `<Button label="Go" intent="ghost" size="xl">` based on what «buttons usually have», without consulting MCP; story compiles because props are typed as `Record<string, unknown>` but renders as the default variant.</Bad>
101
+ <Why_Bad>Props guessed instead of retrieved via MCP (`AX_SB_USE_NEVER_HALLUCINATE_PROPS`). Compiles cleanly, fails at render or silently produces the wrong variant — the failure is then chased through the self-healing loop instead of being answered up-front by `get-documentation`.</Why_Bad>
102
+ <Good>Call `get-documentation` on `Button`, read the actual prop schema (e.g. `label`, `variant`, `disabled`), write the story using the documented props only. If MCP returns incomplete data, comment in the story noting the gap and fall back to reading source.</Good>
103
+ </Anti_Pattern>
104
+
105
+ <Anti_Pattern id="AP_SB_MISSING_PLAY_ON_INTERACTION">
106
+ <Bad>Story named `OpensModalOnClick` consists only of `args: { ... }` and no `play` function; the user-flow concept is documentation, not an executable contract.</Bad>
107
+ <Why_Bad>Interactive story without `play` (`AX_SB_USE_PLAY_FOR_INTERACTION`). The self-verification loop has nothing to assert against; `run-story-tests` will pass trivially without exercising the flow that the story name claims to verify.</Why_Bad>
108
+ <Good>Add `play: async ({ canvasElement, step }) => { const canvas = within(canvasElement); await userEvent.click(canvas.getByRole('button', { name: 'Open' })); await expect(canvas.getByRole('dialog')).toBeVisible(); }`.</Good>
109
+ </Anti_Pattern>
110
+
111
+ <Anti_Pattern id="AP_SB_MISSING_AI_TAG">
112
+ <Bad>Agent-authored story carries `tags: ['autodocs']` only — no `'ai-generated'`.</Bad>
113
+ <Why_Bad>Reserved agent-authorship tag missing (`AX_SB_USE_AI_GENERATED_TAG`). Human curators can no longer batch-audit machine output or distinguish it from hand-curated stories; the tag's purpose is to make agent provenance discoverable.</Why_Bad>
114
+ <Good>`tags: ['autodocs', 'ai-generated']`. Composition with other tags is fine; omission of `'ai-generated'` from agent-authored stories is not.</Good>
115
+ </Anti_Pattern>
116
+
117
+ <Anti_Pattern id="AP_SB_SKIP_SELF_VERIFY">
118
+ <Bad>Agent writes a new story, runs only `npx tsc --noEmit`, sees no type error, and marks the task complete without invoking `run-story-tests`.</Bad>
119
+ <Why_Bad>Self-verification skipped (`AX_SB_USE_SELF_VERIFY_BEFORE_HANDOFF`). Type-check covers the prop schema but not the runtime render or the `play` assertions; the story may explode at first execution. The MCP-exposed runner is exactly the channel that catches this in seconds.</Why_Bad>
120
+ <Good>After authoring: `run-story-tests` on every story in the affected component file. Green run → handoff. Red run → fix the story or the component, re-run, repeat until green.</Good>
121
+ </Anti_Pattern>
122
+
123
+ <Anti_Pattern id="AP_SB_REWRITE_INSTEAD_OF_COMPOSE">
124
+ <Bad>New `Disabled` story restates the full `args: { label, variant, size, icon, ariaLabel, ... }` map identical to `Primary.args` except for one field.</Bad>
125
+ <Why_Bad>Args restated instead of composed (`AX_SB_USE_COMPOSE_EXISTING_FIRST`). The duplicated map drifts the first time `Primary.args` gains or renames a field — the `Disabled` story silently falls behind without any test failure pointing at it.</Why_Bad>
126
+ <Good>`args: { ...Primary.args, disabled: true }`. Composition makes the diff visible and keeps the variant aligned with the base.</Good>
127
+ </Anti_Pattern>
128
+ </Anti_Patterns>
129
+
130
+ <Workflow_Outline>
131
+ <Step id="WF_SB_1_RETRIEVE_DOCS">Call `get-documentation` (and `get-documentation-for-story` when extending an existing variant) for the target component. Read prop schema, existing variants, exposed events.</Step>
132
+ <Step id="WF_SB_2_PICK_BASE_OR_NEW">If an existing story matches the base variant, compose args from it. Otherwise author from documented props only.</Step>
133
+ <Step id="WF_SB_3_AUTHOR_ONE_CONCEPT_PER_STORY">One story = one concept. Add `'ai-generated'` tag. Interactive scenarios get a `play` function asserting the post-state.</Step>
134
+ <Step id="WF_SB_4_RUN_STORY_TESTS">Invoke `run-story-tests` for every story in the affected file. Failure → fix component or story, re-run, repeat.</Step>
135
+ <Step id="WF_SB_5_VERIFY_AND_FINALIZE">Before handoff: tests green; props confirmed via MCP; tag present; one concept per story; existing stories not regressed. Environment blocker → declared EXPLICITLY.</Step>
136
+ </Workflow_Outline>
137
+
138
+ <Verification_Hooks>
139
+ <Hook id="HOOK_SB_RUN_STORY_TESTS">
140
+ <Purpose>Story tests pass for the affected component file via the project's MCP-exposed runner (script name from `package.json`).</Purpose>
141
+ <Command>npm run test-storybook -- --url http://localhost:6006</Command>
142
+ <Expected>Exit 0; all stories in scope pass. Non-zero requires fix or explicit deferred-ownership reference.</Expected>
143
+ </Hook>
144
+ <Hook id="HOOK_SB_AI_TAG_PRESENT">
145
+ <Purpose>Every story file modified by the agent has at least one story tagged `'ai-generated'`.</Purpose>
146
+ <Command>find . -name '*.stories.*' -not -path '*/node_modules/*' -print0 | xargs -0 grep -lE "tags:\s*\[[^]]*'ai-generated'" || echo MISSING</Command>
147
+ <Expected>For agent-touched story files, the path appears in output. `MISSING` after an agent-authored story task means the reserved tag was not applied.</Expected>
148
+ </Hook>
149
+ <Hook id="HOOK_SB_INTERACTIVE_STORIES_HAVE_PLAY">
150
+ <Purpose>Stories whose name implies an interaction (`OnClick`, `OpensModal`, `Submits`, `Toggles`) carry a `play` function.</Purpose>
151
+ <Command>find . -name '*.stories.*' -not -path '*/node_modules/*' -print0 | xargs -0 grep -nE 'export const [A-Z][A-Za-z]*(Click|Submits|Opens|Toggles|Types|Drags)' || true</Command>
152
+ <Expected>Manual review: every match resolves to a story whose body contains `play:`. Matches without `play` are violations.</Expected>
153
+ </Hook>
154
+ </Verification_Hooks>
155
+
156
+ <Reward_Criteria>
157
+ ✅ Props, events, slots/snippets retrieved via MCP before any story is written; source-code fallback annotated when used.
158
+ ✅ Each story expresses one concept; multiple variants live as multiple stories.
159
+ ✅ Interactive stories carry a `play` function asserting the post-interaction state.
160
+ ✅ Every agent-authored story carries the `'ai-generated'` tag.
161
+ ✅ New variants compose `args` from the closest existing story rather than restating the full map.
162
+ ✅ `run-story-tests` green for every story in the affected component file before handoff.
163
+ ✅ Component edits trigger a re-run of all owned stories; regressions surface as fix or explicit deferred-ownership.
164
+
165
+ ❌ Hallucinated props, events, or variant names.
166
+ ❌ Interactive story without a `play` function.
167
+ ❌ Agent-authored story missing the `'ai-generated'` tag.
168
+ ❌ Args restated in full when composition with an existing story would suffice.
169
+ ❌ Task marked complete without running `run-story-tests`.
170
+ ❌ Story failure silenced by `.skip` or deletion instead of fixed or escalated.
171
+ ❌ Parallel render harness introduced beside the project's chosen Storybook addon.
172
+ </Reward_Criteria>
173
+ </StorybookUsageRules>
@@ -0,0 +1,237 @@
1
+ <SvelteTestingRules keywords="svelte, testing, vitest, svelte-testing-library, flushSync, effect-root, mount, unmount, jsdom" type="testing-rules" ver="2.0">
2
+ <Mission>
3
+ Canonical rules for testing Svelte 5 components on the Vitest runner with `@testing-library/svelte`. Every execution-agent MUST mount components through testing-library `render()`, flush pending effects via `flushSync()` before assertions, and unmount in cleanup so state cannot leak across cases.
4
+
5
+ **Base axiom:** a Svelte 5 component is a tree of reactive primitives backed by a compile-time effect graph. A test that asserts the DOM without first flushing the effect graph is asserting an arbitrary intermediate state — sometimes green, sometimes red, never trustworthy. So discipline is non-negotiable: render → mutate → `flushSync` → assert → cleanup.
6
+
7
+ Scope: unit/integration tests for `.svelte` components and `.svelte.ts` modules. Out of scope: end-to-end browser tests (covered by `playwright-e2e`) and Storybook-driven story tests (covered by `storybook-usage`).
8
+
9
+ Test files use the `.svelte.test.ts` extension so the Svelte plugin processes their imports.
10
+ </Mission>
11
+
12
+ <Depends_On>
13
+ - ai/directives/testing/vitest-rules.xml
14
+ - ai/directives/coding/svelte5-runes.xml
15
+ </Depends_On>
16
+
17
+ <Belief_State>
18
+ <Axiom id="AX_SVELTE_TEST_FILE_EXTENSION">
19
+ Component test files use the `.svelte.test.ts` extension — the Svelte-aware Vitest convention. Plain `.test.ts` does NOT receive Svelte plugin processing; importing a `.svelte` component from such a file produces opaque compile or runtime errors. Naming is the contract that tells the toolchain «this file must go through the Svelte compiler».
20
+ </Axiom>
21
+
22
+ <Axiom id="AX_SVELTE_TEST_FLUSH_BEFORE_ASSERT">
23
+ After any state mutation (user event, prop change, direct state write, simulated time advance) the test MUST call `flushSync()` from `svelte` before asserting on the DOM. `flushSync` forces pending `$effect` callbacks and DOM updates to run synchronously; without it the assertion runs against an intermediate, often stale, DOM.
24
+
25
+ Async helpers like `userEvent` may flush implicitly in some scenarios — relying on that implicit flush is fragile. Explicit `flushSync()` after the mutation is the discipline.
26
+ </Axiom>
27
+
28
+ <Axiom id="AX_SVELTE_TEST_EFFECT_ROOT_OUTSIDE_COMPONENT">
29
+ Tests exercising `$effect` directly (not through a mounted component) MUST run inside `$effect.root(() => { ... })` and dispose of its returned cleanup. `$effect` outside a component context is illegal; `$effect.root` provides the disposal boundary that makes it legal AND that prevents effects from leaking into subsequent tests.
30
+
31
+ For component tests, `@testing-library/svelte` `render()` already establishes a component context — explicit `$effect.root` is needed only for direct rune testing in `.svelte.ts` modules.
32
+ </Axiom>
33
+
34
+ <Axiom id="AX_SVELTE_TEST_MOUNT_AND_CLEANUP">
35
+ Every component mount MUST be paired with cleanup. Either:
36
+ - rely on testing-library's auto-cleanup (when the Vitest config enables it), OR
37
+ - register `afterEach(() => cleanup())` explicitly.
38
+
39
+ Skipping cleanup leaves mounted components in the document between cases; subsequent queries return stale matches and inter-test isolation collapses.
40
+ </Axiom>
41
+
42
+ <Axiom id="AX_SVELTE_TEST_LIBRARY_FOR_RENDERING">
43
+ Component rendering and querying go through `@testing-library/svelte`: `render(Component, { props })` for mounting; `screen.getByRole` / `getByLabelText` / `getByText` for querying. Direct `document.querySelector` / `container.querySelector` is forbidden as the default — it bypasses the accessibility-aware query layer that protects the test from CSS-coupling.
44
+
45
+ Reserved exception: an element with no semantic role AND no test-id where a selector is the only way to reach it; in that case the selector is paired with a comment naming the missing semantic.
46
+ </Axiom>
47
+
48
+ <Axiom id="AX_SVELTE_TEST_ROLE_QUERIES_PREFERRED">
49
+ Within the testing-library query surface, prefer role-based queries (`getByRole`, `getByLabelText`, `getByPlaceholderText`) over text-only queries. Role queries express the user-perceived contract; text queries are fragile to copy changes that have no contract impact.
50
+ </Axiom>
51
+
52
+ <Axiom id="AX_SVELTE_TEST_JSDOM_ENVIRONMENT">
53
+ The test runner environment is `jsdom` (or the equivalent browser-like environment the project standardised on). Mixing `jsdom` with `node` between files in the same suite is forbidden — one environment per project. The Svelte plugin is registered with Vitest so `.svelte` imports compile correctly during tests.
54
+ </Axiom>
55
+
56
+ <Axiom id="AX_SVELTE_TEST_PREFER_STORY_TESTS_WHEN_AVAILABLE">
57
+ If the project has a working Storybook integration with a story-test addon, prefer authoring story-level tests over manual `render()` calls — stories already document props and behaviour, and the story-test addon reuses them as executable contracts. Manual `render()` tests are reserved for cases that have no natural story counterpart (e.g. pure `.svelte.ts` reactive modules, error boundaries hard to express as a story variant).
58
+ </Axiom>
59
+
60
+ <Axiom id="AX_SVELTE_TEST_NO_DIRECT_DOM_QUERY">
61
+ `container.querySelector('.some-class')` and `document.getElementById(...)` are forbidden as the default DOM query. They couple the test to CSS class names and DOM structure — neither of which is part of the component contract. The accessibility-aware testing-library queries are the contract surface.
62
+ </Axiom>
63
+
64
+ <Axiom id="AX_SVELTE_TEST_INHERITED_VITEST_RULES">
65
+ All Vitest discipline applies unchanged: single unified context per file, factory-over-hooks for non-lifecycle setup, file-size budget, no `vi.mock` without operator confirm, no auto snapshot updates, explicit imports from `vitest`. This directive only adds Svelte-specific overlays — it does NOT relax inherited rules.
66
+ </Axiom>
67
+ </Belief_State>
68
+
69
+ <Definitions>
70
+ <Definition id="DEF_SVELTE_TEST_FILE">
71
+ A file matching `*.svelte.test.ts` — processed by the Svelte plugin during Vitest's transform stage. Plain `.test.ts` is not a Svelte test file.
72
+ </Definition>
73
+ <Definition id="DEF_FLUSH_BOUNDARY">
74
+ The synchronous point after a state mutation at which `$effect` callbacks and DOM updates run. `flushSync()` from `svelte` forces this boundary explicitly. Assertions placed before the boundary observe stale state.
75
+ </Definition>
76
+ </Definitions>
77
+
78
+ <Code_Patterns>
79
+ <Pattern id="PT_SVELTE_TEST_RENDER_AND_ASSERT">
80
+ <Intent>Minimal render + role-based query + assertion. No state mutation, so no `flushSync` needed.</Intent>
81
+ <Snippet language="typescript">
82
+ ```typescript
83
+ // Counter.svelte.test.ts
84
+ import { afterEach, describe, expect, it } from 'vitest';
85
+ import { cleanup, render, screen } from '@testing-library/svelte';
86
+ import Counter from './Counter.svelte';
87
+
88
+ afterEach(() => cleanup());
89
+
90
+ describe('Counter', () => {
91
+ it('should render the initial count from props', () => {
92
+ render(Counter, { props: { initial: 5, label: 'Count' } });
93
+ expect(screen.getByRole('button')).toHaveTextContent('Count: 5');
94
+ });
95
+ });
96
+ ```
97
+ </Snippet>
98
+ <Why>`.svelte.test.ts` extension; explicit `cleanup` in `afterEach`; role-based query; no mutation so no flush boundary.</Why>
99
+ </Pattern>
100
+
101
+ <Pattern id="PT_SVELTE_TEST_USER_INTERACTION_WITH_FLUSH">
102
+ <Intent>User interaction triggers state mutation → `flushSync` → role-based assertion of the resulting DOM.</Intent>
103
+ <Snippet language="typescript">
104
+ ```typescript
105
+ import { afterEach, describe, expect, it } from 'vitest';
106
+ import { cleanup, render, screen } from '@testing-library/svelte';
107
+ import userEvent from '@testing-library/user-event';
108
+ import { flushSync } from 'svelte';
109
+ import Counter from './Counter.svelte';
110
+
111
+ afterEach(() => cleanup());
112
+
113
+ describe('Counter#increment', () => {
114
+ it('should increment on click and reflect the new count', async () => {
115
+ render(Counter, { props: { initial: 0, label: 'Count' } });
116
+ const button = screen.getByRole('button');
117
+
118
+ await userEvent.click(button);
119
+ flushSync();
120
+
121
+ expect(button).toHaveTextContent('Count: 1');
122
+ });
123
+ });
124
+ ```
125
+ </Snippet>
126
+ <Why>`userEvent.click` is the mutation; explicit `flushSync()` forces effect graph to settle before the assertion runs.</Why>
127
+ </Pattern>
128
+
129
+ <Pattern id="PT_SVELTE_TEST_EFFECT_ROOT_FOR_RUNES">
130
+ <Intent>Testing a `.svelte.ts` reactive module directly — outside any component — via `$effect.root`.</Intent>
131
+ <Snippet language="typescript">
132
+ ```typescript
133
+ // counter-store.svelte.test.ts
134
+ import { describe, expect, it } from 'vitest';
135
+ import { flushSync } from 'svelte';
136
+ import { createCounter } from './counter-store.svelte';
137
+
138
+ describe('createCounter', () => {
139
+ it('should publish derived doubled value reactively', () => {
140
+ const cleanup = $effect.root(() => {
141
+ const counter = createCounter(2);
142
+ let observed = 0;
143
+ $effect(() => { observed = counter.doubled; });
144
+ flushSync();
145
+ expect(observed).toBe(4);
146
+
147
+ counter.increment();
148
+ flushSync();
149
+ expect(observed).toBe(6);
150
+ });
151
+ cleanup();
152
+ });
153
+ });
154
+ ```
155
+ </Snippet>
156
+ <Why>`$effect.root` provides the disposal boundary required for `$effect` outside a component; `flushSync` between mutation and assertion; explicit `cleanup()` disposes the root.</Why>
157
+ </Pattern>
158
+ </Code_Patterns>
159
+
160
+ <Anti_Patterns>
161
+ <Anti_Pattern id="AP_SVELTE_TEST_PLAIN_TS_EXTENSION">
162
+ <Bad>File named `Counter.test.ts` imports `Counter.svelte`; Vitest fails with «Cannot find module» or compiles the component as plain TS and explodes at first runtime use.</Bad>
163
+ <Why_Bad>Plain `.test.ts` extension for a Svelte component test (`AX_SVELTE_TEST_FILE_EXTENSION`). The Svelte plugin's file-pattern rule does not match; the test file bypasses Svelte compilation entirely. The error is opaque because the failure happens during transform, not at a useful assertion point.</Why_Bad>
164
+ <Good>Rename to `Counter.svelte.test.ts`. No code change required; the toolchain now routes the file through the Svelte plugin.</Good>
165
+ </Anti_Pattern>
166
+
167
+ <Anti_Pattern id="AP_SVELTE_TEST_NO_FLUSH">
168
+ <Bad>`await userEvent.click(button); expect(button).toHaveTextContent('Count: 1');` — assertion immediately after the mutation, no `flushSync`.</Bad>
169
+ <Why_Bad>Mutation asserted before the effect graph settles (`AX_SVELTE_TEST_FLUSH_BEFORE_ASSERT`). Sometimes green (when the implicit microtask flush happened to run), sometimes red, never trustworthy. Order-dependent flakiness for the next agent to debug.</Why_Bad>
170
+ <Good>`await userEvent.click(button); flushSync(); expect(button).toHaveTextContent('Count: 1');` — explicit boundary makes the assertion deterministic.</Good>
171
+ </Anti_Pattern>
172
+
173
+ <Anti_Pattern id="AP_SVELTE_TEST_NO_EFFECT_ROOT">
174
+ <Bad>In a `.svelte.test.ts` for a `.svelte.ts` module: `const c = createCounter(); $effect(() => { observed = c.doubled; }); flushSync();` — `$effect` invoked outside any root.</Bad>
175
+ <Why_Bad>`$effect` without component context AND without `$effect.root` (`AX_SVELTE_TEST_EFFECT_ROOT_OUTSIDE_COMPONENT`). The runtime throws «effect_orphan» (or equivalent) the moment the effect tries to register. Even if it survives, there is no disposal — the effect leaks into the next test.</Why_Bad>
176
+ <Good>Wrap in `$effect.root`: `const cleanup = $effect.root(() => { ... $effect(...) ... }); flushSync(); cleanup();` — root provides the disposal boundary; explicit `cleanup()` runs after the assertion.</Good>
177
+ </Anti_Pattern>
178
+
179
+ <Anti_Pattern id="AP_SVELTE_TEST_NO_CLEANUP">
180
+ <Bad>Multiple `render(Component, ...)` calls across cases; no `afterEach(() => cleanup())`; testing-library auto-cleanup not enabled in config.</Bad>
181
+ <Why_Bad>Mount without paired cleanup (`AX_SVELTE_TEST_MOUNT_AND_CLEANUP`). DOM accumulates between cases; `getByRole` starts returning matches from a previous test's mount, producing «works alone, fails in suite» symptoms that are hard to attribute.</Why_Bad>
182
+ <Good>Either enable testing-library auto-cleanup in `vitest.config.ts`, or explicitly `afterEach(() => cleanup())` in the file.</Good>
183
+ </Anti_Pattern>
184
+
185
+ <Anti_Pattern id="AP_SVELTE_TEST_DIRECT_QUERYSELECTOR">
186
+ <Bad>`const button = container.querySelector('.submit-btn'); expect(button.textContent).toBe('Go');`</Bad>
187
+ <Why_Bad>Direct DOM query coupled to a CSS class (`AX_SVELTE_TEST_NO_DIRECT_DOM_QUERY`, `AX_SVELTE_TEST_ROLE_QUERIES_PREFERRED`). `.submit-btn` is implementation detail with no contract status. Refactor that renames the class turns the test red without any behavioural change.</Why_Bad>
188
+ <Good>`expect(screen.getByRole('button', { name: 'Go' })).toBeInTheDocument();` — role + accessible name, the contract surface a user perceives.</Good>
189
+ </Anti_Pattern>
190
+ </Anti_Patterns>
191
+
192
+ <Verification_Hooks>
193
+ <Hook id="HOOK_SVELTE_TEST_RUN">
194
+ <Purpose>Run Svelte component tests via Vitest in one-shot mode.</Purpose>
195
+ <Command>npx vitest run</Command>
196
+ <Expected>Exit 0; all `.svelte.test.ts` files pass.</Expected>
197
+ </Hook>
198
+ <Hook id="HOOK_SVELTE_TEST_EXTENSION_DISCIPLINE">
199
+ <Purpose>Detect Svelte component imports inside plain `.test.ts` files.</Purpose>
200
+ <Command>find . -name '*.test.ts' -not -name '*.svelte.test.ts' -not -path '*/node_modules/*' -print0 | xargs -0 grep -lE "from\s+['\"][^'\"]+\.svelte['\"]" || true</Command>
201
+ <Expected>Empty output. Matches must be renamed to `*.svelte.test.ts`.</Expected>
202
+ </Hook>
203
+ <Hook id="HOOK_SVELTE_TEST_HAS_FLUSH_AFTER_USEREVENT">
204
+ <Purpose>Smoke-grep for likely flush gaps — `userEvent` immediately followed by an assertion with no `flushSync`.</Purpose>
205
+ <Command>find . -name '*.svelte.test.ts' -not -path '*/node_modules/*' -print0 | xargs -0 grep -nE 'userEvent\.|fireEvent\.' || true</Command>
206
+ <Expected>Manual review: each match is followed within a few lines by `flushSync()` (or by an `await` on an async helper that documents its own flush).</Expected>
207
+ </Hook>
208
+ <Hook id="HOOK_SVELTE_TEST_NO_DIRECT_DOM_QUERIES">
209
+ <Purpose>Detect direct DOM queries in component tests.</Purpose>
210
+ <Command>find . -name '*.svelte.test.ts' -not -path '*/node_modules/*' -print0 | xargs -0 grep -nE '(container|document)\.(querySelector|getElementById)' || true</Command>
211
+ <Expected>Empty output. Matches must migrate to `screen.getByRole` / `getByLabelText` / `getByText`, or carry a comment naming the missing semantic that forced a selector fallback.</Expected>
212
+ </Hook>
213
+ <Hook id="HOOK_SVELTE_TEST_HAS_CLEANUP">
214
+ <Purpose>Every `.svelte.test.ts` either enables auto-cleanup in config or registers `afterEach(() => cleanup())`.</Purpose>
215
+ <Command>find . -name '*.svelte.test.ts' -not -path '*/node_modules/*' -print0 | xargs -0 grep -LE "cleanup\(\)|globals:\s*true.*cleanup" || true</Command>
216
+ <Expected>Empty output (every file has cleanup). Matches indicate files without cleanup wiring; reconcile with `vitest.config.ts` if auto-cleanup is enabled project-wide.</Expected>
217
+ </Hook>
218
+ </Verification_Hooks>
219
+
220
+ <Reward_Criteria>
221
+ ✅ Test files use the `.svelte.test.ts` extension; `.test.ts` is reserved for non-Svelte tests.
222
+ ✅ Components mount via `@testing-library/svelte` `render()`; cleanup paired (explicit `afterEach` or auto-cleanup).
223
+ ✅ State mutation followed by `flushSync()` before any DOM assertion.
224
+ ✅ `$effect` outside a component runs inside `$effect.root` with explicit disposal.
225
+ ✅ Role-based queries (`getByRole`, `getByLabelText`, `getByPlaceholderText`) are the default; text queries are secondary.
226
+ ✅ Story-level tests preferred when a Storybook integration exists and a natural story counterpart is available.
227
+ ✅ Inherited Vitest rules honoured: unified context per file, no `vi.mock` without operator confirm, no auto snapshot updates, file-size budget, explicit imports from `vitest`.
228
+
229
+ ❌ Component imports inside a plain `.test.ts` file.
230
+ ❌ Assertion immediately after a mutation with no `flushSync()`.
231
+ ❌ `$effect` used outside a component context without `$effect.root` and disposal.
232
+ ❌ Component mounted without paired cleanup.
233
+ ❌ `container.querySelector` / `document.getElementById` as the default DOM query.
234
+ ❌ Manual `render()` in a project that already maintains a story counterpart for the scenario.
235
+ ❌ Any inherited Vitest rule relaxed (mock without confirm, hidden snapshot update, oversized file, etc.).
236
+ </Reward_Criteria>
237
+ </SvelteTestingRules>