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,199 @@
1
+ <PlaywrightCli keywords="playwright, playwright-cli, e2e-exploration, ax-tree, trace-viewer, codegen, debug, headless, locator-picker, aria-snapshot, screenshot, self-verify" type="testing-rules" ver="2.0">
2
+ <Mission>
3
+ Canonical rules for exploring a running web application through Playwright CLI BEFORE codifying a committed e2e test. This directive gives every execution-agent perception (AX tree, screenshots, trace viewer) and interaction (role-based locators, codegen) so it can see the page, manipulate it, and confirm that the rendered structure matches intent.
4
+
5
+ **Base axiom:** the rendered DOM is the only ground truth for an e2e test contract. Writing a test from memory, from a design doc, or from a guess produces locators that pass type-check and fail at runtime. So the order is fixed: navigate → snapshot AX tree → interact → snapshot delta → only then codify. The CLI session is the source of evidence for every locator and every assertion in the committed test.
6
+
7
+ Tooling reference (canonical CLI surface):
8
+ - `page.goto(url)` / `page.ariaSnapshot()` — primary navigation and perception channel.
9
+ - `page.getByRole(...)` — primary interaction surface.
10
+ - `page.screenshot({ fullPage: true })` — secondary visual channel for layout-only concerns.
11
+ - `npx playwright test --trace=on` + `npx playwright show-trace trace.zip` — failure diagnosis with DOM snapshots and timeline.
12
+ - `npx playwright codegen [url]` — interaction recorder; output requires review before commit.
13
+ - `npx playwright test --update-snapshots` — baseline rewrite (gated; see `AX_CLI_SNAPSHOT_UPDATE_GATE`).
14
+
15
+ Companion (codification of observations into committed tests): `ai/directives/testing/playwright-e2e.xml`.
16
+ </Mission>
17
+
18
+ <Depends_On>
19
+ - ai/directives/coding/typescript-rules.xml
20
+ </Depends_On>
21
+
22
+ <Belief_State>
23
+ <Axiom id="AX_CLI_EXPLORE_BEFORE_AUTHOR">
24
+ Exploration MUST precede authoring. Agent first sees the page through `page.ariaSnapshot()`, then interacts through `page.getByRole(...)`, then captures the post-state. Only after this loop completes does codification into a committed test file begin.
25
+
26
+ A locator that has never been resolved against a running page is a guess; committing it bypasses the only ground truth the test has.
27
+ </Axiom>
28
+
29
+ <Axiom id="AX_CLI_AX_TREE_AS_PRIMARY_VISION">
30
+ `page.ariaSnapshot()` is the primary perceptual channel for an agent. It emits a YAML representation of the accessibility tree — the same structure that `getByRole()` queries and `toMatchAriaSnapshot()` asserts. So the AX tree is the lingua franca across explore → interact → assert.
31
+
32
+ Pixel-level vision (screenshots, visual diff) is a secondary channel reserved for layout-only concerns. Choosing it as the primary signal binds the test to rendering pipelines that vary across machines.
33
+ </Axiom>
34
+
35
+ <Axiom id="AX_CLI_HEADLESS_FOR_AGENT">
36
+ Every CLI exploration session for an agent runs headless. The `--headed` / `--ui` / `--debug` modes are human-only — they assume a sighted operator at the terminal. An agent that opens a headed window has no consumer for the visual output and burns the session waiting for user input that will never arrive.
37
+ </Axiom>
38
+
39
+ <Axiom id="AX_CLI_ROLE_LOCATORS_FROM_AX_TREE">
40
+ Every locator used during exploration is derived from the AX tree just observed (`getByRole`, `getByLabel`, `getByPlaceholder`, `getByText`, `getByTestId`). CSS classes, ID selectors, and XPath expressions are forbidden as the primary locator strategy — they bind the test to implementation details that have no contract status.
41
+ </Axiom>
42
+
43
+ <Axiom id="AX_CLI_DEV_SERVER_PRECONDITION">
44
+ Every CLI command depends on a running application. The agent confirms the dev server is reachable (HTTP 200 at the expected URL, or the project's known boot-complete signal) BEFORE issuing the first Playwright call. Skipping this turns the first `page.goto` failure into a confusing «Playwright is broken» investigation instead of a one-line «start the dev server» fix.
45
+ </Axiom>
46
+
47
+ <Axiom id="AX_CLI_EXPLORE_LOOP_HAS_FOUR_STEPS">
48
+ The exploration loop is fixed at four steps and runs to completion before any test file is touched:
49
+ 1. **Explore** — `page.goto(url)`; `page.ariaSnapshot()`; read structure.
50
+ 2. **Interact** — `page.getByRole(...).click()` / `.fill()` / `.press()`; re-capture `ariaSnapshot()`; observe delta.
51
+ 3. **Verify** — compare observed structure against expected intent; if mismatch, fix the component first, restart, re-explore.
52
+ 4. **Capture** — record the final AX snapshot and any required screenshots as the basis for the committed test.
53
+
54
+ Skipping a step (e.g. interacting without re-snapshotting) hides the contract drift the loop exists to surface.
55
+ </Axiom>
56
+
57
+ <Axiom id="AX_CLI_TRACE_FOR_FAILURE_DIAGNOSIS">
58
+ When a test fails, the primary diagnostic is `playwright test --trace=on` followed by inspecting the trace via `show-trace`. The trace contains DOM snapshots at each step, network requests, console logs, and a timeline — enough to attribute the failure to a real cause instead of guessing.
59
+
60
+ «Edit the test until it passes» without trace inspection is forbidden — it routinely mutes real regressions by relaxing the assertion.
61
+ </Axiom>
62
+
63
+ <Axiom id="AX_CLI_CODEGEN_IS_RECORDER_NOT_AUTHOR">
64
+ `playwright codegen` records interactions but its output is NOT directly committable. The generated locators are typically CSS / nth-child / XPath chains — fragile and implementation-coupled. The agent reviews codegen output and replaces every selector with a role-based equivalent derived from the AX tree before any line of it lands in a committed file.
65
+ </Axiom>
66
+
67
+ <Axiom id="AX_CLI_SNAPSHOT_UPDATE_GATE">
68
+ `npx playwright test --update-snapshots` (rewriting AX/visual baselines) is a gated action. Allowed without confirmation only for the very FIRST snapshot of a NEW test (no prior baseline existed). For any update to an existing baseline the agent MUST stop, present the old vs new snapshot to the operator, name the cause of the diff (intentional UI change vs unexpected regression), and wait for explicit confirmation.
69
+
70
+ Silent `--update-snapshots` on every failure is the single most direct path for an agent to fabricate a green test under e2e.
71
+ </Axiom>
72
+
73
+ <Axiom id="AX_CLI_TRANSITION_TO_AUTHORING">
74
+ Exploration is complete only when: AX snapshot of the target region captured; every interactive element located via `getByRole(...)`; observed structure matches intent. At that point the agent transitions to `playwright-e2e.xml` for codification. Committing a test while exploration is still mid-loop produces a test that asserts the wrong contract.
75
+ </Axiom>
76
+ </Belief_State>
77
+
78
+ <Definitions>
79
+ <Definition id="DEF_CLI_AX_SNAPSHOT">
80
+ Output of `locator.ariaSnapshot()` — YAML representation of the accessibility subtree rooted at `locator`. Default scope is partial (a region or named role), not full page.
81
+ </Definition>
82
+ <Definition id="DEF_CLI_TRACE">
83
+ Output of `playwright test --trace=on` — a `.zip` containing DOM snapshots at each test step, network entries, console logs, and a timeline. Inspected via `npx playwright show-trace trace.zip`.
84
+ </Definition>
85
+ </Definitions>
86
+
87
+ <Code_Patterns>
88
+ <Pattern id="PT_CLI_EXPLORE_LOOP">
89
+ <Intent>Canonical four-step exploration loop captured as a script before any test file is touched.</Intent>
90
+ <Snippet language="typescript">
91
+ ```typescript
92
+ // explore.session.ts — throwaway exploration script, NOT committed as a test.
93
+ import { chromium } from 'playwright';
94
+
95
+ const browser = await chromium.launch();
96
+ const context = await browser.newContext();
97
+ const page = await context.newPage();
98
+
99
+ // 1. Explore
100
+ await page.goto('http://localhost:5173/checkout');
101
+ console.log(await page.getByRole('region', { name: 'Checkout' }).ariaSnapshot());
102
+
103
+ // 2. Interact
104
+ await page.getByRole('textbox', { name: 'Email' }).fill('user@test.com');
105
+ await page.getByRole('button', { name: 'Place Order' }).click();
106
+
107
+ // 3. Verify — snapshot after interaction; compare delta against intent
108
+ console.log(await page.getByRole('region', { name: 'Checkout' }).ariaSnapshot());
109
+
110
+ // 4. Capture — final snapshot is the seed for the committed test's toMatchAriaSnapshot
111
+ await browser.close();
112
+ ```
113
+ </Snippet>
114
+ <Why>One concrete URL, role-based locators derived from the previous snapshot, two snapshots framing the interaction so the delta is observable. The script itself is not committed — it is the audit trail for the committed test's contract.</Why>
115
+ </Pattern>
116
+ </Code_Patterns>
117
+
118
+ <Anti_Patterns>
119
+ <Anti_Pattern id="AP_CLI_WRITE_TEST_WITHOUT_AX_TREE">
120
+ <Bad>Agent reads the design doc, writes `await page.locator('.submit-btn').click()` straight into a committed test file without ever running `page.ariaSnapshot()` against a live page.</Bad>
121
+ <Why_Bad>Locator never resolved against ground truth (`AX_CLI_EXPLORE_BEFORE_AUTHOR`). `.submit-btn` is a CSS class — implementation-coupled, with no contract status (`AX_CLI_ROLE_LOCATORS_FROM_AX_TREE`). First run fails or, worse, matches a different element with the same class and produces a misleading green.</Why_Bad>
122
+ <Good>Run the exploration loop, observe `- button "Place Order"` in the AX snapshot, then write `await page.getByRole('button', { name: 'Place Order' }).click()` in the committed test.</Good>
123
+ </Anti_Pattern>
124
+
125
+ <Anti_Pattern id="AP_CLI_CSS_XPATH_FROM_CODEGEN">
126
+ <Bad>Agent runs `playwright codegen`, copies `page.locator('#root > div:nth-child(3) > button.submit')` straight into the committed test.</Bad>
127
+ <Why_Bad>Codegen output committed without review (`AX_CLI_CODEGEN_IS_RECORDER_NOT_AUTHOR`). The structural path breaks on the first DOM reordering, and the CSS class is implementation-coupled. Codegen is a recorder, not an author.</Why_Bad>
128
+ <Good>Read the AX snapshot of the same region, replace the generated locator with the role-based equivalent (`getByRole('button', { name: 'Submit' })`) before any line of codegen output lands in the test.</Good>
129
+ </Anti_Pattern>
130
+
131
+ <Anti_Pattern id="AP_CLI_SKIP_TRACE_ON_FAILURE">
132
+ <Bad>Test fails red; agent edits the assertion (`toMatch` → `toContain` → eventual deletion of the assertion) until the test passes, never running `--trace=on`.</Bad>
133
+ <Why_Bad>Failure diagnosed by mutation of the test instead of inspection of the actual run (`AX_CLI_TRACE_FOR_FAILURE_DIAGNOSIS`). Real regressions get silenced by progressively weaker assertions; the trace would have shown what actually happened in 30 seconds.</Why_Bad>
134
+ <Good>`npx playwright test --trace=on path/to/failing.spec.ts`; `npx playwright show-trace test-results/.../trace.zip`; identify whether the failure is in the component (fix component) or in the test's contract (fix test, with the new contract documented).</Good>
135
+ </Anti_Pattern>
136
+
137
+ <Anti_Pattern id="AP_CLI_HEADED_FOR_AGENT">
138
+ <Bad>Agent's exploration script launches the browser via `chromium.launch({ headless: false })` or invokes `npx playwright test --headed --ui`.</Bad>
139
+ <Why_Bad>Visual UI modes targeted at a human operator (`AX_CLI_HEADLESS_FOR_AGENT`). Agent has no consumer for the rendered window; the run hangs waiting for human input or burns CPU drawing pixels nobody reads.</Why_Bad>
140
+ <Good>Default headless: `chromium.launch()` (no `headless: false`). Perception flows through `ariaSnapshot()`, screenshots written to disk for retrospective review, traces for failure diagnosis.</Good>
141
+ </Anti_Pattern>
142
+
143
+ <Anti_Pattern id="AP_CLI_AUTO_UPDATE_SNAPSHOTS">
144
+ <Bad>CI fails on an AX snapshot diff; agent's response is `npx playwright test --update-snapshots` followed by a commit of the regenerated baselines.</Bad>
145
+ <Why_Bad>Snapshot baseline rewritten silently (`AX_CLI_SNAPSHOT_UPDATE_GATE`). The diff might have been a real regression; auto-update turns regressions into «accepted contract changes» with no operator visibility. Classic agent-side green-fabrication path.</Why_Bad>
146
+ <Good>Inspect the diff in the test-results report or via `show-trace`; if intentional, present old vs new snapshot to the operator, get confirmation, then `--update-snapshots` on the specific file; if unintentional, fix the component.</Good>
147
+ </Anti_Pattern>
148
+ </Anti_Patterns>
149
+
150
+ <Workflow_Outline>
151
+ <Step id="WF_CLI_1_PREREQ">Confirm Playwright installed (`npx playwright --version`); if absent, `npm i -D @playwright/test &amp;&amp; npx playwright install --with-deps chromium`. Confirm dev server reachable at the expected URL.</Step>
152
+ <Step id="WF_CLI_2_EXPLORE">`page.goto(url)`; `page.ariaSnapshot()`; identify roles, accessible names, nesting.</Step>
153
+ <Step id="WF_CLI_3_INTERACT">`page.getByRole(...).click()` / `.fill()` / `.press()`; re-snapshot after each meaningful step; observe delta.</Step>
154
+ <Step id="WF_CLI_4_CAPTURE">Final AX snapshot of the target region; screenshots only when the test concerns visual layout.</Step>
155
+ <Step id="WF_CLI_5_TRANSITION">When exploration confirms structure matches intent, transition to `playwright-e2e.xml` for codification.</Step>
156
+ </Workflow_Outline>
157
+
158
+ <Verification_Hooks>
159
+ <Hook id="HOOK_CLI_PLAYWRIGHT_INSTALLED">
160
+ <Purpose>Playwright + Chromium are installed and reachable.</Purpose>
161
+ <Command>npx playwright --version &amp;&amp; npx playwright install --dry-run chromium</Command>
162
+ <Expected>Version string printed; Chromium reported as already installed (or installed by the command).</Expected>
163
+ </Hook>
164
+ <Hook id="HOOK_CLI_DEV_SERVER_REACHABLE">
165
+ <Purpose>Dev server is reachable at the expected URL before exploration.</Purpose>
166
+ <Command>curl -fsS -o /dev/null -w "%{http_code}\n" "${BASE_URL:-http://localhost:5173}"</Command>
167
+ <Expected>HTTP 200 (or the project's known boot-complete status). Non-2xx means dev server is not ready; start it before exploring.</Expected>
168
+ </Hook>
169
+ <Hook id="HOOK_CLI_NO_HEADED_IN_AGENT_SCRIPTS">
170
+ <Purpose>No agent-committed script forces headed mode or `--ui`.</Purpose>
171
+ <Command>find . \( -name '*.ts' -o -name '*.js' \) -not -path '*/node_modules/*' -print0 | xargs -0 grep -nE 'headless\s*:\s*false|--headed|--ui|--debug' || true</Command>
172
+ <Expected>Empty output. Matches must either be human-only debugging scripts (excluded from the agent's workflow) or removed.</Expected>
173
+ </Hook>
174
+ <Hook id="HOOK_CLI_NO_AUTO_UPDATE_SNAPSHOTS">
175
+ <Purpose>Detect that the agent did not run `--update-snapshots` silently against an existing baseline.</Purpose>
176
+ <Command>git log -1 --name-only --pretty=format: | grep -E '\.snap$|snapshots/' || true</Command>
177
+ <Expected>If snapshot files appear in the last commit, the commit message MUST reference operator confirmation; uncomfirmed updates are a violation.</Expected>
178
+ </Hook>
179
+ </Verification_Hooks>
180
+
181
+ <Reward_Criteria>
182
+ ✅ Exploration loop completed (explore → interact → verify → capture) before any test is authored.
183
+ ✅ AX tree is the primary perceptual channel; screenshots reserved for visual-layout concerns.
184
+ ✅ Locators come from the just-observed AX tree; role-based queries only.
185
+ ✅ Headless for every agent-driven session; `--headed` / `--ui` / `--debug` reserved for humans.
186
+ ✅ Dev server reachability confirmed before the first `page.goto`.
187
+ ✅ Failures diagnosed via `--trace=on` + `show-trace`, not by mutating the assertion until green.
188
+ ✅ Codegen output reviewed and rewritten to role-based locators before commit.
189
+ ✅ Snapshot baseline updates pass operator confirm; first-baseline writes are the only ungated case.
190
+
191
+ ❌ Test authored without ever running `page.ariaSnapshot()` against a live page.
192
+ ❌ CSS / ID / XPath selectors used as primary locators.
193
+ ❌ Codegen output committed verbatim.
194
+ ❌ Test failure debugged by weakening or deleting assertions instead of inspecting the trace.
195
+ ❌ Agent-driven session running in `--headed`, `--ui`, or `--debug` mode.
196
+ ❌ `npx playwright test --update-snapshots` against an existing baseline without operator confirmation.
197
+ ❌ Committing a test while exploration is still mid-loop.
198
+ </Reward_Criteria>
199
+ </PlaywrightCli>
@@ -0,0 +1,292 @@
1
+ <PlaywrightE2ERules keywords="playwright, e2e, aria-snapshot, role-locators, page-objects, fixture, storage-state, network-mock, route, visual-regression, self-verify" type="testing-rules" ver="2.0">
2
+ <Mission>
3
+ Canonical rules for authoring Playwright E2E tests. Every execution-agent MUST perceive the page through `page.ariaSnapshot()`, locate elements via `getByRole()` only, and codify the observed contract into committed test files backed by fixture-based Page Objects.
4
+
5
+ **Base axiom:** an e2e test asserts a USER-FACING contract — what a screen-reader-equivalent observer sees and what a role-driven interaction does. Anything in the test that ties to CSS classes, DOM structure, or pixel coordinates is contract leakage and will break on the first refactor that does not affect the contract. So locators come from accessible roles, structural assertions come from `toMatchAriaSnapshot`, and visual regression is reserved for explicitly visual concerns.
6
+
7
+ Scope: codification — turning exploration observations into committed test files. Companion (exploration before authoring): `ai/directives/testing/playwright-cli.xml`.
8
+ </Mission>
9
+
10
+ <Depends_On>
11
+ - ai/directives/coding/typescript-rules.xml
12
+ - ai/directives/testing/playwright-cli.xml
13
+ </Depends_On>
14
+
15
+ <Belief_State>
16
+ <Axiom id="AX_E2E_AX_TREE_AS_CONTRACT">
17
+ The accessibility-tree snapshot (`ariaSnapshot()` + `toMatchAriaSnapshot()`) IS the structural contract. It encodes roles, accessible names, and hierarchy — the same surface a screen reader perceives. Textual/structural assertions on the DOM (e.g. `toContainText`) are allowed where AX granularity is insufficient (specific dynamic copy), but they supplement the AX snapshot, not replace it.
18
+ </Axiom>
19
+
20
+ <Axiom id="AX_E2E_ROLE_LOCATORS_ONLY">
21
+ Locator vocabulary is fixed: `getByRole`, `getByLabel`, `getByPlaceholder`, `getByText`, `getByTestId`. CSS selectors (`.class`, `#id`), XPath, and `nth-child` chains are forbidden as primary locators — they bind the test to implementation details with no contract status. `getByTestId` is a last-resort fallback for elements with no semantic role, and it is reserved for stable test IDs the component team owns.
22
+ </Axiom>
23
+
24
+ <Axiom id="AX_E2E_FIXTURE_BASED_POM">
25
+ Page Objects extend Playwright's `test.extend` fixtures — they are NOT standalone classes the test instantiates by hand. Fixture lifecycle (setup per test, teardown after) is the framework's job; bypassing it by `new SomePage(page)` reintroduces the cleanup problem the fixtures solve.
26
+
27
+ One fixture file per business domain (e.g. `auth.fixture.ts`, `checkout.fixture.ts`); unrelated domains do NOT merge into one fixture file.
28
+ </Axiom>
29
+
30
+ <Axiom id="AX_E2E_STRUCTURE_AX_FIRST">
31
+ Test structure is fixed:
32
+ 1. Navigate (`page.goto`).
33
+ 2. Capture / assert structure via `toMatchAriaSnapshot` on a scoped region.
34
+ 3. Interact via `getByRole(...)`.
35
+ 4. Assert the delta via another `toMatchAriaSnapshot` (or focused role-based assertion).
36
+
37
+ Skipping the first AX assertion turns the test into «click + hope»; without an initial baseline the interaction's delta has nothing to be a delta from.
38
+ </Axiom>
39
+
40
+ <Axiom id="AX_E2E_SNAPSHOT_PARTIAL_BY_DEFAULT">
41
+ AX snapshots are scoped to a NAMED region by default (`page.getByRole('region', { name: '...' }).ariaSnapshot()`). Full-page snapshots are reserved for tests whose contract IS the full page (e.g. a landing-page structure test). Defaulting to full-page snapshots produces brittle baselines that explode on every unrelated nav/sidebar change.
42
+ </Axiom>
43
+
44
+ <Axiom id="AX_E2E_AUTH_VIA_STORAGE_STATE">
45
+ Authentication is handled exclusively via `storageState`: a setup project runs the login flow once, writes `storageState.json`, and dependent projects reuse it. Inline login inside every test is forbidden — it slows the suite, couples every test to the login UI, and turns a login regression into a cascading red across the entire suite.
46
+ </Axiom>
47
+
48
+ <Axiom id="AX_E2E_NETWORK_MOCK_AT_ROUTE">
49
+ External API calls are mocked via `page.route()` / `context.route()` at the network boundary. Mocking at the component level or hand-patching `window.fetch` is forbidden — it bypasses the request flow the production code actually exercises and routinely misses headers, CORS, or retries.
50
+
51
+ If the project standardises on a network-mocking harness (MSW, in-house helper), tests reuse it consistently rather than introducing a parallel mocking path per test.
52
+ </Axiom>
53
+
54
+ <Axiom id="AX_E2E_VISUAL_REGRESSION_GATED">
55
+ Visual regression (`toHaveScreenshot()`) is enabled ONLY when the task explicitly requires pixel-level verification. Default contract verification is structural (AX) + behavioural (interaction). Visual regression baselines drift across font rendering, OS chrome, and unrelated CSS, so they belong only on routes that genuinely care about pixels.
56
+ </Axiom>
57
+
58
+ <Axiom id="AX_E2E_FILE_LAYOUT">
59
+ Project-wide layout: tests under `e2e/tests/`, fixtures under `e2e/fixtures/`, auth setup under `e2e/auth/`, snapshot baselines under `e2e/__snapshots__/`. One subject per test file; one domain per fixture file. Mixing layouts forces every reader-agent to grep for the convention instead of trusting it.
60
+ </Axiom>
61
+
62
+ <Axiom id="AX_E2E_FILE_SIZE_BUDGET">
63
+ Soft target ≤200 lines per test file; hard ceiling 300 lines (code only). Approaching the budget triggers extraction of shared logic into fixtures or helpers; exceeding it triggers a split by scenario family. Past the ceiling, instruction-following degrades and the file becomes a maintenance liability.
64
+ </Axiom>
65
+
66
+ <Axiom id="AX_E2E_BROWSER_COVERAGE_PRAGMATIC">
67
+ Default browser coverage is Chromium. Firefox / WebKit projects are added ONLY when multi-browser support is an explicit ticket requirement. Running every test on every browser inflates CI time without proportional contract evidence; per-route multi-browser opt-in is the trade-off.
68
+ </Axiom>
69
+
70
+ <Axiom id="AX_E2E_HEADLESS_ALWAYS">
71
+ Test execution is headless. `--headed` is a human-only debugging mode and never appears in committed scripts or CI configuration.
72
+ </Axiom>
73
+
74
+ <Axiom id="AX_E2E_SELF_VERIFICATION_LOOP">
75
+ After authoring: `npx playwright test --project=chromium`. Observe output → fix failures (in component or test) → re-run. Loop continues until green. Submitting a red test without an EXPLICIT blocker note in the ticket is forbidden — silent red turns the suite into noise the next agent must reverse-engineer.
76
+ </Axiom>
77
+ </Belief_State>
78
+
79
+ <Definitions>
80
+ <Definition id="DEF_E2E_FIXTURE_POM">
81
+ A Page Object exposed as a Playwright fixture: `const test = base.extend&lt;{ checkout: CheckoutPage }&gt;({ checkout: async ({ page }, use) => { await use(new CheckoutPage(page)); } });`. Tests then declare `checkout` in their argument list and receive a fresh per-test instance.
82
+ </Definition>
83
+ <Definition id="DEF_E2E_AX_CONTRACT">
84
+ The YAML emitted by `ariaSnapshot()` IS the structural contract. Diffs against the committed baseline (`toMatchAriaSnapshot`) signal either a real regression or an intentional UI change requiring an operator-confirmed baseline update.
85
+ </Definition>
86
+ </Definitions>
87
+
88
+ <Code_Patterns>
89
+ <Pattern id="PT_E2E_AX_SNAPSHOT_BASELINE">
90
+ <Intent>Navigate to a route, assert the structural baseline against the AX snapshot of a named region.</Intent>
91
+ <Snippet language="typescript">
92
+ ```typescript
93
+ import { expect, test } from '@playwright/test';
94
+
95
+ test('should render checkout form', async ({ page }) => {
96
+ await page.goto('/checkout');
97
+ await expect(
98
+ page.getByRole('region', { name: 'Checkout' }),
99
+ ).toMatchAriaSnapshot(`
100
+ - heading "Checkout" [level=1]
101
+ - textbox "Email"
102
+ - button "Place Order"
103
+ `);
104
+ });
105
+ ```
106
+ </Snippet>
107
+ <Why>Scoped to the `Checkout` region — not the full page. AX literal expresses the contract in role/name terms only.</Why>
108
+ </Pattern>
109
+
110
+ <Pattern id="PT_E2E_INTERACTION_DELTA">
111
+ <Intent>Interact via role locator; assert the AX delta after the interaction.</Intent>
112
+ <Snippet language="typescript">
113
+ ```typescript
114
+ test('should show validation error on empty submit', async ({ page }) => {
115
+ await page.goto('/checkout');
116
+ await page.getByRole('button', { name: 'Place Order' }).click();
117
+ await expect(
118
+ page.getByRole('region', { name: 'Checkout' }),
119
+ ).toMatchAriaSnapshot(`
120
+ - textbox "Email" [invalid=true]
121
+ - text: "Email is required"
122
+ `);
123
+ });
124
+ ```
125
+ </Snippet>
126
+ <Why>Interaction via `getByRole`; delta asserted as a second AX snapshot of the same scoped region.</Why>
127
+ </Pattern>
128
+
129
+ <Pattern id="PT_E2E_FIXTURE_POM">
130
+ <Intent>Fixture-based Page Object — instantiated by the framework lifecycle, not by the test.</Intent>
131
+ <Snippet language="typescript">
132
+ ```typescript
133
+ // e2e/fixtures/checkout.fixture.ts
134
+ import { test as base, expect } from '@playwright/test';
135
+ import { CheckoutPage } from './checkout.page';
136
+
137
+ export const test = base.extend&lt;{ checkout: CheckoutPage }&gt;({
138
+ checkout: async ({ page }, use) => {
139
+ await use(new CheckoutPage(page));
140
+ },
141
+ });
142
+ export { expect };
143
+
144
+ // e2e/tests/checkout.spec.ts
145
+ import { expect, test } from '../fixtures/checkout.fixture';
146
+
147
+ test('happy path', async ({ checkout }) => {
148
+ await checkout.navigate();
149
+ await checkout.fillEmail('user@test.com');
150
+ await checkout.submit();
151
+ await expect(checkout.confirmation).toMatchAriaSnapshot(`
152
+ - heading "Order placed" [level=1]
153
+ `);
154
+ });
155
+ ```
156
+ </Snippet>
157
+ <Why>Test declares only `checkout`; the fixture handles construction per test. No `new CheckoutPage(...)` in the test body.</Why>
158
+ </Pattern>
159
+
160
+ <Pattern id="PT_E2E_AUTH_SETUP_PROJECT">
161
+ <Intent>Auth handled once via a setup project; dependent projects reuse `storageState`.</Intent>
162
+ <Snippet language="typescript">
163
+ ```typescript
164
+ // playwright.config.ts (excerpt)
165
+ export default defineConfig({
166
+ projects: [
167
+ { name: 'setup', testMatch: /auth\.setup\.ts$/ },
168
+ {
169
+ name: 'chromium',
170
+ use: { storageState: 'e2e/auth/user.json' },
171
+ dependencies: ['setup'],
172
+ },
173
+ ],
174
+ });
175
+ ```
176
+ </Snippet>
177
+ <Why>Login runs once; every chromium test starts already authenticated. No inline login per test.</Why>
178
+ </Pattern>
179
+
180
+ <Pattern id="PT_E2E_NETWORK_MOCK">
181
+ <Intent>Mock an external API at the network boundary; production code path is otherwise untouched.</Intent>
182
+ <Snippet language="typescript">
183
+ ```typescript
184
+ test('should show confirmation when order API succeeds', async ({ page }) => {
185
+ await page.route('**/api/orders', async (route) => {
186
+ await route.fulfill({
187
+ status: 200,
188
+ contentType: 'application/json',
189
+ body: JSON.stringify({ orderId: 'ord-1', status: 'confirmed' }),
190
+ });
191
+ });
192
+ await page.goto('/checkout');
193
+ await page.getByRole('button', { name: 'Place Order' }).click();
194
+ await expect(page.getByRole('status')).toContainText('Order ord-1');
195
+ });
196
+ ```
197
+ </Snippet>
198
+ <Why>`page.route` intercepts at the network layer; component code runs unchanged. Assertion via `getByRole('status')`.</Why>
199
+ </Pattern>
200
+ </Code_Patterns>
201
+
202
+ <Anti_Patterns>
203
+ <Anti_Pattern id="AP_E2E_CSS_LOCATOR">
204
+ <Bad>`await page.locator('.btn-primary.submit-action').click();` — CSS class chain as the primary locator.</Bad>
205
+ <Why_Bad>CSS selectors couple the test to implementation (`AX_E2E_ROLE_LOCATORS_ONLY`). Any class rename — even one driven by a refactor that does not change behaviour — turns the test red. The user-facing contract has no concept of `.btn-primary`.</Why_Bad>
206
+ <Good>`await page.getByRole('button', { name: 'Place Order' }).click();` — role + accessible name, mirroring how the user identifies the element.</Good>
207
+ </Anti_Pattern>
208
+
209
+ <Anti_Pattern id="AP_E2E_INLINE_LOGIN">
210
+ <Bad>Every test begins with `await page.goto('/login'); await page.getByLabel('Email').fill(...); await page.getByLabel('Password').fill(...); await page.getByRole('button', { name: 'Sign in' }).click();`.</Bad>
211
+ <Why_Bad>Inline login per test (`AX_E2E_AUTH_VIA_STORAGE_STATE`). One regression in the login UI cascades into every test going red; the suite spends most of its time logging in instead of exercising the contract being tested.</Why_Bad>
212
+ <Good>Extract the login flow into a setup project that writes `storageState.json`; configure the test project with `use: { storageState: 'e2e/auth/user.json' }, dependencies: ['setup']`.</Good>
213
+ </Anti_Pattern>
214
+
215
+ <Anti_Pattern id="AP_E2E_FULL_PAGE_SNAPSHOT">
216
+ <Bad>`await expect(page).toMatchAriaSnapshot(\`- banner ... - main ... - contentinfo ...\`);` — full-page snapshot for a test that only verifies the checkout region.</Bad>
217
+ <Why_Bad>Snapshot scope mismatched to test intent (`AX_E2E_SNAPSHOT_PARTIAL_BY_DEFAULT`). Any change to the unrelated banner / footer / sidebar produces a snapshot diff that has nothing to do with the test's contract. Maintenance cost balloons; signal-to-noise drops.</Why_Bad>
218
+ <Good>Scope to the region under test: `await expect(page.getByRole('region', { name: 'Checkout' })).toMatchAriaSnapshot(\`...\`);`.</Good>
219
+ </Anti_Pattern>
220
+
221
+ <Anti_Pattern id="AP_E2E_STANDALONE_POM">
222
+ <Bad>`class CheckoutPage { constructor(page) { this.page = page; } } ... test('...', async ({ page }) => { const checkout = new CheckoutPage(page); ... });`</Bad>
223
+ <Why_Bad>Page Object instantiated by the test instead of supplied by a fixture (`AX_E2E_FIXTURE_BASED_POM`). Reintroduces the manual setup/teardown problem fixtures solve; no per-test lifecycle isolation; the page object cannot expose its own fixture-managed state (intercepts, storage, helpers).</Why_Bad>
224
+ <Good>Define `test = base.extend({ checkout: async ({ page }, use) => use(new CheckoutPage(page)) })`; the test declares `checkout` as an argument and receives a fresh per-test instance.</Good>
225
+ </Anti_Pattern>
226
+
227
+ <Anti_Pattern id="AP_E2E_UNMOCKED_NETWORK">
228
+ <Bad>Test exercises `/checkout` against the real backend; flakiness is «accepted» because the backend is «usually up».</Bad>
229
+ <Why_Bad>External dependency not mocked (`AX_E2E_NETWORK_MOCK_AT_ROUTE`). The test depends on infrastructure state outside the contract under test; one downstream incident turns the suite red and erodes trust. Worse, it cannot exercise failure paths because the real backend will not produce them on demand.</Why_Bad>
230
+ <Good>`await page.route('**/api/orders', route => route.fulfill({ status: 200, body: JSON.stringify(fixture) }));` for the happy path; `route.fulfill({ status: 500 })` for the failure path.</Good>
231
+ </Anti_Pattern>
232
+ </Anti_Patterns>
233
+
234
+ <Workflow_Outline>
235
+ <Step id="WF_E2E_1_EXPLORE">Run the exploration loop in `playwright-cli.xml` to capture AX snapshots and confirmed locators against the running app.</Step>
236
+ <Step id="WF_E2E_2_CODIFY">Author the fixture file (if a Page Object is needed) and the test file: AX baseline → interaction via role locator → AX delta.</Step>
237
+ <Step id="WF_E2E_3_MOCK_AND_AUTH">Mock external APIs via `page.route()`; reuse the auth setup project rather than logging in inline.</Step>
238
+ <Step id="WF_E2E_4_SELF_VERIFY">`npx playwright test --project=chromium`; fix failures (component or test); re-run until green.</Step>
239
+ <Step id="WF_E2E_5_FINALIZE">Confirm file under budget; snapshots scoped; no CSS/XPath locators; no inline login; no committed `.only` / `.skip` without deferred-ownership reference.</Step>
240
+ </Workflow_Outline>
241
+
242
+ <Verification_Hooks>
243
+ <Hook id="HOOK_E2E_RUN_CHROMIUM">
244
+ <Purpose>Run the e2e suite on Chromium.</Purpose>
245
+ <Command>npx playwright test --project=chromium</Command>
246
+ <Expected>Exit 0; all tests pass.</Expected>
247
+ </Hook>
248
+ <Hook id="HOOK_E2E_NO_CSS_LOCATORS">
249
+ <Purpose>Smoke-grep for forbidden CSS / XPath locator forms in test files.</Purpose>
250
+ <Command>find e2e -name '*.spec.ts' -o -name '*.test.ts' 2>/dev/null | xargs grep -nE "page\.locator\(['\"]([.#]|\.\\.|//|xpath=)" || true</Command>
251
+ <Expected>Empty output. Matches must be rewritten as `getByRole` / `getByLabel` / `getByTestId` derived from the AX tree.</Expected>
252
+ </Hook>
253
+ <Hook id="HOOK_E2E_NO_HEADED">
254
+ <Purpose>No committed configuration runs Playwright in headed mode.</Purpose>
255
+ <Command>find . \( -name 'playwright.config.*' -o -name '*.spec.ts' -o -name '*.test.ts' \) -not -path '*/node_modules/*' -print0 | xargs -0 grep -nE 'headless\s*:\s*false|--headed' || true</Command>
256
+ <Expected>Empty output.</Expected>
257
+ </Hook>
258
+ <Hook id="HOOK_E2E_FILE_SIZE_BUDGET">
259
+ <Purpose>Test files stay under the 300-line hard ceiling (code only).</Purpose>
260
+ <Command>find e2e -name '*.spec.ts' -o -name '*.test.ts' 2>/dev/null | while read f; do lines=$(grep -cvE '^\s*(//|/\*|\*|$)' "$f"); [ "$lines" -gt 200 ] &amp;&amp; echo "$lines $f"; done | sort -n</Command>
261
+ <Expected>No file exceeds 300 code-lines. Files over 200 carry a tracked split task or explicit justification.</Expected>
262
+ </Hook>
263
+ <Hook id="HOOK_E2E_NO_ONLY_OR_SKIP">
264
+ <Purpose>No committed `.only` / `.skip` without a deferred-ownership reference.</Purpose>
265
+ <Command>find e2e -name '*.spec.ts' -o -name '*.test.ts' 2>/dev/null | xargs grep -nE '\b(test|describe)\.(only|skip|fixme)\b' || true</Command>
266
+ <Expected>Empty output, or each match accompanied by an inline `TASK-` reference.</Expected>
267
+ </Hook>
268
+ </Verification_Hooks>
269
+
270
+ <Reward_Criteria>
271
+ ✅ AX snapshot is the structural contract; `toMatchAriaSnapshot` on scoped regions before and after interaction.
272
+ ✅ Locators come from accessible roles, labels, placeholders, text, or stable test IDs — never CSS / XPath / nth-child.
273
+ ✅ Page Objects exposed as fixtures via `test.extend`; one fixture file per business domain.
274
+ ✅ Auth via `storageState` from a setup project; no inline login per test.
275
+ ✅ External APIs mocked at the network boundary via `page.route()`; project-wide harness reused consistently.
276
+ ✅ Visual regression (`toHaveScreenshot`) used only when the contract is genuinely visual.
277
+ ✅ Files live under the documented layout (`e2e/tests/`, `e2e/fixtures/`, `e2e/auth/`, `e2e/__snapshots__/`).
278
+ ✅ Test files under 200 code-lines (soft) / 300 (hard); past the budget → split by scenario family.
279
+ ✅ Headless execution everywhere; self-verification loop completes before handoff.
280
+
281
+ ❌ CSS classes, IDs, XPath, or nth-child as primary locators.
282
+ ❌ Inline login inside every test.
283
+ ❌ Full-page AX snapshots for tests that target a specific region.
284
+ ❌ Standalone Page Object instantiated by the test (`new SomePage(page)`).
285
+ ❌ External APIs left unmocked; component-level `fetch` patching.
286
+ ❌ Visual regression baselines for tests whose contract is structural.
287
+ ❌ Test file exceeds the 300-line hard ceiling.
288
+ ❌ Committed `test.only` / `test.skip` / `test.fixme` without deferred-ownership reference.
289
+ ❌ Snapshot baselines updated silently via `--update-snapshots`.
290
+ ❌ Red test handed off without an EXPLICIT blocker note.
291
+ </Reward_Criteria>
292
+ </PlaywrightE2ERules>