@agentic-qe/v3 3.0.0-alpha.6 → 3.0.0-alpha.8

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 (612) hide show
  1. package/assets/agents/v3/subagents/v3-qe-code-reviewer.md +339 -0
  2. package/assets/agents/v3/subagents/v3-qe-integration-reviewer.md +344 -0
  3. package/assets/agents/v3/subagents/v3-qe-performance-reviewer.md +351 -0
  4. package/assets/agents/v3/subagents/v3-qe-security-reviewer.md +374 -0
  5. package/assets/agents/v3/subagents/v3-qe-tdd-green.md +334 -0
  6. package/assets/agents/v3/subagents/v3-qe-tdd-red.md +329 -0
  7. package/assets/agents/v3/subagents/v3-qe-tdd-refactor.md +361 -0
  8. package/assets/agents/v3/v3-qe-accessibility-auditor.md +266 -0
  9. package/assets/agents/v3/v3-qe-bdd-generator.md +279 -0
  10. package/assets/agents/v3/v3-qe-chaos-engineer.md +265 -0
  11. package/assets/agents/v3/v3-qe-code-complexity.md +298 -0
  12. package/assets/agents/v3/v3-qe-code-intelligence.md +262 -0
  13. package/assets/agents/v3/v3-qe-contract-validator.md +267 -0
  14. package/assets/agents/v3/v3-qe-coverage-specialist.md +227 -0
  15. package/assets/agents/v3/v3-qe-defect-predictor.md +251 -0
  16. package/assets/agents/v3/v3-qe-dependency-mapper.md +277 -0
  17. package/assets/agents/v3/v3-qe-deployment-advisor.md +275 -0
  18. package/assets/agents/v3/v3-qe-flaky-hunter.md +248 -0
  19. package/assets/agents/v3/v3-qe-fleet-commander.md +293 -0
  20. package/assets/agents/v3/v3-qe-gap-detector.md +260 -0
  21. package/assets/agents/v3/v3-qe-graphql-tester.md +308 -0
  22. package/assets/agents/v3/v3-qe-impact-analyzer.md +299 -0
  23. package/assets/agents/v3/v3-qe-integration-tester.md +238 -0
  24. package/assets/agents/v3/v3-qe-kg-builder.md +273 -0
  25. package/assets/agents/v3/v3-qe-learning-coordinator.md +226 -0
  26. package/assets/agents/v3/v3-qe-load-tester.md +280 -0
  27. package/assets/agents/v3/v3-qe-metrics-optimizer.md +300 -0
  28. package/assets/agents/v3/v3-qe-mutation-tester.md +301 -0
  29. package/assets/agents/v3/v3-qe-parallel-executor.md +240 -0
  30. package/assets/agents/v3/v3-qe-pattern-learner.md +271 -0
  31. package/assets/agents/v3/v3-qe-performance-tester.md +262 -0
  32. package/assets/agents/v3/v3-qe-property-tester.md +247 -0
  33. package/assets/agents/v3/v3-qe-quality-gate.md +218 -0
  34. package/assets/agents/v3/v3-qe-queen-coordinator.md +214 -0
  35. package/assets/agents/v3/v3-qe-qx-partner.md +313 -0
  36. package/assets/agents/v3/v3-qe-regression-analyzer.md +322 -0
  37. package/assets/agents/v3/v3-qe-requirements-validator.md +360 -0
  38. package/assets/agents/v3/v3-qe-responsive-tester.md +311 -0
  39. package/assets/agents/v3/v3-qe-retry-handler.md +256 -0
  40. package/assets/agents/v3/v3-qe-risk-assessor.md +273 -0
  41. package/assets/agents/v3/v3-qe-root-cause-analyzer.md +286 -0
  42. package/assets/agents/v3/v3-qe-security-auditor.md +299 -0
  43. package/assets/agents/v3/v3-qe-security-scanner.md +235 -0
  44. package/assets/agents/v3/v3-qe-tdd-specialist.md +239 -0
  45. package/assets/agents/v3/v3-qe-test-architect.md +233 -0
  46. package/assets/agents/v3/v3-qe-transfer-specialist.md +295 -0
  47. package/assets/agents/v3/v3-qe-visual-tester.md +232 -0
  48. package/assets/skills/accessibility-testing/SKILL.md +216 -0
  49. package/assets/skills/agentdb-advanced/SKILL.md +550 -0
  50. package/assets/skills/agentdb-learning/SKILL.md +545 -0
  51. package/assets/skills/agentdb-memory-patterns/SKILL.md +339 -0
  52. package/assets/skills/agentdb-optimization/SKILL.md +509 -0
  53. package/assets/skills/agentdb-vector-search/SKILL.md +339 -0
  54. package/assets/skills/agentic-jujutsu/SKILL.md +645 -0
  55. package/assets/skills/agentic-quality-engineering/SKILL.md +335 -0
  56. package/assets/skills/api-testing-patterns/SKILL.md +294 -0
  57. package/assets/skills/aqe-v2-v3-migration/skill.md +322 -0
  58. package/assets/skills/brutal-honesty-review/README.md +218 -0
  59. package/assets/skills/brutal-honesty-review/SKILL.md +235 -0
  60. package/assets/skills/brutal-honesty-review/resources/assessment-rubrics.md +295 -0
  61. package/assets/skills/brutal-honesty-review/resources/review-template.md +102 -0
  62. package/assets/skills/brutal-honesty-review/scripts/assess-code.sh +179 -0
  63. package/assets/skills/brutal-honesty-review/scripts/assess-tests.sh +223 -0
  64. package/assets/skills/bug-reporting-excellence/SKILL.md +225 -0
  65. package/assets/skills/chaos-engineering-resilience/SKILL.md +158 -0
  66. package/assets/skills/cicd-pipeline-qe-orchestrator/README.md +304 -0
  67. package/assets/skills/cicd-pipeline-qe-orchestrator/SKILL.md +315 -0
  68. package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/microservice-pipeline.md +239 -0
  69. package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/mobile-pipeline.md +375 -0
  70. package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/monolith-pipeline.md +268 -0
  71. package/assets/skills/code-review-quality/SKILL.md +227 -0
  72. package/assets/skills/compatibility-testing/SKILL.md +205 -0
  73. package/assets/skills/compliance-testing/SKILL.md +225 -0
  74. package/assets/skills/consultancy-practices/SKILL.md +202 -0
  75. package/assets/skills/context-driven-testing/SKILL.md +196 -0
  76. package/assets/skills/contract-testing/SKILL.md +222 -0
  77. package/assets/skills/database-testing/SKILL.md +244 -0
  78. package/assets/skills/exploratory-testing-advanced/SKILL.md +201 -0
  79. package/assets/skills/flow-nexus-neural/SKILL.md +738 -0
  80. package/assets/skills/flow-nexus-platform/SKILL.md +1157 -0
  81. package/assets/skills/flow-nexus-swarm/SKILL.md +610 -0
  82. package/assets/skills/github-code-review/SKILL.md +1140 -0
  83. package/assets/skills/github-multi-repo/SKILL.md +874 -0
  84. package/assets/skills/github-project-management/SKILL.md +1277 -0
  85. package/assets/skills/github-release-management/SKILL.md +1081 -0
  86. package/assets/skills/github-workflow-automation/SKILL.md +1065 -0
  87. package/assets/skills/hive-mind-advanced/SKILL.md +712 -0
  88. package/assets/skills/holistic-testing-pact/SKILL.md +171 -0
  89. package/assets/skills/hooks-automation/SKILL.md +1201 -0
  90. package/assets/skills/localization-testing/SKILL.md +221 -0
  91. package/assets/skills/mobile-testing/SKILL.md +219 -0
  92. package/assets/skills/mutation-testing/SKILL.md +229 -0
  93. package/assets/skills/n8n-expression-testing/SKILL.md +434 -0
  94. package/assets/skills/n8n-integration-testing-patterns/SKILL.md +540 -0
  95. package/assets/skills/n8n-security-testing/SKILL.md +599 -0
  96. package/assets/skills/n8n-trigger-testing-strategies/SKILL.md +541 -0
  97. package/assets/skills/n8n-workflow-testing-fundamentals/SKILL.md +447 -0
  98. package/assets/skills/pair-programming/SKILL.md +1202 -0
  99. package/assets/skills/performance-analysis/SKILL.md +563 -0
  100. package/assets/skills/performance-testing/SKILL.md +310 -0
  101. package/assets/skills/quality-metrics/SKILL.md +225 -0
  102. package/assets/skills/reasoningbank-agentdb/SKILL.md +446 -0
  103. package/assets/skills/reasoningbank-intelligence/SKILL.md +201 -0
  104. package/assets/skills/refactoring-patterns/SKILL.md +205 -0
  105. package/assets/skills/regression-testing/SKILL.md +227 -0
  106. package/assets/skills/risk-based-testing/SKILL.md +206 -0
  107. package/assets/skills/security-testing/SKILL.md +306 -0
  108. package/assets/skills/sherlock-review/SKILL.md +250 -0
  109. package/assets/skills/shift-left-testing/SKILL.md +225 -0
  110. package/assets/skills/shift-right-testing/SKILL.md +227 -0
  111. package/assets/skills/six-thinking-hats/README.md +190 -0
  112. package/assets/skills/six-thinking-hats/SKILL.md +280 -0
  113. package/assets/skills/six-thinking-hats/resources/examples/api-testing-example.md +345 -0
  114. package/assets/skills/six-thinking-hats/resources/templates/solo-session-template.md +167 -0
  115. package/assets/skills/six-thinking-hats/resources/templates/team-session-template.md +336 -0
  116. package/assets/skills/skill-builder/SKILL.md +910 -0
  117. package/assets/skills/sparc-methodology/SKILL.md +1115 -0
  118. package/assets/skills/stream-chain/SKILL.md +563 -0
  119. package/assets/skills/swarm-advanced/SKILL.md +973 -0
  120. package/assets/skills/swarm-orchestration/SKILL.md +179 -0
  121. package/assets/skills/tdd-london-chicago/SKILL.md +244 -0
  122. package/assets/skills/technical-writing/SKILL.md +178 -0
  123. package/assets/skills/test-automation-strategy/SKILL.md +230 -0
  124. package/assets/skills/test-data-management/SKILL.md +270 -0
  125. package/assets/skills/test-design-techniques/SKILL.md +244 -0
  126. package/assets/skills/test-environment-management/SKILL.md +243 -0
  127. package/assets/skills/test-reporting-analytics/SKILL.md +214 -0
  128. package/assets/skills/testability-scoring/README.md +71 -0
  129. package/assets/skills/testability-scoring/SKILL.md +346 -0
  130. package/assets/skills/testability-scoring/resources/templates/config.template.js +84 -0
  131. package/assets/skills/testability-scoring/resources/templates/testability-scoring.spec.template.js +532 -0
  132. package/assets/skills/testability-scoring/scripts/generate-html-report.js +1007 -0
  133. package/assets/skills/testability-scoring/scripts/run-assessment.sh +70 -0
  134. package/assets/skills/v3-qe-chaos-resilience/SKILL.md +238 -0
  135. package/assets/skills/v3-qe-code-intelligence/SKILL.md +209 -0
  136. package/assets/skills/v3-qe-contract-testing/SKILL.md +218 -0
  137. package/assets/skills/v3-qe-coverage-analysis/SKILL.md +187 -0
  138. package/assets/skills/v3-qe-defect-intelligence/SKILL.md +205 -0
  139. package/assets/skills/v3-qe-learning-optimization/SKILL.md +238 -0
  140. package/assets/skills/v3-qe-quality-assessment/SKILL.md +213 -0
  141. package/assets/skills/v3-qe-requirements-validation/SKILL.md +248 -0
  142. package/assets/skills/v3-qe-test-execution/SKILL.md +182 -0
  143. package/assets/skills/v3-qe-test-generation/SKILL.md +141 -0
  144. package/assets/skills/v3-qe-visual-accessibility/SKILL.md +242 -0
  145. package/assets/skills/verification-quality/SKILL.md +649 -0
  146. package/assets/skills/visual-testing-advanced/SKILL.md +219 -0
  147. package/assets/skills/xp-practices/SKILL.md +229 -0
  148. package/dist/cli/bundle.js +23 -13
  149. package/dist/init/agents-installer.js +4 -4
  150. package/dist/init/agents-installer.js.map +1 -1
  151. package/dist/init/init-wizard.d.ts.map +1 -1
  152. package/dist/init/init-wizard.js +15 -5
  153. package/dist/init/init-wizard.js.map +1 -1
  154. package/dist/init/skills-installer.js +4 -4
  155. package/dist/init/skills-installer.js.map +1 -1
  156. package/package.json +7 -1
  157. package/docs/analysis/V3-INIT-REQUIREMENTS-ANALYSIS.md +0 -352
  158. package/implementation/README.md +0 -90
  159. package/implementation/adrs/ADR-030-coherence-gated-quality-gates.md +0 -312
  160. package/implementation/adrs/ADR-031-strange-loop-self-awareness.md +0 -484
  161. package/implementation/adrs/ADR-032-time-crystal-scheduling.md +0 -530
  162. package/implementation/adrs/ADR-033-early-exit-testing.md +0 -634
  163. package/implementation/adrs/ADR-034-neural-topology-optimizer.md +0 -589
  164. package/implementation/adrs/ADR-035-causal-discovery.md +0 -610
  165. package/implementation/adrs/ADR-036-result-persistence.md +0 -326
  166. package/implementation/adrs/ADR-037-v3-qe-agent-naming.md +0 -105
  167. package/implementation/adrs/ADR-038-v3-qe-memory-unification.md +0 -154
  168. package/implementation/adrs/ADR-039-v3-qe-mcp-optimization.md +0 -179
  169. package/implementation/adrs/ADR-040-v3-qe-agentic-flow-integration.md +0 -240
  170. package/implementation/adrs/ADR-041-v3-qe-cli-enhancement.md +0 -296
  171. package/implementation/adrs/ADR-042-v3-qe-token-tracking-integration.md +0 -517
  172. package/implementation/adrs/v3-adrs.md +0 -2783
  173. package/implementation/planning/AQE-V3-MASTER-PLAN.md +0 -815
  174. package/security-scan-report-2026-01-11.md +0 -410
  175. package/security-verification-report-2026-01-11.md +0 -278
  176. package/src/benchmarks/performance-benchmarks.ts +0 -646
  177. package/src/benchmarks/run-benchmarks.ts +0 -324
  178. package/src/causal-discovery/causal-graph.ts +0 -450
  179. package/src/causal-discovery/discovery-engine.ts +0 -438
  180. package/src/causal-discovery/index.ts +0 -117
  181. package/src/causal-discovery/types.ts +0 -456
  182. package/src/causal-discovery/weight-matrix.ts +0 -453
  183. package/src/cli/commands/qe-tools.ts +0 -634
  184. package/src/cli/index.ts +0 -1976
  185. package/src/compatibility/agent-mapper.ts +0 -291
  186. package/src/compatibility/cli-adapter.ts +0 -277
  187. package/src/compatibility/config-migrator.ts +0 -334
  188. package/src/compatibility/index.ts +0 -112
  189. package/src/compatibility/mcp-adapter.ts +0 -248
  190. package/src/compatibility/types.ts +0 -156
  191. package/src/coordination/claims/claim-repository.ts +0 -636
  192. package/src/coordination/claims/claim-service.ts +0 -675
  193. package/src/coordination/claims/handoff-manager.ts +0 -535
  194. package/src/coordination/claims/index.ts +0 -276
  195. package/src/coordination/claims/interfaces.ts +0 -687
  196. package/src/coordination/claims/work-stealing.ts +0 -436
  197. package/src/coordination/cross-domain-router.ts +0 -492
  198. package/src/coordination/index.ts +0 -127
  199. package/src/coordination/interfaces.ts +0 -691
  200. package/src/coordination/protocol-executor.ts +0 -760
  201. package/src/coordination/protocols/code-intelligence-index.ts +0 -855
  202. package/src/coordination/protocols/defect-investigation.ts +0 -1184
  203. package/src/coordination/protocols/index.ts +0 -11
  204. package/src/coordination/protocols/learning-consolidation.ts +0 -1181
  205. package/src/coordination/protocols/morning-sync.ts +0 -1055
  206. package/src/coordination/protocols/quality-gate.ts +0 -1566
  207. package/src/coordination/protocols/security-audit.ts +0 -1587
  208. package/src/coordination/queen-coordinator.ts +0 -1176
  209. package/src/coordination/result-saver.ts +0 -780
  210. package/src/coordination/task-executor.ts +0 -1146
  211. package/src/coordination/workflow-orchestrator.ts +0 -1917
  212. package/src/domains/chaos-resilience/coordinator.ts +0 -1032
  213. package/src/domains/chaos-resilience/index.ts +0 -143
  214. package/src/domains/chaos-resilience/interfaces.ts +0 -659
  215. package/src/domains/chaos-resilience/plugin.ts +0 -691
  216. package/src/domains/chaos-resilience/services/chaos-engineer.ts +0 -1097
  217. package/src/domains/chaos-resilience/services/index.ts +0 -19
  218. package/src/domains/chaos-resilience/services/load-tester.ts +0 -799
  219. package/src/domains/chaos-resilience/services/performance-profiler.ts +0 -792
  220. package/src/domains/code-intelligence/coordinator.ts +0 -631
  221. package/src/domains/code-intelligence/index.ts +0 -86
  222. package/src/domains/code-intelligence/interfaces.ts +0 -162
  223. package/src/domains/code-intelligence/plugin.ts +0 -451
  224. package/src/domains/code-intelligence/services/impact-analyzer.ts +0 -567
  225. package/src/domains/code-intelligence/services/index.ts +0 -26
  226. package/src/domains/code-intelligence/services/knowledge-graph.ts +0 -1067
  227. package/src/domains/code-intelligence/services/semantic-analyzer.ts +0 -901
  228. package/src/domains/contract-testing/coordinator.ts +0 -1038
  229. package/src/domains/contract-testing/index.ts +0 -122
  230. package/src/domains/contract-testing/interfaces.ts +0 -458
  231. package/src/domains/contract-testing/plugin.ts +0 -746
  232. package/src/domains/contract-testing/services/api-compatibility.ts +0 -748
  233. package/src/domains/contract-testing/services/contract-validator.ts +0 -1700
  234. package/src/domains/contract-testing/services/index.ts +0 -19
  235. package/src/domains/contract-testing/services/schema-validator.ts +0 -1102
  236. package/src/domains/coverage-analysis/coordinator.ts +0 -485
  237. package/src/domains/coverage-analysis/index.ts +0 -114
  238. package/src/domains/coverage-analysis/interfaces.ts +0 -142
  239. package/src/domains/coverage-analysis/plugin.ts +0 -172
  240. package/src/domains/coverage-analysis/services/coverage-analyzer.ts +0 -449
  241. package/src/domains/coverage-analysis/services/coverage-embedder.ts +0 -733
  242. package/src/domains/coverage-analysis/services/coverage-parser.ts +0 -753
  243. package/src/domains/coverage-analysis/services/gap-detector.ts +0 -592
  244. package/src/domains/coverage-analysis/services/hnsw-index.ts +0 -728
  245. package/src/domains/coverage-analysis/services/index.ts +0 -61
  246. package/src/domains/coverage-analysis/services/risk-scorer.ts +0 -540
  247. package/src/domains/coverage-analysis/services/sublinear-analyzer.ts +0 -747
  248. package/src/domains/defect-intelligence/coordinator.ts +0 -635
  249. package/src/domains/defect-intelligence/index.ts +0 -83
  250. package/src/domains/defect-intelligence/interfaces.ts +0 -152
  251. package/src/domains/defect-intelligence/plugin.ts +0 -483
  252. package/src/domains/defect-intelligence/services/causal-root-cause-analyzer.ts +0 -494
  253. package/src/domains/defect-intelligence/services/defect-predictor.ts +0 -852
  254. package/src/domains/defect-intelligence/services/index.ts +0 -37
  255. package/src/domains/defect-intelligence/services/pattern-learner.ts +0 -738
  256. package/src/domains/defect-intelligence/services/root-cause-analyzer.ts +0 -637
  257. package/src/domains/domain-interface.ts +0 -77
  258. package/src/domains/index.ts +0 -23
  259. package/src/domains/learning-optimization/coordinator.ts +0 -1215
  260. package/src/domains/learning-optimization/index.ts +0 -127
  261. package/src/domains/learning-optimization/interfaces.ts +0 -570
  262. package/src/domains/learning-optimization/plugin.ts +0 -851
  263. package/src/domains/learning-optimization/services/index.ts +0 -29
  264. package/src/domains/learning-optimization/services/learning-coordinator.ts +0 -972
  265. package/src/domains/learning-optimization/services/metrics-optimizer.ts +0 -915
  266. package/src/domains/learning-optimization/services/production-intel.ts +0 -971
  267. package/src/domains/learning-optimization/services/transfer-specialist.ts +0 -723
  268. package/src/domains/quality-assessment/coherence/gate-controller.ts +0 -549
  269. package/src/domains/quality-assessment/coherence/index.ts +0 -211
  270. package/src/domains/quality-assessment/coherence/lambda-calculator.ts +0 -384
  271. package/src/domains/quality-assessment/coherence/partition-detector.ts +0 -469
  272. package/src/domains/quality-assessment/coherence/types.ts +0 -384
  273. package/src/domains/quality-assessment/coordinator.ts +0 -605
  274. package/src/domains/quality-assessment/index.ts +0 -97
  275. package/src/domains/quality-assessment/interfaces.ts +0 -152
  276. package/src/domains/quality-assessment/plugin.ts +0 -496
  277. package/src/domains/quality-assessment/services/coherence-gate.ts +0 -358
  278. package/src/domains/quality-assessment/services/deployment-advisor.ts +0 -571
  279. package/src/domains/quality-assessment/services/index.ts +0 -34
  280. package/src/domains/quality-assessment/services/quality-analyzer.ts +0 -670
  281. package/src/domains/quality-assessment/services/quality-gate.ts +0 -384
  282. package/src/domains/requirements-validation/coordinator.ts +0 -812
  283. package/src/domains/requirements-validation/index.ts +0 -92
  284. package/src/domains/requirements-validation/interfaces.ts +0 -303
  285. package/src/domains/requirements-validation/plugin.ts +0 -576
  286. package/src/domains/requirements-validation/services/bdd-scenario-writer.ts +0 -676
  287. package/src/domains/requirements-validation/services/index.ts +0 -20
  288. package/src/domains/requirements-validation/services/requirements-validator.ts +0 -559
  289. package/src/domains/requirements-validation/services/testability-scorer.ts +0 -639
  290. package/src/domains/security-compliance/coordinator.ts +0 -757
  291. package/src/domains/security-compliance/index.ts +0 -120
  292. package/src/domains/security-compliance/interfaces.ts +0 -434
  293. package/src/domains/security-compliance/plugin.ts +0 -509
  294. package/src/domains/security-compliance/services/compliance-validator.ts +0 -1226
  295. package/src/domains/security-compliance/services/index.ts +0 -31
  296. package/src/domains/security-compliance/services/security-auditor.ts +0 -2227
  297. package/src/domains/security-compliance/services/security-scanner.ts +0 -2354
  298. package/src/domains/security-compliance/services/semgrep-integration.ts +0 -289
  299. package/src/domains/test-execution/coordinator.ts +0 -426
  300. package/src/domains/test-execution/index.ts +0 -76
  301. package/src/domains/test-execution/interfaces.ts +0 -119
  302. package/src/domains/test-execution/plugin.ts +0 -208
  303. package/src/domains/test-execution/services/flaky-detector.ts +0 -1240
  304. package/src/domains/test-execution/services/index.ts +0 -8
  305. package/src/domains/test-execution/services/retry-handler.ts +0 -820
  306. package/src/domains/test-execution/services/test-executor.ts +0 -885
  307. package/src/domains/test-generation/coordinator.ts +0 -656
  308. package/src/domains/test-generation/index.ts +0 -77
  309. package/src/domains/test-generation/interfaces.ts +0 -118
  310. package/src/domains/test-generation/plugin.ts +0 -397
  311. package/src/domains/test-generation/services/index.ts +0 -23
  312. package/src/domains/test-generation/services/pattern-matcher.ts +0 -1725
  313. package/src/domains/test-generation/services/test-generator.ts +0 -2750
  314. package/src/domains/visual-accessibility/coordinator.ts +0 -860
  315. package/src/domains/visual-accessibility/index.ts +0 -116
  316. package/src/domains/visual-accessibility/interfaces.ts +0 -435
  317. package/src/domains/visual-accessibility/plugin.ts +0 -568
  318. package/src/domains/visual-accessibility/services/accessibility-tester.ts +0 -982
  319. package/src/domains/visual-accessibility/services/axe-core-audit.ts +0 -630
  320. package/src/domains/visual-accessibility/services/index.ts +0 -28
  321. package/src/domains/visual-accessibility/services/responsive-tester.ts +0 -934
  322. package/src/domains/visual-accessibility/services/visual-tester.ts +0 -458
  323. package/src/early-exit/early-exit-controller.ts +0 -490
  324. package/src/early-exit/early-exit-decision.ts +0 -391
  325. package/src/early-exit/index.ts +0 -115
  326. package/src/early-exit/quality-signal.ts +0 -389
  327. package/src/early-exit/speculative-executor.ts +0 -505
  328. package/src/early-exit/types.ts +0 -407
  329. package/src/feedback/coverage-learner.ts +0 -456
  330. package/src/feedback/feedback-loop.ts +0 -426
  331. package/src/feedback/index.ts +0 -72
  332. package/src/feedback/pattern-promotion.ts +0 -373
  333. package/src/feedback/quality-score-calculator.ts +0 -334
  334. package/src/feedback/test-outcome-tracker.ts +0 -450
  335. package/src/feedback/types.ts +0 -497
  336. package/src/index.ts +0 -224
  337. package/src/init/agents-installer.ts +0 -536
  338. package/src/init/index.ts +0 -80
  339. package/src/init/init-wizard.ts +0 -1061
  340. package/src/init/project-analyzer.ts +0 -696
  341. package/src/init/self-configurator.ts +0 -488
  342. package/src/init/skills-installer.ts +0 -467
  343. package/src/init/types.ts +0 -432
  344. package/src/integrations/ruvector/ast-complexity.ts +0 -470
  345. package/src/integrations/ruvector/coverage-router.ts +0 -594
  346. package/src/integrations/ruvector/diff-risk-classifier.ts +0 -759
  347. package/src/integrations/ruvector/fallback.ts +0 -942
  348. package/src/integrations/ruvector/graph-boundaries.ts +0 -809
  349. package/src/integrations/ruvector/index.ts +0 -363
  350. package/src/integrations/ruvector/interfaces.ts +0 -609
  351. package/src/integrations/ruvector/q-learning-router.ts +0 -550
  352. package/src/kernel/agent-coordinator.ts +0 -165
  353. package/src/kernel/agentdb-backend.ts +0 -504
  354. package/src/kernel/event-bus.ts +0 -129
  355. package/src/kernel/hybrid-backend.ts +0 -538
  356. package/src/kernel/index.ts +0 -28
  357. package/src/kernel/interfaces.ts +0 -257
  358. package/src/kernel/kernel.ts +0 -285
  359. package/src/kernel/memory-backend.ts +0 -169
  360. package/src/kernel/memory-factory.ts +0 -293
  361. package/src/kernel/plugin-loader.ts +0 -179
  362. package/src/learning/index.ts +0 -219
  363. package/src/learning/pattern-store.ts +0 -990
  364. package/src/learning/qe-guidance.ts +0 -832
  365. package/src/learning/qe-hooks.ts +0 -644
  366. package/src/learning/qe-patterns.ts +0 -449
  367. package/src/learning/qe-reasoning-bank.ts +0 -951
  368. package/src/learning/real-embeddings.ts +0 -277
  369. package/src/learning/real-qe-reasoning-bank.ts +0 -833
  370. package/src/learning/sqlite-persistence.ts +0 -554
  371. package/src/mcp/entry.ts +0 -59
  372. package/src/mcp/handlers/agent-handlers.ts +0 -285
  373. package/src/mcp/handlers/core-handlers.ts +0 -317
  374. package/src/mcp/handlers/domain-handlers.ts +0 -1444
  375. package/src/mcp/handlers/index.ts +0 -57
  376. package/src/mcp/handlers/memory-handlers.ts +0 -338
  377. package/src/mcp/handlers/task-handlers.ts +0 -363
  378. package/src/mcp/index.ts +0 -30
  379. package/src/mcp/metrics/index.ts +0 -14
  380. package/src/mcp/metrics/metrics-collector.ts +0 -503
  381. package/src/mcp/protocol-server.ts +0 -752
  382. package/src/mcp/security/cve-prevention.ts +0 -742
  383. package/src/mcp/security/index.ts +0 -356
  384. package/src/mcp/security/oauth21-provider.ts +0 -821
  385. package/src/mcp/security/rate-limiter.ts +0 -615
  386. package/src/mcp/security/sampling-server.ts +0 -662
  387. package/src/mcp/security/schema-validator.ts +0 -855
  388. package/src/mcp/server.ts +0 -657
  389. package/src/mcp/tool-registry.ts +0 -391
  390. package/src/mcp/tools/base.ts +0 -399
  391. package/src/mcp/tools/chaos-resilience/inject.ts +0 -699
  392. package/src/mcp/tools/code-intelligence/analyze.ts +0 -745
  393. package/src/mcp/tools/contract-testing/validate.ts +0 -708
  394. package/src/mcp/tools/coverage-analysis/index.ts +0 -770
  395. package/src/mcp/tools/defect-intelligence/predict.ts +0 -466
  396. package/src/mcp/tools/index.ts +0 -214
  397. package/src/mcp/tools/learning-optimization/optimize.ts +0 -772
  398. package/src/mcp/tools/quality-assessment/evaluate.ts +0 -385
  399. package/src/mcp/tools/registry.ts +0 -248
  400. package/src/mcp/tools/requirements-validation/validate.ts +0 -394
  401. package/src/mcp/tools/security-compliance/scan.ts +0 -365
  402. package/src/mcp/tools/test-execution/execute.ts +0 -291
  403. package/src/mcp/tools/test-generation/generate.ts +0 -544
  404. package/src/mcp/tools/visual-accessibility/index.ts +0 -791
  405. package/src/mcp/transport/index.ts +0 -31
  406. package/src/mcp/transport/stdio.ts +0 -318
  407. package/src/mcp/types.ts +0 -543
  408. package/src/neural-optimizer/index.ts +0 -111
  409. package/src/neural-optimizer/replay-buffer.ts +0 -455
  410. package/src/neural-optimizer/swarm-topology.ts +0 -508
  411. package/src/neural-optimizer/topology-optimizer.ts +0 -828
  412. package/src/neural-optimizer/types.ts +0 -481
  413. package/src/neural-optimizer/value-network.ts +0 -351
  414. package/src/optimization/auto-tuner.ts +0 -817
  415. package/src/optimization/index.ts +0 -77
  416. package/src/optimization/metric-collectors.ts +0 -474
  417. package/src/optimization/qe-workers.ts +0 -704
  418. package/src/optimization/tuning-algorithm.ts +0 -401
  419. package/src/optimization/types.ts +0 -314
  420. package/src/routing/index.ts +0 -51
  421. package/src/routing/qe-agent-registry.ts +0 -963
  422. package/src/routing/qe-task-router.ts +0 -564
  423. package/src/routing/routing-feedback.ts +0 -365
  424. package/src/routing/types.ts +0 -406
  425. package/src/shared/embeddings/embedding-cache.ts +0 -157
  426. package/src/shared/embeddings/index.ts +0 -50
  427. package/src/shared/embeddings/nomic-embedder.ts +0 -404
  428. package/src/shared/embeddings/ollama-client.ts +0 -195
  429. package/src/shared/embeddings/types.ts +0 -147
  430. package/src/shared/entities/agent.ts +0 -141
  431. package/src/shared/entities/base-entity.ts +0 -79
  432. package/src/shared/entities/index.ts +0 -6
  433. package/src/shared/events/domain-events.ts +0 -259
  434. package/src/shared/events/index.ts +0 -5
  435. package/src/shared/git/git-analyzer.ts +0 -656
  436. package/src/shared/git/index.ts +0 -11
  437. package/src/shared/http/http-client.ts +0 -420
  438. package/src/shared/http/index.ts +0 -13
  439. package/src/shared/index.ts +0 -41
  440. package/src/shared/io/file-reader.ts +0 -525
  441. package/src/shared/io/index.ts +0 -25
  442. package/src/shared/llm/cache.ts +0 -473
  443. package/src/shared/llm/circuit-breaker.ts +0 -369
  444. package/src/shared/llm/cost-tracker.ts +0 -460
  445. package/src/shared/llm/index.ts +0 -140
  446. package/src/shared/llm/interfaces.ts +0 -629
  447. package/src/shared/llm/provider-manager.ts +0 -685
  448. package/src/shared/llm/providers/claude.ts +0 -524
  449. package/src/shared/llm/providers/index.ts +0 -8
  450. package/src/shared/llm/providers/ollama.ts +0 -575
  451. package/src/shared/llm/providers/openai.ts +0 -609
  452. package/src/shared/metrics/code-metrics.ts +0 -520
  453. package/src/shared/metrics/index.ts +0 -23
  454. package/src/shared/metrics/system-metrics.ts +0 -353
  455. package/src/shared/parsers/index.ts +0 -6
  456. package/src/shared/parsers/typescript-parser.ts +0 -841
  457. package/src/shared/security/compliance-patterns.ts +0 -666
  458. package/src/shared/security/index.ts +0 -30
  459. package/src/shared/security/osv-client.ts +0 -468
  460. package/src/shared/types/index.ts +0 -150
  461. package/src/shared/value-objects/index.ts +0 -273
  462. package/src/strange-loop/healing-controller.ts +0 -833
  463. package/src/strange-loop/index.ts +0 -104
  464. package/src/strange-loop/self-model.ts +0 -494
  465. package/src/strange-loop/strange-loop.ts +0 -446
  466. package/src/strange-loop/swarm-observer.ts +0 -448
  467. package/src/strange-loop/topology-analyzer.ts +0 -565
  468. package/src/strange-loop/types.ts +0 -640
  469. package/src/time-crystal/default-phases.ts +0 -520
  470. package/src/time-crystal/index.ts +0 -164
  471. package/src/time-crystal/oscillator.ts +0 -425
  472. package/src/time-crystal/phase-executor.ts +0 -521
  473. package/src/time-crystal/scheduler.ts +0 -1025
  474. package/src/time-crystal/test-runner.ts +0 -787
  475. package/src/time-crystal/types.ts +0 -421
  476. package/src/workers/base-worker.ts +0 -304
  477. package/src/workers/daemon.ts +0 -264
  478. package/src/workers/index.ts +0 -119
  479. package/src/workers/interfaces.ts +0 -393
  480. package/src/workers/worker-manager.ts +0 -424
  481. package/src/workers/workers/compliance-checker.ts +0 -445
  482. package/src/workers/workers/coverage-tracker.ts +0 -344
  483. package/src/workers/workers/defect-predictor.ts +0 -375
  484. package/src/workers/workers/flaky-detector.ts +0 -390
  485. package/src/workers/workers/index.ts +0 -17
  486. package/src/workers/workers/learning-consolidation.ts +0 -442
  487. package/src/workers/workers/performance-baseline.ts +0 -434
  488. package/src/workers/workers/quality-gate.ts +0 -419
  489. package/src/workers/workers/regression-monitor.ts +0 -357
  490. package/src/workers/workers/security-scan.ts +0 -349
  491. package/src/workers/workers/test-health.ts +0 -359
  492. package/tests/integration/code-intelligence/knowledge-graph-real.test.ts +0 -540
  493. package/tests/integration/coordination/cross-domain-router.test.ts +0 -403
  494. package/tests/integration/coordination/protocol-executor.test.ts +0 -454
  495. package/tests/integration/coordination/workflow-orchestrator.test.ts +0 -418
  496. package/tests/integration/feedback/feedback-loop-integration.test.ts +0 -560
  497. package/tests/integration/migration/v2-to-v3-migration.test.ts +0 -471
  498. package/tests/integration/parsers/typescript-parser.test.ts +0 -463
  499. package/tests/integration/security/vulnerability-detection.test.ts +0 -628
  500. package/tests/integration/test-execution/coordinator.test.ts +0 -410
  501. package/tests/integration/test-generation/coordinator.test.ts +0 -361
  502. package/tests/mocks/index.ts +0 -228
  503. package/tests/time-crystal/default-phases.test.ts +0 -476
  504. package/tests/time-crystal/oscillator.test.ts +0 -541
  505. package/tests/time-crystal/phase-executor.test.ts +0 -653
  506. package/tests/time-crystal/scheduler.test.ts +0 -626
  507. package/tests/time-crystal/test-runner.test.ts +0 -594
  508. package/tests/unit/causal-discovery/causal-graph.test.ts +0 -504
  509. package/tests/unit/causal-discovery/causal-root-cause-analyzer.test.ts +0 -347
  510. package/tests/unit/causal-discovery/discovery-engine.test.ts +0 -435
  511. package/tests/unit/causal-discovery/weight-matrix.test.ts +0 -328
  512. package/tests/unit/cli/cli.test.ts +0 -341
  513. package/tests/unit/cli/commands.test.ts +0 -414
  514. package/tests/unit/cli/init-command.test.ts +0 -274
  515. package/tests/unit/cli/migrate-command.test.ts +0 -396
  516. package/tests/unit/coordination/claims/claim-service.test.ts +0 -949
  517. package/tests/unit/coordination/claims/handoff-manager.test.ts +0 -773
  518. package/tests/unit/coordination/claims/work-stealing.test.ts +0 -492
  519. package/tests/unit/coordination/queen-coordinator.test.ts +0 -966
  520. package/tests/unit/coordination/result-saver.test.ts +0 -653
  521. package/tests/unit/coordination/task-executor.test.ts +0 -810
  522. package/tests/unit/domains/chaos-resilience/chaos-engineer.test.ts +0 -484
  523. package/tests/unit/domains/chaos-resilience/load-tester.test.ts +0 -559
  524. package/tests/unit/domains/chaos-resilience/performance-profiler.test.ts +0 -490
  525. package/tests/unit/domains/code-intelligence/impact-analyzer.test.ts +0 -560
  526. package/tests/unit/domains/code-intelligence/knowledge-graph.test.ts +0 -460
  527. package/tests/unit/domains/code-intelligence/semantic-analyzer.test.ts +0 -584
  528. package/tests/unit/domains/contract-testing/api-compatibility.test.ts +0 -483
  529. package/tests/unit/domains/contract-testing/contract-validator.test.ts +0 -370
  530. package/tests/unit/domains/contract-testing/schema-validator.test.ts +0 -610
  531. package/tests/unit/domains/coverage-analysis/coverage-embedder.test.ts +0 -298
  532. package/tests/unit/domains/coverage-analysis/hnsw-index.test.ts +0 -292
  533. package/tests/unit/domains/coverage-analysis/sublinear-analyzer.test.ts +0 -506
  534. package/tests/unit/domains/defect-intelligence/defect-predictor.test.ts +0 -370
  535. package/tests/unit/domains/defect-intelligence/pattern-learner.test.ts +0 -546
  536. package/tests/unit/domains/defect-intelligence/root-cause-analyzer.test.ts +0 -534
  537. package/tests/unit/domains/learning-optimization/learning-coordinator.test.ts +0 -541
  538. package/tests/unit/domains/learning-optimization/metrics-optimizer.test.ts +0 -552
  539. package/tests/unit/domains/learning-optimization/production-intel.test.ts +0 -589
  540. package/tests/unit/domains/learning-optimization/transfer-specialist.test.ts +0 -453
  541. package/tests/unit/domains/quality-assessment/coherence-gate.test.ts +0 -1006
  542. package/tests/unit/domains/quality-assessment/deployment-advisor.test.ts +0 -515
  543. package/tests/unit/domains/quality-assessment/quality-analyzer.test.ts +0 -401
  544. package/tests/unit/domains/quality-assessment/quality-gate.test.ts +0 -324
  545. package/tests/unit/domains/requirements-validation/bdd-scenario-writer.test.ts +0 -479
  546. package/tests/unit/domains/requirements-validation/requirements-validator.test.ts +0 -452
  547. package/tests/unit/domains/requirements-validation/testability-scorer.test.ts +0 -505
  548. package/tests/unit/domains/security-compliance/compliance-validator.test.ts +0 -500
  549. package/tests/unit/domains/security-compliance/security-auditor.test.ts +0 -498
  550. package/tests/unit/domains/security-compliance/security-scanner.test.ts +0 -412
  551. package/tests/unit/domains/visual-accessibility/accessibility-tester.test.ts +0 -432
  552. package/tests/unit/domains/visual-accessibility/responsive-tester.test.ts +0 -506
  553. package/tests/unit/domains/visual-accessibility/visual-tester.test.ts +0 -412
  554. package/tests/unit/early-exit/early-exit-controller.test.ts +0 -548
  555. package/tests/unit/early-exit/early-exit-decision.test.ts +0 -617
  556. package/tests/unit/early-exit/index.test.ts +0 -254
  557. package/tests/unit/early-exit/quality-signal.test.ts +0 -589
  558. package/tests/unit/early-exit/speculative-executor.test.ts +0 -453
  559. package/tests/unit/feedback/coverage-learner.test.ts +0 -288
  560. package/tests/unit/feedback/feedback-loop.test.ts +0 -458
  561. package/tests/unit/feedback/pattern-promotion.test.ts +0 -390
  562. package/tests/unit/feedback/quality-score-calculator.test.ts +0 -364
  563. package/tests/unit/feedback/test-outcome-tracker.test.ts +0 -243
  564. package/tests/unit/init/init-wizard.test.ts +0 -881
  565. package/tests/unit/init/project-analyzer.test.ts +0 -807
  566. package/tests/unit/init/self-configurator.test.ts +0 -493
  567. package/tests/unit/integrations/ruvector/ast-complexity.test.ts +0 -240
  568. package/tests/unit/integrations/ruvector/coverage-router.test.ts +0 -366
  569. package/tests/unit/integrations/ruvector/diff-risk-classifier.test.ts +0 -340
  570. package/tests/unit/integrations/ruvector/graph-boundaries.test.ts +0 -355
  571. package/tests/unit/integrations/ruvector/q-learning-router.test.ts +0 -314
  572. package/tests/unit/kernel/agent-coordinator.test.ts +0 -220
  573. package/tests/unit/kernel/event-bus.test.ts +0 -197
  574. package/tests/unit/learning/qe-reasoning-bank.test.ts +0 -666
  575. package/tests/unit/learning/real-qe-reasoning-bank.benchmark.test.ts +0 -415
  576. package/tests/unit/mcp/mcp-server.test.ts +0 -544
  577. package/tests/unit/mcp/metrics/metrics-collector.test.ts +0 -340
  578. package/tests/unit/mcp/security/cve-prevention.test.ts +0 -512
  579. package/tests/unit/mcp/security/oauth21-provider.test.ts +0 -624
  580. package/tests/unit/mcp/security/rate-limiter.test.ts +0 -410
  581. package/tests/unit/mcp/security/sampling-server.test.ts +0 -420
  582. package/tests/unit/mcp/security/schema-validator.test.ts +0 -494
  583. package/tests/unit/mcp/tools/base.test.ts +0 -336
  584. package/tests/unit/mcp/tools/domain-tools.test.ts +0 -759
  585. package/tests/unit/mcp/tools/registry.test.ts +0 -240
  586. package/tests/unit/neural-optimizer/replay-buffer.test.ts +0 -403
  587. package/tests/unit/neural-optimizer/swarm-topology.test.ts +0 -473
  588. package/tests/unit/neural-optimizer/topology-optimizer.test.ts +0 -595
  589. package/tests/unit/neural-optimizer/value-network.test.ts +0 -343
  590. package/tests/unit/optimization/auto-tuner.test.ts +0 -506
  591. package/tests/unit/optimization/metric-collectors.test.ts +0 -352
  592. package/tests/unit/optimization/qe-workers.test.ts +0 -407
  593. package/tests/unit/optimization/tuning-algorithm.test.ts +0 -467
  594. package/tests/unit/routing/qe-agent-registry.test.ts +0 -229
  595. package/tests/unit/routing/qe-task-router.test.ts +0 -390
  596. package/tests/unit/routing/routing-feedback.test.ts +0 -339
  597. package/tests/unit/shared/embeddings/nomic-embedder.test.ts +0 -419
  598. package/tests/unit/shared/http/http-client.test.ts +0 -719
  599. package/tests/unit/shared/io/file-reader.test.ts +0 -511
  600. package/tests/unit/shared/llm/cache.test.ts +0 -391
  601. package/tests/unit/shared/llm/circuit-breaker.test.ts +0 -293
  602. package/tests/unit/shared/llm/cost-tracker.test.ts +0 -431
  603. package/tests/unit/shared/llm/provider-manager.test.ts +0 -550
  604. package/tests/unit/shared/llm/providers.test.ts +0 -532
  605. package/tests/unit/shared/parsers/typescript-parser.test.ts +0 -693
  606. package/tests/unit/shared/value-objects.test.ts +0 -184
  607. package/tests/unit/strange-loop/strange-loop.test.ts +0 -1170
  608. package/tests/unit/workers/base-worker.test.ts +0 -341
  609. package/tests/unit/workers/daemon.test.ts +0 -291
  610. package/tests/unit/workers/worker-manager.test.ts +0 -284
  611. package/tsconfig.json +0 -32
  612. package/vitest.config.ts +0 -27
@@ -1,1725 +0,0 @@
1
- /**
2
- * Agentic QE v3 - Pattern Matching Service
3
- * Implements IPatternMatchingService for learning and applying test patterns
4
- *
5
- * Uses TypeScript Compiler API for real AST parsing and pattern extraction
6
- * Uses NomicEmbedder for semantic embeddings when available
7
- */
8
-
9
- import { v4 as uuidv4 } from 'uuid';
10
- import * as ts from 'typescript';
11
- import * as fs from 'fs';
12
- import * as path from 'path';
13
- import { Result, ok, err } from '../../../shared/types';
14
- import { MemoryBackend, VectorSearchResult } from '../../../kernel/interfaces';
15
- import { Pattern, LearnPatternsRequest, LearnedPatterns } from '../interfaces';
16
- import { NomicEmbedder, IEmbeddingProvider, EMBEDDING_CONFIG } from '../../../shared/embeddings';
17
-
18
- /**
19
- * Interface for the pattern matching service
20
- */
21
- export interface IPatternMatchingService {
22
- findMatchingPatterns(
23
- context: PatternSearchContext
24
- ): Promise<Result<PatternMatch[], Error>>;
25
- applyPattern(patternId: string, targetCode: string): Promise<Result<AppliedPattern, Error>>;
26
- recordPattern(pattern: PatternDefinition): Promise<Result<Pattern, Error>>;
27
- learnPatterns(request: LearnPatternsRequest): Promise<Result<LearnedPatterns, Error>>;
28
- getPattern(patternId: string): Promise<Pattern | undefined>;
29
- listPatterns(filter?: PatternFilter): Promise<Pattern[]>;
30
- }
31
-
32
- /**
33
- * Context for pattern search
34
- */
35
- export interface PatternSearchContext {
36
- sourceCode?: string;
37
- fileType?: string;
38
- testType?: 'unit' | 'integration' | 'e2e' | 'property';
39
- framework?: string;
40
- tags?: string[];
41
- semanticQuery?: string;
42
- }
43
-
44
- /**
45
- * Pattern match result
46
- */
47
- export interface PatternMatch {
48
- pattern: Pattern;
49
- score: number;
50
- matchReason: string;
51
- suggestedApplication: string;
52
- }
53
-
54
- /**
55
- * Applied pattern result
56
- */
57
- export interface AppliedPattern {
58
- patternId: string;
59
- generatedCode: string;
60
- modifications: PatternModification[];
61
- confidence: number;
62
- }
63
-
64
- /**
65
- * Pattern modification record
66
- */
67
- export interface PatternModification {
68
- location: string;
69
- original?: string;
70
- replacement: string;
71
- reason: string;
72
- }
73
-
74
- /**
75
- * Pattern definition for recording
76
- */
77
- export interface PatternDefinition {
78
- name: string;
79
- structure: string;
80
- description?: string;
81
- tags?: string[];
82
- testType?: 'unit' | 'integration' | 'e2e' | 'property';
83
- framework?: string;
84
- examples?: PatternExample[];
85
- }
86
-
87
- /**
88
- * Pattern example
89
- */
90
- export interface PatternExample {
91
- input: string;
92
- output: string;
93
- context?: string;
94
- }
95
-
96
- /**
97
- * Pattern filter
98
- */
99
- export interface PatternFilter {
100
- testType?: 'unit' | 'integration' | 'e2e' | 'property';
101
- framework?: string;
102
- tags?: string[];
103
- minApplicability?: number;
104
- limit?: number;
105
- }
106
-
107
- /**
108
- * Configuration for the pattern matcher
109
- */
110
- export interface PatternMatcherConfig {
111
- maxPatterns: number;
112
- minMatchScore: number;
113
- enableVectorSearch: boolean;
114
- embeddingDimension: number;
115
- patternNamespace: string;
116
- /** Optional embedder instance (defaults to NomicEmbedder with fallback) */
117
- embedder?: IEmbeddingProvider;
118
- }
119
-
120
- const DEFAULT_CONFIG: PatternMatcherConfig = {
121
- maxPatterns: 100,
122
- minMatchScore: 0.5,
123
- enableVectorSearch: true,
124
- embeddingDimension: EMBEDDING_CONFIG.DIMENSIONS,
125
- patternNamespace: 'test-generation:patterns',
126
- };
127
-
128
- /**
129
- * Pattern Matching Service Implementation
130
- * Manages test patterns with learning and semantic search capabilities
131
- */
132
- export class PatternMatcherService implements IPatternMatchingService {
133
- private readonly config: PatternMatcherConfig;
134
- private readonly patternCache: Map<string, Pattern> = new Map();
135
- private readonly tsParser: TypeScriptASTParser;
136
- private readonly embedder: IEmbeddingProvider;
137
-
138
- constructor(
139
- private readonly memory: MemoryBackend,
140
- config: Partial<PatternMatcherConfig> = {}
141
- ) {
142
- this.config = { ...DEFAULT_CONFIG, ...config };
143
- this.tsParser = new TypeScriptASTParser();
144
- // Use provided embedder or create NomicEmbedder with fallback enabled
145
- this.embedder = config.embedder ?? new NomicEmbedder({ enableFallback: true });
146
- }
147
-
148
- /**
149
- * Match testable patterns from a source file
150
- * Uses TypeScript AST to identify functions, classes, and methods that need tests
151
- */
152
- async matchTestablePatterns(filePath: string): Promise<Result<TestablePattern[], Error>> {
153
- try {
154
- // Read file content
155
- let content: string;
156
- try {
157
- content = fs.readFileSync(filePath, 'utf-8');
158
- } catch {
159
- return err(new Error(`Cannot read file: ${filePath}`));
160
- }
161
-
162
- return this.matchTestablePatternsFromCode(content, filePath);
163
- } catch (error) {
164
- return err(error instanceof Error ? error : new Error(String(error)));
165
- }
166
- }
167
-
168
- /**
169
- * Match testable patterns from source code string
170
- */
171
- async matchTestablePatternsFromCode(
172
- sourceCode: string,
173
- fileName: string = 'module.ts'
174
- ): Promise<Result<TestablePattern[], Error>> {
175
- try {
176
- const patterns: TestablePattern[] = [];
177
- const sourceFile = this.tsParser.parseSource(sourceCode, fileName);
178
-
179
- // Extract functions and generate test suggestions
180
- const functions = this.tsParser.extractFunctions(sourceFile);
181
- for (const fn of functions) {
182
- patterns.push(this.createFunctionPattern(fn));
183
- }
184
-
185
- // Extract classes and their methods
186
- const classes = this.tsParser.extractClasses(sourceFile);
187
- for (const cls of classes) {
188
- // Add class-level pattern
189
- patterns.push(this.createClassPattern(cls));
190
-
191
- // Add method-level patterns for each public method
192
- for (const method of cls.methods) {
193
- patterns.push(this.createMethodPattern(cls.name, method));
194
- }
195
- }
196
-
197
- return ok(patterns);
198
- } catch (error) {
199
- return err(error instanceof Error ? error : new Error(String(error)));
200
- }
201
- }
202
-
203
- /**
204
- * Create a testable pattern for a function
205
- */
206
- private createFunctionPattern(fn: FunctionInfo): TestablePattern {
207
- const suggestedTests = this.suggestTestsForFunction(fn);
208
-
209
- return {
210
- type: 'function',
211
- name: fn.name,
212
- complexity: fn.complexity,
213
- lines: { start: fn.startLine, end: fn.endLine },
214
- branches: this.estimateBranches(fn.complexity),
215
- suggestedTests,
216
- context: {
217
- parameters: fn.parameters,
218
- returnType: fn.returnType,
219
- isAsync: fn.isAsync,
220
- },
221
- };
222
- }
223
-
224
- /**
225
- * Create a testable pattern for a class
226
- */
227
- private createClassPattern(cls: ClassInfo): TestablePattern {
228
- const totalComplexity = cls.methods.reduce((sum, m) => sum + m.complexity, 0);
229
- const suggestedTests = this.suggestTestsForClass(cls);
230
-
231
- return {
232
- type: 'class',
233
- name: cls.name,
234
- complexity: totalComplexity,
235
- lines: { start: cls.startLine, end: cls.endLine },
236
- branches: this.estimateBranches(totalComplexity),
237
- suggestedTests,
238
- context: {
239
- dependencies: cls.properties
240
- .filter((p) => !p.isPrivate)
241
- .map((p) => p.name),
242
- },
243
- };
244
- }
245
-
246
- /**
247
- * Create a testable pattern for a class method
248
- */
249
- private createMethodPattern(className: string, method: FunctionInfo): TestablePattern {
250
- const suggestedTests = this.suggestTestsForMethod(className, method);
251
-
252
- return {
253
- type: 'method',
254
- name: `${className}.${method.name}`,
255
- complexity: method.complexity,
256
- lines: { start: method.startLine, end: method.endLine },
257
- branches: this.estimateBranches(method.complexity),
258
- suggestedTests,
259
- context: {
260
- parameters: method.parameters,
261
- returnType: method.returnType,
262
- isAsync: method.isAsync,
263
- },
264
- };
265
- }
266
-
267
- /**
268
- * Suggest tests for a function based on its signature and complexity
269
- */
270
- private suggestTestsForFunction(fn: FunctionInfo): SuggestedTest[] {
271
- const tests: SuggestedTest[] = [];
272
-
273
- // Happy path test
274
- tests.push({
275
- description: `handles valid input correctly`,
276
- type: 'happy-path',
277
- priority: 'high',
278
- testCode: this.generateHappyPathTest(fn.name, fn.parameters, fn.isAsync),
279
- });
280
-
281
- // Parameter validation tests
282
- for (const param of fn.parameters) {
283
- if (!param.optional) {
284
- tests.push({
285
- description: `handles missing ${param.name} parameter`,
286
- type: 'error-handling',
287
- priority: 'high',
288
- });
289
- }
290
-
291
- // Type-specific tests
292
- if (param.type?.includes('string')) {
293
- tests.push({
294
- description: `handles empty string for ${param.name}`,
295
- type: 'boundary',
296
- priority: 'medium',
297
- });
298
- }
299
-
300
- if (param.type?.includes('number')) {
301
- tests.push({
302
- description: `handles zero value for ${param.name}`,
303
- type: 'boundary',
304
- priority: 'medium',
305
- });
306
- tests.push({
307
- description: `handles negative value for ${param.name}`,
308
- type: 'edge-case',
309
- priority: 'medium',
310
- });
311
- }
312
-
313
- if (param.type?.includes('[]') || param.type?.includes('Array')) {
314
- tests.push({
315
- description: `handles empty array for ${param.name}`,
316
- type: 'boundary',
317
- priority: 'medium',
318
- });
319
- }
320
- }
321
-
322
- // Async-specific tests
323
- if (fn.isAsync) {
324
- tests.push({
325
- description: `handles async rejection`,
326
- type: 'error-handling',
327
- priority: 'high',
328
- });
329
- }
330
-
331
- // Complexity-based tests
332
- if (fn.complexity > 5) {
333
- tests.push({
334
- description: `handles complex branching logic`,
335
- type: 'edge-case',
336
- priority: 'medium',
337
- });
338
- }
339
-
340
- return tests;
341
- }
342
-
343
- /**
344
- * Suggest tests for a class
345
- */
346
- private suggestTestsForClass(cls: ClassInfo): SuggestedTest[] {
347
- const tests: SuggestedTest[] = [];
348
-
349
- // Constructor test
350
- if (cls.hasConstructor) {
351
- tests.push({
352
- description: `instantiates correctly`,
353
- type: 'happy-path',
354
- priority: 'high',
355
- });
356
- }
357
-
358
- // Public methods coverage
359
- const publicMethods = cls.methods.filter(
360
- (m) => !m.name.startsWith('_') && !m.name.startsWith('#')
361
- );
362
- if (publicMethods.length > 0) {
363
- tests.push({
364
- description: `all public methods are callable`,
365
- type: 'happy-path',
366
- priority: 'high',
367
- });
368
- }
369
-
370
- // State management test
371
- if (cls.properties.some((p) => !p.isReadonly)) {
372
- tests.push({
373
- description: `maintains correct state after operations`,
374
- type: 'edge-case',
375
- priority: 'medium',
376
- });
377
- }
378
-
379
- return tests;
380
- }
381
-
382
- /**
383
- * Suggest tests for a class method
384
- */
385
- private suggestTestsForMethod(_className: string, method: FunctionInfo): SuggestedTest[] {
386
- // Reuse function test suggestions with method-specific context
387
- const tests = this.suggestTestsForFunction(method);
388
-
389
- // Add method-specific tests
390
- tests.push({
391
- description: `correctly modifies instance state`,
392
- type: 'edge-case',
393
- priority: 'medium',
394
- });
395
-
396
- return tests;
397
- }
398
-
399
- /**
400
- * Generate a happy path test code snippet
401
- */
402
- private generateHappyPathTest(
403
- fnName: string,
404
- params: ParameterInfo[],
405
- isAsync: boolean
406
- ): string {
407
- const paramList = params.map((p) => this.generateMockValue(p)).join(', ');
408
- const call = `${fnName}(${paramList})`;
409
- const assertion = isAsync ? `await ${call}` : call;
410
-
411
- return `it('should handle valid input correctly', ${isAsync ? 'async ' : ''}() => {
412
- const result = ${assertion};
413
- expect(result).toBeDefined();
414
- });`;
415
- }
416
-
417
- /**
418
- * Generate a mock value for a parameter based on its type
419
- */
420
- private generateMockValue(param: ParameterInfo): string {
421
- if (param.defaultValue) {
422
- return param.defaultValue;
423
- }
424
-
425
- const type = param.type?.toLowerCase() || 'unknown';
426
-
427
- if (type.includes('string')) return `'test-${param.name}'`;
428
- if (type.includes('number')) return '42';
429
- if (type.includes('boolean')) return 'true';
430
- if (type.includes('[]') || type.includes('array')) return '[]';
431
- if (type.includes('object') || type.includes('{')) return '{}';
432
- if (type.includes('function')) return '() => {}';
433
- if (type.includes('promise')) return 'Promise.resolve()';
434
- if (type.includes('date')) return 'new Date()';
435
- if (type.includes('null')) return 'null';
436
- if (type.includes('undefined')) return 'undefined';
437
-
438
- return `mock${param.name.charAt(0).toUpperCase() + param.name.slice(1)}`;
439
- }
440
-
441
- /**
442
- * Estimate number of branches from cyclomatic complexity
443
- */
444
- private estimateBranches(complexity: number): number {
445
- // Branches = complexity - 1 (assuming one path is the default)
446
- return Math.max(0, complexity - 1);
447
- }
448
-
449
- /**
450
- * Find patterns matching the given context
451
- */
452
- async findMatchingPatterns(
453
- context: PatternSearchContext
454
- ): Promise<Result<PatternMatch[], Error>> {
455
- try {
456
- const matches: PatternMatch[] = [];
457
-
458
- // Strategy 1: Semantic search if enabled and query provided
459
- if (this.config.enableVectorSearch && context.semanticQuery) {
460
- const semanticMatches = await this.semanticSearch(context.semanticQuery);
461
- matches.push(...semanticMatches);
462
- }
463
-
464
- // Strategy 2: Tag-based matching
465
- if (context.tags && context.tags.length > 0) {
466
- const tagMatches = await this.matchByTags(context.tags);
467
- this.mergeMatches(matches, tagMatches);
468
- }
469
-
470
- // Strategy 3: File type and framework matching
471
- if (context.fileType || context.framework || context.testType) {
472
- const metadataMatches = await this.matchByMetadata(context);
473
- this.mergeMatches(matches, metadataMatches);
474
- }
475
-
476
- // Strategy 4: Code structure analysis
477
- if (context.sourceCode) {
478
- const structureMatches = await this.matchByStructure(context.sourceCode);
479
- this.mergeMatches(matches, structureMatches);
480
- }
481
-
482
- // Filter by minimum score and sort by relevance
483
- const filteredMatches = matches
484
- .filter((m) => m.score >= this.config.minMatchScore)
485
- .sort((a, b) => b.score - a.score)
486
- .slice(0, this.config.maxPatterns);
487
-
488
- return ok(filteredMatches);
489
- } catch (error) {
490
- return err(error instanceof Error ? error : new Error(String(error)));
491
- }
492
- }
493
-
494
- /**
495
- * Apply a pattern to generate code
496
- */
497
- async applyPattern(
498
- patternId: string,
499
- targetCode: string
500
- ): Promise<Result<AppliedPattern, Error>> {
501
- try {
502
- const pattern = await this.getPattern(patternId);
503
- if (!pattern) {
504
- return err(new Error(`Pattern not found: ${patternId}`));
505
- }
506
-
507
- // Analyze target code structure
508
- const codeAnalysis = this.analyzeCodeStructure(targetCode);
509
-
510
- // Apply pattern transformations
511
- const modifications: PatternModification[] = [];
512
- let generatedCode = pattern.structure;
513
-
514
- // Replace placeholders in pattern with actual code elements
515
- const placeholders = this.extractPlaceholders(pattern.structure);
516
- for (const placeholder of placeholders) {
517
- const replacement = this.resolvePlaceholder(placeholder, codeAnalysis);
518
- if (replacement) {
519
- generatedCode = generatedCode.replace(
520
- new RegExp(`\\{\\{${placeholder}\\}\\}`, 'g'),
521
- replacement
522
- );
523
- modifications.push({
524
- location: placeholder,
525
- original: `{{${placeholder}}}`,
526
- replacement,
527
- reason: `Resolved from code analysis`,
528
- });
529
- }
530
- }
531
-
532
- // Calculate confidence based on how well the pattern matched
533
- const confidence = this.calculateApplicationConfidence(
534
- pattern,
535
- codeAnalysis,
536
- modifications
537
- );
538
-
539
- // Update pattern usage statistics
540
- await this.recordPatternUsage(patternId);
541
-
542
- return ok({
543
- patternId,
544
- generatedCode,
545
- modifications,
546
- confidence,
547
- });
548
- } catch (error) {
549
- return err(error instanceof Error ? error : new Error(String(error)));
550
- }
551
- }
552
-
553
- /**
554
- * Record a new pattern
555
- */
556
- async recordPattern(definition: PatternDefinition): Promise<Result<Pattern, Error>> {
557
- try {
558
- const pattern: Pattern = {
559
- id: uuidv4(),
560
- name: definition.name,
561
- structure: definition.structure,
562
- examples: definition.examples?.length ?? 0,
563
- applicability: 0.5, // Start with neutral applicability
564
- };
565
-
566
- // Store pattern in memory
567
- const patternKey = `${this.config.patternNamespace}:${pattern.id}`;
568
- await this.memory.set(patternKey, {
569
- ...pattern,
570
- description: definition.description,
571
- tags: definition.tags,
572
- testType: definition.testType,
573
- framework: definition.framework,
574
- examples: definition.examples,
575
- createdAt: new Date().toISOString(),
576
- usageCount: 0,
577
- });
578
-
579
- // Store vector embedding for semantic search if enabled
580
- if (this.config.enableVectorSearch) {
581
- const embedding = await this.generatePatternEmbedding(definition);
582
- await this.memory.storeVector(patternKey, embedding, {
583
- patternId: pattern.id,
584
- name: pattern.name,
585
- tags: definition.tags,
586
- });
587
- }
588
-
589
- // Add to local cache
590
- this.patternCache.set(pattern.id, pattern);
591
-
592
- return ok(pattern);
593
- } catch (error) {
594
- return err(error instanceof Error ? error : new Error(String(error)));
595
- }
596
- }
597
-
598
- /**
599
- * Learn patterns from existing test files
600
- */
601
- async learnPatterns(request: LearnPatternsRequest): Promise<Result<LearnedPatterns, Error>> {
602
- try {
603
- const { testFiles, depth } = request;
604
- const patterns: Pattern[] = [];
605
-
606
- for (const file of testFiles) {
607
- const filePatterns = await this.extractPatternsFromFile(file, depth);
608
- patterns.push(...filePatterns);
609
- }
610
-
611
- // Deduplicate similar patterns
612
- const uniquePatterns = this.deduplicatePatterns(patterns);
613
-
614
- // Store learned patterns
615
- for (const pattern of uniquePatterns) {
616
- await this.recordPattern({
617
- name: pattern.name,
618
- structure: pattern.structure,
619
- tags: ['learned', 'auto-extracted'],
620
- });
621
- }
622
-
623
- // Calculate overall confidence based on pattern consistency
624
- const confidence = this.calculateLearningConfidence(uniquePatterns);
625
-
626
- return ok({
627
- patterns: uniquePatterns,
628
- confidence,
629
- });
630
- } catch (error) {
631
- return err(error instanceof Error ? error : new Error(String(error)));
632
- }
633
- }
634
-
635
- /**
636
- * Get a pattern by ID
637
- */
638
- async getPattern(patternId: string): Promise<Pattern | undefined> {
639
- // Check cache first
640
- if (this.patternCache.has(patternId)) {
641
- return this.patternCache.get(patternId);
642
- }
643
-
644
- // Load from memory
645
- const patternKey = `${this.config.patternNamespace}:${patternId}`;
646
- const stored = await this.memory.get<Pattern & { usageCount: number }>(patternKey);
647
-
648
- if (stored) {
649
- const pattern: Pattern = {
650
- id: stored.id,
651
- name: stored.name,
652
- structure: stored.structure,
653
- examples: stored.examples,
654
- applicability: stored.applicability,
655
- };
656
- this.patternCache.set(patternId, pattern);
657
- return pattern;
658
- }
659
-
660
- return undefined;
661
- }
662
-
663
- /**
664
- * List patterns with optional filtering
665
- */
666
- async listPatterns(filter?: PatternFilter): Promise<Pattern[]> {
667
- const patterns: Pattern[] = [];
668
- const limit = filter?.limit ?? this.config.maxPatterns;
669
-
670
- // Search for patterns in memory
671
- const keys = await this.memory.search(`${this.config.patternNamespace}:*`, limit * 2);
672
-
673
- for (const key of keys) {
674
- const stored = await this.memory.get<Pattern & {
675
- testType?: string;
676
- framework?: string;
677
- tags?: string[];
678
- }>(key);
679
-
680
- if (stored) {
681
- // Apply filters
682
- if (filter?.testType && stored.testType !== filter.testType) continue;
683
- if (filter?.framework && stored.framework !== filter.framework) continue;
684
- if (filter?.minApplicability && stored.applicability < filter.minApplicability) continue;
685
- if (filter?.tags && filter.tags.length > 0) {
686
- const hasTag = filter.tags.some((t) => stored.tags?.includes(t));
687
- if (!hasTag) continue;
688
- }
689
-
690
- patterns.push({
691
- id: stored.id,
692
- name: stored.name,
693
- structure: stored.structure,
694
- examples: stored.examples,
695
- applicability: stored.applicability,
696
- });
697
-
698
- if (patterns.length >= limit) break;
699
- }
700
- }
701
-
702
- return patterns.sort((a, b) => b.applicability - a.applicability);
703
- }
704
-
705
- // ============================================================================
706
- // Private Helper Methods
707
- // ============================================================================
708
-
709
- private async semanticSearch(query: string): Promise<PatternMatch[]> {
710
- // Generate embedding for query and search using NomicEmbedder
711
- const queryEmbedding = await this.generateQueryEmbedding(query);
712
- const results: VectorSearchResult[] = await this.memory.vectorSearch(
713
- queryEmbedding,
714
- 10
715
- );
716
-
717
- const matches: PatternMatch[] = [];
718
- for (const result of results) {
719
- const pattern = await this.getPattern(
720
- (result.metadata as { patternId: string })?.patternId
721
- );
722
- if (pattern) {
723
- matches.push({
724
- pattern,
725
- score: result.score,
726
- matchReason: 'Semantic similarity to query',
727
- suggestedApplication: `Apply ${pattern.name} pattern to generate tests`,
728
- });
729
- }
730
- }
731
-
732
- return matches;
733
- }
734
-
735
- private async matchByTags(tags: string[]): Promise<PatternMatch[]> {
736
- const matches: PatternMatch[] = [];
737
- const patterns = await this.listPatterns({ tags });
738
-
739
- for (const pattern of patterns) {
740
- matches.push({
741
- pattern,
742
- score: 0.7, // Tag matching gives moderate score
743
- matchReason: `Pattern tags match: ${tags.join(', ')}`,
744
- suggestedApplication: `Apply ${pattern.name} pattern based on tag match`,
745
- });
746
- }
747
-
748
- return matches;
749
- }
750
-
751
- private async matchByMetadata(context: PatternSearchContext): Promise<PatternMatch[]> {
752
- const matches: PatternMatch[] = [];
753
- const patterns = await this.listPatterns({
754
- testType: context.testType,
755
- framework: context.framework,
756
- });
757
-
758
- for (const pattern of patterns) {
759
- matches.push({
760
- pattern,
761
- score: 0.6, // Metadata matching gives moderate score
762
- matchReason: `Pattern matches ${context.testType || ''} ${context.framework || ''}`.trim(),
763
- suggestedApplication: `Apply ${pattern.name} pattern for ${context.testType || 'test'} generation`,
764
- });
765
- }
766
-
767
- return matches;
768
- }
769
-
770
- private async matchByStructure(sourceCode: string): Promise<PatternMatch[]> {
771
- // Analyze code structure using TypeScript AST and find matching patterns
772
- const analysis = this.analyzeCodeStructure(sourceCode);
773
- const matches: PatternMatch[] = [];
774
-
775
- // Look for patterns that match detected constructs
776
- const allPatterns = await this.listPatterns();
777
- for (const pattern of allPatterns) {
778
- const structureScore = this.calculateStructureMatch(pattern, analysis);
779
- if (structureScore > 0) {
780
- matches.push({
781
- pattern,
782
- score: structureScore,
783
- matchReason: `Pattern structure matches code constructs`,
784
- suggestedApplication: `Apply ${pattern.name} based on code structure analysis`,
785
- });
786
- }
787
- }
788
-
789
- return matches;
790
- }
791
-
792
- private mergeMatches(target: PatternMatch[], source: PatternMatch[]): void {
793
- for (const match of source) {
794
- const existing = target.find((m) => m.pattern.id === match.pattern.id);
795
- if (existing) {
796
- // Combine scores
797
- existing.score = Math.min(1, existing.score + match.score * 0.5);
798
- existing.matchReason += `, ${match.matchReason}`;
799
- } else {
800
- target.push(match);
801
- }
802
- }
803
- }
804
-
805
- private analyzeCodeStructure(code: string): CodeAnalysis {
806
- // Use real TypeScript AST parsing for accurate analysis
807
- const parser = new TypeScriptASTParser();
808
- const sourceFile = parser.parseSource(code);
809
- const functions = parser.extractFunctions(sourceFile);
810
- const classes = parser.extractClasses(sourceFile);
811
-
812
- // Calculate total complexity from all functions and methods
813
- let totalComplexity = functions.reduce((sum, fn) => sum + fn.complexity, 0);
814
- for (const cls of classes) {
815
- totalComplexity += cls.methods.reduce((sum, m) => sum + m.complexity, 0);
816
- }
817
-
818
- return {
819
- hasClasses: classes.length > 0,
820
- hasFunctions: functions.length > 0,
821
- hasAsyncCode: functions.some((f) => f.isAsync) ||
822
- classes.some((c) => c.methods.some((m) => m.isAsync)),
823
- hasExports: functions.some((f) => f.isExported) ||
824
- classes.some((c) => c.isExported),
825
- imports: this.extractImports(code),
826
- identifiers: this.extractIdentifiers(code),
827
- complexity: totalComplexity || this.estimateComplexity(code),
828
- functions,
829
- classes,
830
- };
831
- }
832
-
833
- private extractImports(code: string): string[] {
834
- const importRegex = /import\s+(?:\{[^}]+\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/g;
835
- const imports: string[] = [];
836
- let match;
837
- while ((match = importRegex.exec(code)) !== null) {
838
- imports.push(match[1]);
839
- }
840
- return imports;
841
- }
842
-
843
- private extractIdentifiers(code: string): string[] {
844
- const identifierRegex = /(?:class|function|const|let|var)\s+(\w+)/g;
845
- const identifiers: string[] = [];
846
- let match;
847
- while ((match = identifierRegex.exec(code)) !== null) {
848
- identifiers.push(match[1]);
849
- }
850
- return identifiers;
851
- }
852
-
853
- private estimateComplexity(code: string): number {
854
- // Simple complexity estimation based on control flow statements
855
- const controlFlowPatterns = [
856
- /if\s*\(/g,
857
- /else\s*{/g,
858
- /for\s*\(/g,
859
- /while\s*\(/g,
860
- /switch\s*\(/g,
861
- /\?\s*:/g, // ternary
862
- ];
863
-
864
- let complexity = 1;
865
- for (const pattern of controlFlowPatterns) {
866
- const matches = code.match(pattern);
867
- complexity += matches ? matches.length : 0;
868
- }
869
-
870
- return complexity;
871
- }
872
-
873
- private extractPlaceholders(structure: string): string[] {
874
- const placeholderRegex = /\{\{(\w+)\}\}/g;
875
- const placeholders: string[] = [];
876
- let match;
877
- while ((match = placeholderRegex.exec(structure)) !== null) {
878
- placeholders.push(match[1]);
879
- }
880
- return placeholders;
881
- }
882
-
883
- private resolvePlaceholder(placeholder: string, analysis: CodeAnalysis): string | null {
884
- // Resolve placeholders based on code analysis results
885
- switch (placeholder.toLowerCase()) {
886
- case 'classname':
887
- case 'modulename':
888
- return analysis.identifiers[0] || 'Module';
889
- case 'functionname':
890
- return analysis.identifiers.find((id) => /^[a-z]/.test(id)) || 'func';
891
- case 'imports':
892
- return analysis.imports.map((i) => `import '${i}'`).join('\n');
893
- default:
894
- return null;
895
- }
896
- }
897
-
898
- private calculateApplicationConfidence(
899
- pattern: Pattern,
900
- analysis: CodeAnalysis,
901
- modifications: PatternModification[]
902
- ): number {
903
- // Base confidence from pattern applicability
904
- let confidence = pattern.applicability;
905
-
906
- // Adjust based on how many placeholders were resolved
907
- const placeholders = this.extractPlaceholders(pattern.structure);
908
- const resolvedRatio = modifications.length / Math.max(placeholders.length, 1);
909
- confidence = confidence * 0.5 + resolvedRatio * 0.5;
910
-
911
- // Adjust based on code complexity match
912
- if (analysis.complexity > 10) {
913
- confidence *= 0.9; // Slightly lower confidence for complex code
914
- }
915
-
916
- return Math.min(1, Math.max(0, confidence));
917
- }
918
-
919
- private calculateStructureMatch(pattern: Pattern, analysis: CodeAnalysis): number {
920
- // Calculate how well pattern structure matches code using AST analysis
921
- let score = 0;
922
-
923
- // Check for structural similarities
924
- if (analysis.hasClasses && pattern.structure.includes('class')) score += 0.3;
925
- if (analysis.hasFunctions && pattern.structure.includes('function')) score += 0.3;
926
- if (analysis.hasAsyncCode && pattern.structure.includes('async')) score += 0.2;
927
- if (analysis.hasExports && pattern.structure.includes('export')) score += 0.2;
928
-
929
- return Math.min(1, score);
930
- }
931
-
932
- private async recordPatternUsage(patternId: string): Promise<void> {
933
- const patternKey = `${this.config.patternNamespace}:${patternId}`;
934
- const stored = await this.memory.get<Pattern & { usageCount: number }>(patternKey);
935
-
936
- if (stored) {
937
- const usageCount = (stored.usageCount || 0) + 1;
938
- // Increase applicability score based on usage
939
- const newApplicability = Math.min(1, stored.applicability + 0.01);
940
-
941
- await this.memory.set(patternKey, {
942
- ...stored,
943
- usageCount,
944
- applicability: newApplicability,
945
- lastUsedAt: new Date().toISOString(),
946
- });
947
-
948
- // Update cache
949
- if (this.patternCache.has(patternId)) {
950
- const cached = this.patternCache.get(patternId)!;
951
- cached.applicability = newApplicability;
952
- }
953
- }
954
- }
955
-
956
- private async extractPatternsFromFile(
957
- file: string,
958
- depth: 'shallow' | 'deep'
959
- ): Promise<Pattern[]> {
960
- const patterns: Pattern[] = [];
961
-
962
- try {
963
- // Read the file content
964
- let content: string;
965
- try {
966
- content = fs.readFileSync(file, 'utf-8');
967
- } catch {
968
- // File doesn't exist or can't be read, return empty
969
- return patterns;
970
- }
971
-
972
- // Parse with TypeScript AST
973
- const parser = new TypeScriptASTParser();
974
- const sourceFile = parser.parseSource(content, path.basename(file));
975
-
976
- // Extract test patterns from describe/it/test blocks
977
- const testPatterns = this.extractTestBlockPatterns(sourceFile, content);
978
- patterns.push(...testPatterns);
979
-
980
- // Deep analysis extracts more detailed patterns
981
- if (depth === 'deep') {
982
- // Extract setup/teardown patterns
983
- const setupPatterns = this.extractSetupTeardownPatterns(sourceFile, content);
984
- patterns.push(...setupPatterns);
985
-
986
- // Extract assertion patterns
987
- const assertionPatterns = this.extractAssertionPatterns(content);
988
- patterns.push(...assertionPatterns);
989
-
990
- // Extract mocking patterns
991
- const mockPatterns = this.extractMockingPatterns(content);
992
- patterns.push(...mockPatterns);
993
- }
994
- } catch {
995
- // If parsing fails, return a basic pattern
996
- patterns.push({
997
- id: uuidv4(),
998
- name: `Basic pattern from ${path.basename(file)}`,
999
- structure: `describe('{{moduleName}}', () => {\n it('should {{behavior}}', () => {\n // Test implementation\n });\n});`,
1000
- examples: 1,
1001
- applicability: 0.5,
1002
- });
1003
- }
1004
-
1005
- return patterns;
1006
- }
1007
-
1008
- /**
1009
- * Extract test block patterns (describe/it/test)
1010
- */
1011
- private extractTestBlockPatterns(
1012
- _sourceFile: ts.SourceFile,
1013
- content: string
1014
- ): Pattern[] {
1015
- const patterns: Pattern[] = [];
1016
-
1017
- // Find describe blocks with their nested structure
1018
- const describeRegex = /describe\s*\(\s*['"`]([^'"`]+)['"`]\s*,\s*(?:function\s*\(\s*\)|(?:\(\s*\))?\s*=>)\s*\{/g;
1019
- let match;
1020
-
1021
- while ((match = describeRegex.exec(content)) !== null) {
1022
- const startIndex = match.index;
1023
- const blockContent = this.extractBlockContent(content, startIndex + match[0].length - 1);
1024
-
1025
- if (blockContent) {
1026
- // Analyze the structure of tests within this describe block
1027
- const itCount = (blockContent.match(/\bit\s*\(/g) || []).length;
1028
- const testCount = (blockContent.match(/\btest\s*\(/g) || []).length;
1029
- const hasBeforeEach = /beforeEach\s*\(/.test(blockContent);
1030
- const hasAfterEach = /afterEach\s*\(/.test(blockContent);
1031
-
1032
- // Create a structural pattern
1033
- let structure = `describe('{{moduleName}}', () => {\n`;
1034
- if (hasBeforeEach) structure += ` beforeEach(() => {\n // Setup\n });\n\n`;
1035
- if (hasAfterEach) structure += ` afterEach(() => {\n // Teardown\n });\n\n`;
1036
-
1037
- for (let i = 0; i < Math.max(itCount, testCount); i++) {
1038
- structure += ` it('should {{behavior${i > 0 ? i + 1 : ''}}}', () => {\n // Test implementation\n });\n`;
1039
- }
1040
- structure += '});';
1041
-
1042
- patterns.push({
1043
- id: uuidv4(),
1044
- name: `Test block pattern: ${match[1]}`,
1045
- structure,
1046
- examples: 1,
1047
- applicability: 0.6,
1048
- });
1049
- }
1050
- }
1051
-
1052
- return patterns;
1053
- }
1054
-
1055
- /**
1056
- * Extract setup/teardown patterns (beforeEach, afterEach, etc.)
1057
- */
1058
- private extractSetupTeardownPatterns(
1059
- _sourceFile: ts.SourceFile,
1060
- content: string
1061
- ): Pattern[] {
1062
- const patterns: Pattern[] = [];
1063
-
1064
- // beforeEach pattern
1065
- if (/beforeEach\s*\(/.test(content)) {
1066
- const beforeEachMatch = content.match(/beforeEach\s*\(\s*(?:async\s*)?\(\s*\)\s*=>\s*\{([^}]*)\}/);
1067
- if (beforeEachMatch) {
1068
- patterns.push({
1069
- id: uuidv4(),
1070
- name: 'beforeEach setup pattern',
1071
- structure: `beforeEach(async () => {\n {{setupCode}}\n});`,
1072
- examples: 1,
1073
- applicability: 0.7,
1074
- });
1075
- }
1076
- }
1077
-
1078
- // afterEach pattern
1079
- if (/afterEach\s*\(/.test(content)) {
1080
- patterns.push({
1081
- id: uuidv4(),
1082
- name: 'afterEach teardown pattern',
1083
- structure: `afterEach(async () => {\n {{teardownCode}}\n});`,
1084
- examples: 1,
1085
- applicability: 0.7,
1086
- });
1087
- }
1088
-
1089
- // beforeAll pattern
1090
- if (/beforeAll\s*\(/.test(content)) {
1091
- patterns.push({
1092
- id: uuidv4(),
1093
- name: 'beforeAll setup pattern',
1094
- structure: `beforeAll(async () => {\n {{setupCode}}\n});`,
1095
- examples: 1,
1096
- applicability: 0.6,
1097
- });
1098
- }
1099
-
1100
- return patterns;
1101
- }
1102
-
1103
- /**
1104
- * Extract assertion patterns from test code
1105
- */
1106
- private extractAssertionPatterns(content: string): Pattern[] {
1107
- const patterns: Pattern[] = [];
1108
- const assertionTypes = new Set<string>();
1109
-
1110
- // Detect assertion styles
1111
- if (/expect\([^)]+\)\.toBe\(/.test(content)) assertionTypes.add('toBe');
1112
- if (/expect\([^)]+\)\.toEqual\(/.test(content)) assertionTypes.add('toEqual');
1113
- if (/expect\([^)]+\)\.toThrow\(/.test(content)) assertionTypes.add('toThrow');
1114
- if (/expect\([^)]+\)\.toHaveBeenCalled/.test(content)) assertionTypes.add('toHaveBeenCalled');
1115
- if (/expect\([^)]+\)\.resolves/.test(content)) assertionTypes.add('resolves');
1116
- if (/expect\([^)]+\)\.rejects/.test(content)) assertionTypes.add('rejects');
1117
-
1118
- if (assertionTypes.size > 0) {
1119
- const assertionStructures = Array.from(assertionTypes).map((type) => {
1120
- switch (type) {
1121
- case 'toBe':
1122
- return 'expect({{actual}}).toBe({{expected}})';
1123
- case 'toEqual':
1124
- return 'expect({{actual}}).toEqual({{expected}})';
1125
- case 'toThrow':
1126
- return 'expect(() => {{call}}).toThrow({{error}})';
1127
- case 'toHaveBeenCalled':
1128
- return 'expect({{mock}}).toHaveBeenCalledWith({{args}})';
1129
- case 'resolves':
1130
- return 'await expect({{promise}}).resolves.toEqual({{expected}})';
1131
- case 'rejects':
1132
- return 'await expect({{promise}}).rejects.toThrow({{error}})';
1133
- default:
1134
- return `expect({{actual}}).${type}({{expected}})`;
1135
- }
1136
- });
1137
-
1138
- patterns.push({
1139
- id: uuidv4(),
1140
- name: 'Assertion patterns',
1141
- structure: assertionStructures.join('\n'),
1142
- examples: assertionTypes.size,
1143
- applicability: 0.8,
1144
- });
1145
- }
1146
-
1147
- return patterns;
1148
- }
1149
-
1150
- /**
1151
- * Extract mocking patterns from test code
1152
- */
1153
- private extractMockingPatterns(content: string): Pattern[] {
1154
- const patterns: Pattern[] = [];
1155
-
1156
- // jest.mock pattern
1157
- if (/jest\.mock\(/.test(content)) {
1158
- patterns.push({
1159
- id: uuidv4(),
1160
- name: 'Jest module mock pattern',
1161
- structure: `jest.mock('{{modulePath}}', () => ({\n {{mockImplementation}}\n}));`,
1162
- examples: 1,
1163
- applicability: 0.7,
1164
- });
1165
- }
1166
-
1167
- // jest.fn pattern
1168
- if (/jest\.fn\(/.test(content)) {
1169
- patterns.push({
1170
- id: uuidv4(),
1171
- name: 'Jest function mock pattern',
1172
- structure: `const {{mockName}} = jest.fn().mockReturnValue({{returnValue}});`,
1173
- examples: 1,
1174
- applicability: 0.7,
1175
- });
1176
- }
1177
-
1178
- // vi.mock pattern (vitest)
1179
- if (/vi\.mock\(/.test(content)) {
1180
- patterns.push({
1181
- id: uuidv4(),
1182
- name: 'Vitest module mock pattern',
1183
- structure: `vi.mock('{{modulePath}}', () => ({\n {{mockImplementation}}\n}));`,
1184
- examples: 1,
1185
- applicability: 0.7,
1186
- });
1187
- }
1188
-
1189
- // vi.fn pattern (vitest)
1190
- if (/vi\.fn\(/.test(content)) {
1191
- patterns.push({
1192
- id: uuidv4(),
1193
- name: 'Vitest function mock pattern',
1194
- structure: `const {{mockName}} = vi.fn().mockReturnValue({{returnValue}});`,
1195
- examples: 1,
1196
- applicability: 0.7,
1197
- });
1198
- }
1199
-
1200
- // spyOn pattern
1201
- if (/(?:jest|vi)\.spyOn\(/.test(content)) {
1202
- patterns.push({
1203
- id: uuidv4(),
1204
- name: 'SpyOn pattern',
1205
- structure: `const spy = {{framework}}.spyOn({{object}}, '{{method}}').mockImplementation({{impl}});`,
1206
- examples: 1,
1207
- applicability: 0.6,
1208
- });
1209
- }
1210
-
1211
- return patterns;
1212
- }
1213
-
1214
- /**
1215
- * Extract a complete block of code starting from an opening brace
1216
- */
1217
- private extractBlockContent(content: string, startIndex: number): string | null {
1218
- let braceCount = 0;
1219
- let endIndex = startIndex;
1220
- let started = false;
1221
-
1222
- for (let i = startIndex; i < content.length; i++) {
1223
- const char = content[i];
1224
- if (char === '{') {
1225
- braceCount++;
1226
- started = true;
1227
- } else if (char === '}') {
1228
- braceCount--;
1229
- if (started && braceCount === 0) {
1230
- endIndex = i;
1231
- break;
1232
- }
1233
- }
1234
- }
1235
-
1236
- if (endIndex > startIndex) {
1237
- return content.substring(startIndex, endIndex + 1);
1238
- }
1239
- return null;
1240
- }
1241
-
1242
- private deduplicatePatterns(patterns: Pattern[]): Pattern[] {
1243
- const seen = new Map<string, Pattern>();
1244
-
1245
- for (const pattern of patterns) {
1246
- // Use structure hash as key for deduplication
1247
- const structureKey = this.hashStructure(pattern.structure);
1248
- if (!seen.has(structureKey)) {
1249
- seen.set(structureKey, pattern);
1250
- } else {
1251
- // Merge examples count
1252
- const existing = seen.get(structureKey)!;
1253
- existing.examples += pattern.examples;
1254
- }
1255
- }
1256
-
1257
- return Array.from(seen.values());
1258
- }
1259
-
1260
- private hashStructure(structure: string): string {
1261
- // Simple hash for structure comparison
1262
- const normalized = structure.replace(/\s+/g, ' ').trim();
1263
- let hash = 0;
1264
- for (let i = 0; i < normalized.length; i++) {
1265
- const char = normalized.charCodeAt(i);
1266
- hash = ((hash << 5) - hash) + char;
1267
- hash = hash & hash;
1268
- }
1269
- return hash.toString(16);
1270
- }
1271
-
1272
- private calculateLearningConfidence(patterns: Pattern[]): number {
1273
- if (patterns.length === 0) return 0;
1274
-
1275
- // Confidence based on:
1276
- // 1. Number of patterns found
1277
- // 2. Average examples per pattern
1278
- // 3. Structural diversity
1279
-
1280
- const avgExamples =
1281
- patterns.reduce((sum, p) => sum + p.examples, 0) / patterns.length;
1282
- const countFactor = Math.min(1, patterns.length / 10);
1283
- const examplesFactor = Math.min(1, avgExamples / 5);
1284
-
1285
- return countFactor * 0.5 + examplesFactor * 0.5;
1286
- }
1287
-
1288
- /**
1289
- * Generate embedding for a pattern definition
1290
- * Uses NomicEmbedder for semantic embeddings (falls back to pseudo-embeddings if Ollama unavailable)
1291
- */
1292
- private async generatePatternEmbedding(definition: PatternDefinition): Promise<number[]> {
1293
- const text = this.formatPatternForEmbedding(definition);
1294
- return this.embedder.embed(text);
1295
- }
1296
-
1297
- /**
1298
- * Generate embedding for a search query
1299
- * Uses the same embedder as patterns for consistent similarity matching
1300
- */
1301
- private async generateQueryEmbedding(query: string): Promise<number[]> {
1302
- return this.embedder.embed(query);
1303
- }
1304
-
1305
- /**
1306
- * Format a pattern definition for embedding generation
1307
- * Creates a semantic-rich text representation
1308
- */
1309
- private formatPatternForEmbedding(definition: PatternDefinition): string {
1310
- const parts = [
1311
- `Pattern: ${definition.name}`,
1312
- definition.description ? `Description: ${definition.description}` : '',
1313
- `Structure: ${definition.structure}`,
1314
- definition.tags?.length ? `Tags: ${definition.tags.join(', ')}` : '',
1315
- definition.testType ? `Test type: ${definition.testType}` : '',
1316
- definition.framework ? `Framework: ${definition.framework}` : '',
1317
- ].filter(Boolean);
1318
-
1319
- return parts.join('\n');
1320
- }
1321
- }
1322
-
1323
- /**
1324
- * Code analysis result
1325
- */
1326
- interface CodeAnalysis {
1327
- hasClasses: boolean;
1328
- hasFunctions: boolean;
1329
- hasAsyncCode: boolean;
1330
- hasExports: boolean;
1331
- imports: string[];
1332
- identifiers: string[];
1333
- complexity: number;
1334
- functions?: FunctionInfo[];
1335
- classes?: ClassInfo[];
1336
- }
1337
-
1338
- /**
1339
- * Information about a function extracted from AST
1340
- */
1341
- interface FunctionInfo {
1342
- name: string;
1343
- parameters: ParameterInfo[];
1344
- returnType: string | undefined;
1345
- isAsync: boolean;
1346
- isExported: boolean;
1347
- complexity: number;
1348
- startLine: number;
1349
- endLine: number;
1350
- body?: string;
1351
- }
1352
-
1353
- /**
1354
- * Information about a class extracted from AST
1355
- */
1356
- interface ClassInfo {
1357
- name: string;
1358
- methods: FunctionInfo[];
1359
- properties: PropertyInfo[];
1360
- isExported: boolean;
1361
- hasConstructor: boolean;
1362
- startLine: number;
1363
- endLine: number;
1364
- }
1365
-
1366
- /**
1367
- * Information about a parameter
1368
- */
1369
- interface ParameterInfo {
1370
- name: string;
1371
- type: string | undefined;
1372
- optional: boolean;
1373
- defaultValue: string | undefined;
1374
- }
1375
-
1376
- /**
1377
- * Information about a class property
1378
- */
1379
- interface PropertyInfo {
1380
- name: string;
1381
- type: string | undefined;
1382
- isPrivate: boolean;
1383
- isReadonly: boolean;
1384
- }
1385
-
1386
- /**
1387
- * Testable pattern extracted from code analysis
1388
- */
1389
- export interface TestablePattern {
1390
- type: 'function' | 'class' | 'method' | 'module';
1391
- name: string;
1392
- complexity: number;
1393
- lines: { start: number; end: number };
1394
- branches: number;
1395
- suggestedTests: SuggestedTest[];
1396
- context: {
1397
- parameters?: ParameterInfo[];
1398
- returnType?: string;
1399
- dependencies?: string[];
1400
- isAsync?: boolean;
1401
- };
1402
- }
1403
-
1404
- /**
1405
- * Suggested test for a pattern
1406
- */
1407
- interface SuggestedTest {
1408
- description: string;
1409
- type: 'happy-path' | 'edge-case' | 'error-handling' | 'boundary';
1410
- priority: 'high' | 'medium' | 'low';
1411
- testCode?: string;
1412
- }
1413
-
1414
- /**
1415
- * TypeScript AST Parser Helper
1416
- * Provides utilities for parsing TypeScript files and extracting patterns
1417
- */
1418
- class TypeScriptASTParser {
1419
- private sourceFile: ts.SourceFile | null = null;
1420
- private sourceCode: string = '';
1421
-
1422
- /**
1423
- * Parse a TypeScript file and return the source file AST
1424
- */
1425
- parseFile(filePath: string, content?: string): ts.SourceFile {
1426
- if (content) {
1427
- this.sourceCode = content;
1428
- } else {
1429
- this.sourceCode = fs.readFileSync(filePath, 'utf-8');
1430
- }
1431
-
1432
- this.sourceFile = ts.createSourceFile(
1433
- path.basename(filePath),
1434
- this.sourceCode,
1435
- ts.ScriptTarget.Latest,
1436
- true,
1437
- ts.ScriptKind.TS
1438
- );
1439
-
1440
- return this.sourceFile;
1441
- }
1442
-
1443
- /**
1444
- * Parse source code string directly
1445
- */
1446
- parseSource(source: string, fileName: string = 'module.ts'): ts.SourceFile {
1447
- this.sourceCode = source;
1448
- this.sourceFile = ts.createSourceFile(
1449
- fileName,
1450
- source,
1451
- ts.ScriptTarget.Latest,
1452
- true,
1453
- ts.ScriptKind.TS
1454
- );
1455
- return this.sourceFile;
1456
- }
1457
-
1458
- /**
1459
- * Extract all functions from the AST
1460
- */
1461
- extractFunctions(sourceFile: ts.SourceFile): FunctionInfo[] {
1462
- const functions: FunctionInfo[] = [];
1463
-
1464
- const visit = (node: ts.Node): void => {
1465
- if (ts.isFunctionDeclaration(node) && node.name) {
1466
- functions.push(this.extractFunctionInfo(node, sourceFile));
1467
- } else if (ts.isVariableStatement(node)) {
1468
- // Handle arrow functions assigned to variables
1469
- for (const declaration of node.declarationList.declarations) {
1470
- if (
1471
- ts.isVariableDeclaration(declaration) &&
1472
- declaration.initializer &&
1473
- (ts.isArrowFunction(declaration.initializer) ||
1474
- ts.isFunctionExpression(declaration.initializer))
1475
- ) {
1476
- const name = declaration.name.getText(sourceFile);
1477
- functions.push(
1478
- this.extractArrowFunctionInfo(
1479
- name,
1480
- declaration.initializer,
1481
- sourceFile,
1482
- node
1483
- )
1484
- );
1485
- }
1486
- }
1487
- }
1488
- ts.forEachChild(node, visit);
1489
- };
1490
-
1491
- ts.forEachChild(sourceFile, visit);
1492
- return functions;
1493
- }
1494
-
1495
- /**
1496
- * Extract all classes from the AST
1497
- */
1498
- extractClasses(sourceFile: ts.SourceFile): ClassInfo[] {
1499
- const classes: ClassInfo[] = [];
1500
-
1501
- const visit = (node: ts.Node): void => {
1502
- if (ts.isClassDeclaration(node) && node.name) {
1503
- classes.push(this.extractClassInfo(node, sourceFile));
1504
- }
1505
- ts.forEachChild(node, visit);
1506
- };
1507
-
1508
- ts.forEachChild(sourceFile, visit);
1509
- return classes;
1510
- }
1511
-
1512
- /**
1513
- * Extract information from a function declaration
1514
- */
1515
- private extractFunctionInfo(
1516
- node: ts.FunctionDeclaration,
1517
- sourceFile: ts.SourceFile
1518
- ): FunctionInfo {
1519
- const name = node.name?.getText(sourceFile) || 'anonymous';
1520
- const parameters = this.extractParameters(node.parameters, sourceFile);
1521
- const returnType = node.type?.getText(sourceFile);
1522
- const isAsync = node.modifiers?.some(
1523
- (m) => m.kind === ts.SyntaxKind.AsyncKeyword
1524
- ) ?? false;
1525
- const isExported = node.modifiers?.some(
1526
- (m) => m.kind === ts.SyntaxKind.ExportKeyword
1527
- ) ?? false;
1528
-
1529
- const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(
1530
- node.getStart(sourceFile)
1531
- );
1532
- const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(
1533
- node.getEnd()
1534
- );
1535
-
1536
- const complexity = this.calculateCyclomaticComplexity(node);
1537
-
1538
- return {
1539
- name,
1540
- parameters,
1541
- returnType,
1542
- isAsync,
1543
- isExported,
1544
- complexity,
1545
- startLine: startLine + 1,
1546
- endLine: endLine + 1,
1547
- body: node.body?.getText(sourceFile),
1548
- };
1549
- }
1550
-
1551
- /**
1552
- * Extract information from an arrow function or function expression
1553
- */
1554
- private extractArrowFunctionInfo(
1555
- name: string,
1556
- node: ts.ArrowFunction | ts.FunctionExpression,
1557
- sourceFile: ts.SourceFile,
1558
- parentNode: ts.Node
1559
- ): FunctionInfo {
1560
- const parameters = this.extractParameters(node.parameters, sourceFile);
1561
- const returnType = node.type?.getText(sourceFile);
1562
- const isAsync = node.modifiers?.some(
1563
- (m) => m.kind === ts.SyntaxKind.AsyncKeyword
1564
- ) ?? false;
1565
-
1566
- // Check if parent is exported
1567
- const isExported = ts.isVariableStatement(parentNode) &&
1568
- (parentNode.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
1569
-
1570
- const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(
1571
- node.getStart(sourceFile)
1572
- );
1573
- const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(
1574
- node.getEnd()
1575
- );
1576
-
1577
- const complexity = this.calculateCyclomaticComplexity(node);
1578
-
1579
- return {
1580
- name,
1581
- parameters,
1582
- returnType,
1583
- isAsync,
1584
- isExported,
1585
- complexity,
1586
- startLine: startLine + 1,
1587
- endLine: endLine + 1,
1588
- body: node.body?.getText(sourceFile),
1589
- };
1590
- }
1591
-
1592
- /**
1593
- * Extract class information
1594
- */
1595
- private extractClassInfo(
1596
- node: ts.ClassDeclaration,
1597
- sourceFile: ts.SourceFile
1598
- ): ClassInfo {
1599
- const name = node.name?.getText(sourceFile) || 'AnonymousClass';
1600
- const methods: FunctionInfo[] = [];
1601
- const properties: PropertyInfo[] = [];
1602
- let hasConstructor = false;
1603
-
1604
- const isExported = node.modifiers?.some(
1605
- (m) => m.kind === ts.SyntaxKind.ExportKeyword
1606
- ) ?? false;
1607
-
1608
- for (const member of node.members) {
1609
- if (ts.isMethodDeclaration(member)) {
1610
- const methodName = member.name.getText(sourceFile);
1611
- const parameters = this.extractParameters(member.parameters, sourceFile);
1612
- const returnType = member.type?.getText(sourceFile);
1613
- const isAsync = member.modifiers?.some(
1614
- (m) => m.kind === ts.SyntaxKind.AsyncKeyword
1615
- ) ?? false;
1616
-
1617
- const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(
1618
- member.getStart(sourceFile)
1619
- );
1620
- const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(
1621
- member.getEnd()
1622
- );
1623
-
1624
- methods.push({
1625
- name: methodName,
1626
- parameters,
1627
- returnType,
1628
- isAsync,
1629
- isExported: false,
1630
- complexity: this.calculateCyclomaticComplexity(member),
1631
- startLine: startLine + 1,
1632
- endLine: endLine + 1,
1633
- body: member.body?.getText(sourceFile),
1634
- });
1635
- } else if (ts.isConstructorDeclaration(member)) {
1636
- hasConstructor = true;
1637
- } else if (ts.isPropertyDeclaration(member)) {
1638
- const propName = member.name.getText(sourceFile);
1639
- const propType = member.type?.getText(sourceFile);
1640
- const isPrivate = member.modifiers?.some(
1641
- (m) => m.kind === ts.SyntaxKind.PrivateKeyword
1642
- ) ?? false;
1643
- const isReadonly = member.modifiers?.some(
1644
- (m) => m.kind === ts.SyntaxKind.ReadonlyKeyword
1645
- ) ?? false;
1646
-
1647
- properties.push({
1648
- name: propName,
1649
- type: propType,
1650
- isPrivate,
1651
- isReadonly,
1652
- });
1653
- }
1654
- }
1655
-
1656
- const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(
1657
- node.getStart(sourceFile)
1658
- );
1659
- const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(
1660
- node.getEnd()
1661
- );
1662
-
1663
- return {
1664
- name,
1665
- methods,
1666
- properties,
1667
- isExported,
1668
- hasConstructor,
1669
- startLine: startLine + 1,
1670
- endLine: endLine + 1,
1671
- };
1672
- }
1673
-
1674
- /**
1675
- * Extract parameter information
1676
- */
1677
- private extractParameters(
1678
- params: ts.NodeArray<ts.ParameterDeclaration>,
1679
- sourceFile: ts.SourceFile
1680
- ): ParameterInfo[] {
1681
- return params.map((param) => ({
1682
- name: param.name.getText(sourceFile),
1683
- type: param.type?.getText(sourceFile),
1684
- optional: param.questionToken !== undefined,
1685
- defaultValue: param.initializer?.getText(sourceFile),
1686
- }));
1687
- }
1688
-
1689
- /**
1690
- * Calculate cyclomatic complexity of a node
1691
- */
1692
- calculateCyclomaticComplexity(node: ts.Node): number {
1693
- let complexity = 1;
1694
-
1695
- const visit = (n: ts.Node): void => {
1696
- switch (n.kind) {
1697
- case ts.SyntaxKind.IfStatement:
1698
- case ts.SyntaxKind.ForStatement:
1699
- case ts.SyntaxKind.ForInStatement:
1700
- case ts.SyntaxKind.ForOfStatement:
1701
- case ts.SyntaxKind.WhileStatement:
1702
- case ts.SyntaxKind.DoStatement:
1703
- case ts.SyntaxKind.CaseClause:
1704
- case ts.SyntaxKind.CatchClause:
1705
- case ts.SyntaxKind.ConditionalExpression:
1706
- case ts.SyntaxKind.QuestionQuestionToken:
1707
- complexity++;
1708
- break;
1709
- case ts.SyntaxKind.BinaryExpression:
1710
- const binary = n as ts.BinaryExpression;
1711
- if (
1712
- binary.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
1713
- binary.operatorToken.kind === ts.SyntaxKind.BarBarToken
1714
- ) {
1715
- complexity++;
1716
- }
1717
- break;
1718
- }
1719
- ts.forEachChild(n, visit);
1720
- };
1721
-
1722
- ts.forEachChild(node, visit);
1723
- return complexity;
1724
- }
1725
- }