@agentic-qe/v3 3.0.0-alpha.5 → 3.0.0-alpha.7

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 (609) 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 +8 -8
  149. package/dist/init/agents-installer.js +4 -4
  150. package/dist/init/agents-installer.js.map +1 -1
  151. package/dist/init/skills-installer.js +4 -4
  152. package/dist/init/skills-installer.js.map +1 -1
  153. package/package.json +8 -2
  154. package/docs/analysis/V3-INIT-REQUIREMENTS-ANALYSIS.md +0 -352
  155. package/implementation/README.md +0 -90
  156. package/implementation/adrs/ADR-030-coherence-gated-quality-gates.md +0 -312
  157. package/implementation/adrs/ADR-031-strange-loop-self-awareness.md +0 -484
  158. package/implementation/adrs/ADR-032-time-crystal-scheduling.md +0 -530
  159. package/implementation/adrs/ADR-033-early-exit-testing.md +0 -634
  160. package/implementation/adrs/ADR-034-neural-topology-optimizer.md +0 -589
  161. package/implementation/adrs/ADR-035-causal-discovery.md +0 -610
  162. package/implementation/adrs/ADR-036-result-persistence.md +0 -326
  163. package/implementation/adrs/ADR-037-v3-qe-agent-naming.md +0 -105
  164. package/implementation/adrs/ADR-038-v3-qe-memory-unification.md +0 -154
  165. package/implementation/adrs/ADR-039-v3-qe-mcp-optimization.md +0 -179
  166. package/implementation/adrs/ADR-040-v3-qe-agentic-flow-integration.md +0 -240
  167. package/implementation/adrs/ADR-041-v3-qe-cli-enhancement.md +0 -296
  168. package/implementation/adrs/ADR-042-v3-qe-token-tracking-integration.md +0 -517
  169. package/implementation/adrs/v3-adrs.md +0 -2783
  170. package/implementation/planning/AQE-V3-MASTER-PLAN.md +0 -815
  171. package/security-scan-report-2026-01-11.md +0 -410
  172. package/security-verification-report-2026-01-11.md +0 -278
  173. package/src/benchmarks/performance-benchmarks.ts +0 -646
  174. package/src/benchmarks/run-benchmarks.ts +0 -324
  175. package/src/causal-discovery/causal-graph.ts +0 -450
  176. package/src/causal-discovery/discovery-engine.ts +0 -438
  177. package/src/causal-discovery/index.ts +0 -117
  178. package/src/causal-discovery/types.ts +0 -456
  179. package/src/causal-discovery/weight-matrix.ts +0 -453
  180. package/src/cli/commands/qe-tools.ts +0 -634
  181. package/src/cli/index.ts +0 -1976
  182. package/src/compatibility/agent-mapper.ts +0 -291
  183. package/src/compatibility/cli-adapter.ts +0 -277
  184. package/src/compatibility/config-migrator.ts +0 -334
  185. package/src/compatibility/index.ts +0 -112
  186. package/src/compatibility/mcp-adapter.ts +0 -248
  187. package/src/compatibility/types.ts +0 -156
  188. package/src/coordination/claims/claim-repository.ts +0 -636
  189. package/src/coordination/claims/claim-service.ts +0 -675
  190. package/src/coordination/claims/handoff-manager.ts +0 -535
  191. package/src/coordination/claims/index.ts +0 -276
  192. package/src/coordination/claims/interfaces.ts +0 -687
  193. package/src/coordination/claims/work-stealing.ts +0 -436
  194. package/src/coordination/cross-domain-router.ts +0 -492
  195. package/src/coordination/index.ts +0 -127
  196. package/src/coordination/interfaces.ts +0 -691
  197. package/src/coordination/protocol-executor.ts +0 -760
  198. package/src/coordination/protocols/code-intelligence-index.ts +0 -855
  199. package/src/coordination/protocols/defect-investigation.ts +0 -1184
  200. package/src/coordination/protocols/index.ts +0 -11
  201. package/src/coordination/protocols/learning-consolidation.ts +0 -1181
  202. package/src/coordination/protocols/morning-sync.ts +0 -1055
  203. package/src/coordination/protocols/quality-gate.ts +0 -1566
  204. package/src/coordination/protocols/security-audit.ts +0 -1587
  205. package/src/coordination/queen-coordinator.ts +0 -1176
  206. package/src/coordination/result-saver.ts +0 -780
  207. package/src/coordination/task-executor.ts +0 -1146
  208. package/src/coordination/workflow-orchestrator.ts +0 -1917
  209. package/src/domains/chaos-resilience/coordinator.ts +0 -1032
  210. package/src/domains/chaos-resilience/index.ts +0 -143
  211. package/src/domains/chaos-resilience/interfaces.ts +0 -659
  212. package/src/domains/chaos-resilience/plugin.ts +0 -691
  213. package/src/domains/chaos-resilience/services/chaos-engineer.ts +0 -1097
  214. package/src/domains/chaos-resilience/services/index.ts +0 -19
  215. package/src/domains/chaos-resilience/services/load-tester.ts +0 -799
  216. package/src/domains/chaos-resilience/services/performance-profiler.ts +0 -792
  217. package/src/domains/code-intelligence/coordinator.ts +0 -631
  218. package/src/domains/code-intelligence/index.ts +0 -86
  219. package/src/domains/code-intelligence/interfaces.ts +0 -162
  220. package/src/domains/code-intelligence/plugin.ts +0 -451
  221. package/src/domains/code-intelligence/services/impact-analyzer.ts +0 -567
  222. package/src/domains/code-intelligence/services/index.ts +0 -26
  223. package/src/domains/code-intelligence/services/knowledge-graph.ts +0 -1067
  224. package/src/domains/code-intelligence/services/semantic-analyzer.ts +0 -901
  225. package/src/domains/contract-testing/coordinator.ts +0 -1038
  226. package/src/domains/contract-testing/index.ts +0 -122
  227. package/src/domains/contract-testing/interfaces.ts +0 -458
  228. package/src/domains/contract-testing/plugin.ts +0 -746
  229. package/src/domains/contract-testing/services/api-compatibility.ts +0 -748
  230. package/src/domains/contract-testing/services/contract-validator.ts +0 -1700
  231. package/src/domains/contract-testing/services/index.ts +0 -19
  232. package/src/domains/contract-testing/services/schema-validator.ts +0 -1102
  233. package/src/domains/coverage-analysis/coordinator.ts +0 -485
  234. package/src/domains/coverage-analysis/index.ts +0 -114
  235. package/src/domains/coverage-analysis/interfaces.ts +0 -142
  236. package/src/domains/coverage-analysis/plugin.ts +0 -172
  237. package/src/domains/coverage-analysis/services/coverage-analyzer.ts +0 -449
  238. package/src/domains/coverage-analysis/services/coverage-embedder.ts +0 -733
  239. package/src/domains/coverage-analysis/services/coverage-parser.ts +0 -753
  240. package/src/domains/coverage-analysis/services/gap-detector.ts +0 -592
  241. package/src/domains/coverage-analysis/services/hnsw-index.ts +0 -728
  242. package/src/domains/coverage-analysis/services/index.ts +0 -61
  243. package/src/domains/coverage-analysis/services/risk-scorer.ts +0 -540
  244. package/src/domains/coverage-analysis/services/sublinear-analyzer.ts +0 -747
  245. package/src/domains/defect-intelligence/coordinator.ts +0 -635
  246. package/src/domains/defect-intelligence/index.ts +0 -83
  247. package/src/domains/defect-intelligence/interfaces.ts +0 -152
  248. package/src/domains/defect-intelligence/plugin.ts +0 -483
  249. package/src/domains/defect-intelligence/services/causal-root-cause-analyzer.ts +0 -494
  250. package/src/domains/defect-intelligence/services/defect-predictor.ts +0 -852
  251. package/src/domains/defect-intelligence/services/index.ts +0 -37
  252. package/src/domains/defect-intelligence/services/pattern-learner.ts +0 -738
  253. package/src/domains/defect-intelligence/services/root-cause-analyzer.ts +0 -637
  254. package/src/domains/domain-interface.ts +0 -77
  255. package/src/domains/index.ts +0 -23
  256. package/src/domains/learning-optimization/coordinator.ts +0 -1215
  257. package/src/domains/learning-optimization/index.ts +0 -127
  258. package/src/domains/learning-optimization/interfaces.ts +0 -570
  259. package/src/domains/learning-optimization/plugin.ts +0 -851
  260. package/src/domains/learning-optimization/services/index.ts +0 -29
  261. package/src/domains/learning-optimization/services/learning-coordinator.ts +0 -972
  262. package/src/domains/learning-optimization/services/metrics-optimizer.ts +0 -915
  263. package/src/domains/learning-optimization/services/production-intel.ts +0 -971
  264. package/src/domains/learning-optimization/services/transfer-specialist.ts +0 -723
  265. package/src/domains/quality-assessment/coherence/gate-controller.ts +0 -549
  266. package/src/domains/quality-assessment/coherence/index.ts +0 -211
  267. package/src/domains/quality-assessment/coherence/lambda-calculator.ts +0 -384
  268. package/src/domains/quality-assessment/coherence/partition-detector.ts +0 -469
  269. package/src/domains/quality-assessment/coherence/types.ts +0 -384
  270. package/src/domains/quality-assessment/coordinator.ts +0 -605
  271. package/src/domains/quality-assessment/index.ts +0 -97
  272. package/src/domains/quality-assessment/interfaces.ts +0 -152
  273. package/src/domains/quality-assessment/plugin.ts +0 -496
  274. package/src/domains/quality-assessment/services/coherence-gate.ts +0 -358
  275. package/src/domains/quality-assessment/services/deployment-advisor.ts +0 -571
  276. package/src/domains/quality-assessment/services/index.ts +0 -34
  277. package/src/domains/quality-assessment/services/quality-analyzer.ts +0 -670
  278. package/src/domains/quality-assessment/services/quality-gate.ts +0 -384
  279. package/src/domains/requirements-validation/coordinator.ts +0 -812
  280. package/src/domains/requirements-validation/index.ts +0 -92
  281. package/src/domains/requirements-validation/interfaces.ts +0 -303
  282. package/src/domains/requirements-validation/plugin.ts +0 -576
  283. package/src/domains/requirements-validation/services/bdd-scenario-writer.ts +0 -676
  284. package/src/domains/requirements-validation/services/index.ts +0 -20
  285. package/src/domains/requirements-validation/services/requirements-validator.ts +0 -559
  286. package/src/domains/requirements-validation/services/testability-scorer.ts +0 -639
  287. package/src/domains/security-compliance/coordinator.ts +0 -757
  288. package/src/domains/security-compliance/index.ts +0 -120
  289. package/src/domains/security-compliance/interfaces.ts +0 -434
  290. package/src/domains/security-compliance/plugin.ts +0 -509
  291. package/src/domains/security-compliance/services/compliance-validator.ts +0 -1226
  292. package/src/domains/security-compliance/services/index.ts +0 -31
  293. package/src/domains/security-compliance/services/security-auditor.ts +0 -2227
  294. package/src/domains/security-compliance/services/security-scanner.ts +0 -2354
  295. package/src/domains/security-compliance/services/semgrep-integration.ts +0 -289
  296. package/src/domains/test-execution/coordinator.ts +0 -426
  297. package/src/domains/test-execution/index.ts +0 -76
  298. package/src/domains/test-execution/interfaces.ts +0 -119
  299. package/src/domains/test-execution/plugin.ts +0 -208
  300. package/src/domains/test-execution/services/flaky-detector.ts +0 -1240
  301. package/src/domains/test-execution/services/index.ts +0 -8
  302. package/src/domains/test-execution/services/retry-handler.ts +0 -820
  303. package/src/domains/test-execution/services/test-executor.ts +0 -885
  304. package/src/domains/test-generation/coordinator.ts +0 -656
  305. package/src/domains/test-generation/index.ts +0 -77
  306. package/src/domains/test-generation/interfaces.ts +0 -118
  307. package/src/domains/test-generation/plugin.ts +0 -397
  308. package/src/domains/test-generation/services/index.ts +0 -23
  309. package/src/domains/test-generation/services/pattern-matcher.ts +0 -1725
  310. package/src/domains/test-generation/services/test-generator.ts +0 -2750
  311. package/src/domains/visual-accessibility/coordinator.ts +0 -860
  312. package/src/domains/visual-accessibility/index.ts +0 -116
  313. package/src/domains/visual-accessibility/interfaces.ts +0 -435
  314. package/src/domains/visual-accessibility/plugin.ts +0 -568
  315. package/src/domains/visual-accessibility/services/accessibility-tester.ts +0 -982
  316. package/src/domains/visual-accessibility/services/axe-core-audit.ts +0 -630
  317. package/src/domains/visual-accessibility/services/index.ts +0 -28
  318. package/src/domains/visual-accessibility/services/responsive-tester.ts +0 -934
  319. package/src/domains/visual-accessibility/services/visual-tester.ts +0 -458
  320. package/src/early-exit/early-exit-controller.ts +0 -490
  321. package/src/early-exit/early-exit-decision.ts +0 -391
  322. package/src/early-exit/index.ts +0 -115
  323. package/src/early-exit/quality-signal.ts +0 -389
  324. package/src/early-exit/speculative-executor.ts +0 -505
  325. package/src/early-exit/types.ts +0 -407
  326. package/src/feedback/coverage-learner.ts +0 -456
  327. package/src/feedback/feedback-loop.ts +0 -426
  328. package/src/feedback/index.ts +0 -72
  329. package/src/feedback/pattern-promotion.ts +0 -373
  330. package/src/feedback/quality-score-calculator.ts +0 -334
  331. package/src/feedback/test-outcome-tracker.ts +0 -450
  332. package/src/feedback/types.ts +0 -497
  333. package/src/index.ts +0 -224
  334. package/src/init/agents-installer.ts +0 -536
  335. package/src/init/index.ts +0 -80
  336. package/src/init/init-wizard.ts +0 -1061
  337. package/src/init/project-analyzer.ts +0 -696
  338. package/src/init/self-configurator.ts +0 -488
  339. package/src/init/skills-installer.ts +0 -467
  340. package/src/init/types.ts +0 -432
  341. package/src/integrations/ruvector/ast-complexity.ts +0 -470
  342. package/src/integrations/ruvector/coverage-router.ts +0 -594
  343. package/src/integrations/ruvector/diff-risk-classifier.ts +0 -759
  344. package/src/integrations/ruvector/fallback.ts +0 -942
  345. package/src/integrations/ruvector/graph-boundaries.ts +0 -809
  346. package/src/integrations/ruvector/index.ts +0 -363
  347. package/src/integrations/ruvector/interfaces.ts +0 -609
  348. package/src/integrations/ruvector/q-learning-router.ts +0 -550
  349. package/src/kernel/agent-coordinator.ts +0 -165
  350. package/src/kernel/agentdb-backend.ts +0 -504
  351. package/src/kernel/event-bus.ts +0 -129
  352. package/src/kernel/hybrid-backend.ts +0 -538
  353. package/src/kernel/index.ts +0 -28
  354. package/src/kernel/interfaces.ts +0 -257
  355. package/src/kernel/kernel.ts +0 -285
  356. package/src/kernel/memory-backend.ts +0 -169
  357. package/src/kernel/memory-factory.ts +0 -293
  358. package/src/kernel/plugin-loader.ts +0 -179
  359. package/src/learning/index.ts +0 -219
  360. package/src/learning/pattern-store.ts +0 -990
  361. package/src/learning/qe-guidance.ts +0 -832
  362. package/src/learning/qe-hooks.ts +0 -644
  363. package/src/learning/qe-patterns.ts +0 -449
  364. package/src/learning/qe-reasoning-bank.ts +0 -951
  365. package/src/learning/real-embeddings.ts +0 -277
  366. package/src/learning/real-qe-reasoning-bank.ts +0 -833
  367. package/src/learning/sqlite-persistence.ts +0 -554
  368. package/src/mcp/entry.ts +0 -59
  369. package/src/mcp/handlers/agent-handlers.ts +0 -285
  370. package/src/mcp/handlers/core-handlers.ts +0 -317
  371. package/src/mcp/handlers/domain-handlers.ts +0 -1444
  372. package/src/mcp/handlers/index.ts +0 -57
  373. package/src/mcp/handlers/memory-handlers.ts +0 -338
  374. package/src/mcp/handlers/task-handlers.ts +0 -363
  375. package/src/mcp/index.ts +0 -30
  376. package/src/mcp/metrics/index.ts +0 -14
  377. package/src/mcp/metrics/metrics-collector.ts +0 -503
  378. package/src/mcp/protocol-server.ts +0 -752
  379. package/src/mcp/security/cve-prevention.ts +0 -742
  380. package/src/mcp/security/index.ts +0 -356
  381. package/src/mcp/security/oauth21-provider.ts +0 -821
  382. package/src/mcp/security/rate-limiter.ts +0 -615
  383. package/src/mcp/security/sampling-server.ts +0 -662
  384. package/src/mcp/security/schema-validator.ts +0 -855
  385. package/src/mcp/server.ts +0 -657
  386. package/src/mcp/tool-registry.ts +0 -391
  387. package/src/mcp/tools/base.ts +0 -399
  388. package/src/mcp/tools/chaos-resilience/inject.ts +0 -699
  389. package/src/mcp/tools/code-intelligence/analyze.ts +0 -745
  390. package/src/mcp/tools/contract-testing/validate.ts +0 -708
  391. package/src/mcp/tools/coverage-analysis/index.ts +0 -770
  392. package/src/mcp/tools/defect-intelligence/predict.ts +0 -466
  393. package/src/mcp/tools/index.ts +0 -214
  394. package/src/mcp/tools/learning-optimization/optimize.ts +0 -772
  395. package/src/mcp/tools/quality-assessment/evaluate.ts +0 -385
  396. package/src/mcp/tools/registry.ts +0 -248
  397. package/src/mcp/tools/requirements-validation/validate.ts +0 -394
  398. package/src/mcp/tools/security-compliance/scan.ts +0 -365
  399. package/src/mcp/tools/test-execution/execute.ts +0 -291
  400. package/src/mcp/tools/test-generation/generate.ts +0 -544
  401. package/src/mcp/tools/visual-accessibility/index.ts +0 -791
  402. package/src/mcp/transport/index.ts +0 -31
  403. package/src/mcp/transport/stdio.ts +0 -318
  404. package/src/mcp/types.ts +0 -543
  405. package/src/neural-optimizer/index.ts +0 -111
  406. package/src/neural-optimizer/replay-buffer.ts +0 -455
  407. package/src/neural-optimizer/swarm-topology.ts +0 -508
  408. package/src/neural-optimizer/topology-optimizer.ts +0 -828
  409. package/src/neural-optimizer/types.ts +0 -481
  410. package/src/neural-optimizer/value-network.ts +0 -351
  411. package/src/optimization/auto-tuner.ts +0 -817
  412. package/src/optimization/index.ts +0 -77
  413. package/src/optimization/metric-collectors.ts +0 -474
  414. package/src/optimization/qe-workers.ts +0 -704
  415. package/src/optimization/tuning-algorithm.ts +0 -401
  416. package/src/optimization/types.ts +0 -314
  417. package/src/routing/index.ts +0 -51
  418. package/src/routing/qe-agent-registry.ts +0 -963
  419. package/src/routing/qe-task-router.ts +0 -564
  420. package/src/routing/routing-feedback.ts +0 -365
  421. package/src/routing/types.ts +0 -406
  422. package/src/shared/embeddings/embedding-cache.ts +0 -157
  423. package/src/shared/embeddings/index.ts +0 -50
  424. package/src/shared/embeddings/nomic-embedder.ts +0 -404
  425. package/src/shared/embeddings/ollama-client.ts +0 -195
  426. package/src/shared/embeddings/types.ts +0 -147
  427. package/src/shared/entities/agent.ts +0 -141
  428. package/src/shared/entities/base-entity.ts +0 -79
  429. package/src/shared/entities/index.ts +0 -6
  430. package/src/shared/events/domain-events.ts +0 -259
  431. package/src/shared/events/index.ts +0 -5
  432. package/src/shared/git/git-analyzer.ts +0 -656
  433. package/src/shared/git/index.ts +0 -11
  434. package/src/shared/http/http-client.ts +0 -420
  435. package/src/shared/http/index.ts +0 -13
  436. package/src/shared/index.ts +0 -41
  437. package/src/shared/io/file-reader.ts +0 -525
  438. package/src/shared/io/index.ts +0 -25
  439. package/src/shared/llm/cache.ts +0 -473
  440. package/src/shared/llm/circuit-breaker.ts +0 -369
  441. package/src/shared/llm/cost-tracker.ts +0 -460
  442. package/src/shared/llm/index.ts +0 -140
  443. package/src/shared/llm/interfaces.ts +0 -629
  444. package/src/shared/llm/provider-manager.ts +0 -685
  445. package/src/shared/llm/providers/claude.ts +0 -524
  446. package/src/shared/llm/providers/index.ts +0 -8
  447. package/src/shared/llm/providers/ollama.ts +0 -575
  448. package/src/shared/llm/providers/openai.ts +0 -609
  449. package/src/shared/metrics/code-metrics.ts +0 -520
  450. package/src/shared/metrics/index.ts +0 -23
  451. package/src/shared/metrics/system-metrics.ts +0 -353
  452. package/src/shared/parsers/index.ts +0 -6
  453. package/src/shared/parsers/typescript-parser.ts +0 -841
  454. package/src/shared/security/compliance-patterns.ts +0 -666
  455. package/src/shared/security/index.ts +0 -30
  456. package/src/shared/security/osv-client.ts +0 -468
  457. package/src/shared/types/index.ts +0 -150
  458. package/src/shared/value-objects/index.ts +0 -273
  459. package/src/strange-loop/healing-controller.ts +0 -833
  460. package/src/strange-loop/index.ts +0 -104
  461. package/src/strange-loop/self-model.ts +0 -494
  462. package/src/strange-loop/strange-loop.ts +0 -446
  463. package/src/strange-loop/swarm-observer.ts +0 -448
  464. package/src/strange-loop/topology-analyzer.ts +0 -565
  465. package/src/strange-loop/types.ts +0 -640
  466. package/src/time-crystal/default-phases.ts +0 -520
  467. package/src/time-crystal/index.ts +0 -164
  468. package/src/time-crystal/oscillator.ts +0 -425
  469. package/src/time-crystal/phase-executor.ts +0 -521
  470. package/src/time-crystal/scheduler.ts +0 -1025
  471. package/src/time-crystal/test-runner.ts +0 -787
  472. package/src/time-crystal/types.ts +0 -421
  473. package/src/workers/base-worker.ts +0 -304
  474. package/src/workers/daemon.ts +0 -264
  475. package/src/workers/index.ts +0 -119
  476. package/src/workers/interfaces.ts +0 -393
  477. package/src/workers/worker-manager.ts +0 -424
  478. package/src/workers/workers/compliance-checker.ts +0 -445
  479. package/src/workers/workers/coverage-tracker.ts +0 -344
  480. package/src/workers/workers/defect-predictor.ts +0 -375
  481. package/src/workers/workers/flaky-detector.ts +0 -390
  482. package/src/workers/workers/index.ts +0 -17
  483. package/src/workers/workers/learning-consolidation.ts +0 -442
  484. package/src/workers/workers/performance-baseline.ts +0 -434
  485. package/src/workers/workers/quality-gate.ts +0 -419
  486. package/src/workers/workers/regression-monitor.ts +0 -357
  487. package/src/workers/workers/security-scan.ts +0 -349
  488. package/src/workers/workers/test-health.ts +0 -359
  489. package/tests/integration/code-intelligence/knowledge-graph-real.test.ts +0 -540
  490. package/tests/integration/coordination/cross-domain-router.test.ts +0 -403
  491. package/tests/integration/coordination/protocol-executor.test.ts +0 -454
  492. package/tests/integration/coordination/workflow-orchestrator.test.ts +0 -418
  493. package/tests/integration/feedback/feedback-loop-integration.test.ts +0 -560
  494. package/tests/integration/migration/v2-to-v3-migration.test.ts +0 -471
  495. package/tests/integration/parsers/typescript-parser.test.ts +0 -463
  496. package/tests/integration/security/vulnerability-detection.test.ts +0 -628
  497. package/tests/integration/test-execution/coordinator.test.ts +0 -410
  498. package/tests/integration/test-generation/coordinator.test.ts +0 -361
  499. package/tests/mocks/index.ts +0 -228
  500. package/tests/time-crystal/default-phases.test.ts +0 -476
  501. package/tests/time-crystal/oscillator.test.ts +0 -541
  502. package/tests/time-crystal/phase-executor.test.ts +0 -653
  503. package/tests/time-crystal/scheduler.test.ts +0 -626
  504. package/tests/time-crystal/test-runner.test.ts +0 -594
  505. package/tests/unit/causal-discovery/causal-graph.test.ts +0 -504
  506. package/tests/unit/causal-discovery/causal-root-cause-analyzer.test.ts +0 -347
  507. package/tests/unit/causal-discovery/discovery-engine.test.ts +0 -435
  508. package/tests/unit/causal-discovery/weight-matrix.test.ts +0 -328
  509. package/tests/unit/cli/cli.test.ts +0 -341
  510. package/tests/unit/cli/commands.test.ts +0 -414
  511. package/tests/unit/cli/init-command.test.ts +0 -274
  512. package/tests/unit/cli/migrate-command.test.ts +0 -396
  513. package/tests/unit/coordination/claims/claim-service.test.ts +0 -949
  514. package/tests/unit/coordination/claims/handoff-manager.test.ts +0 -773
  515. package/tests/unit/coordination/claims/work-stealing.test.ts +0 -492
  516. package/tests/unit/coordination/queen-coordinator.test.ts +0 -966
  517. package/tests/unit/coordination/result-saver.test.ts +0 -653
  518. package/tests/unit/coordination/task-executor.test.ts +0 -810
  519. package/tests/unit/domains/chaos-resilience/chaos-engineer.test.ts +0 -484
  520. package/tests/unit/domains/chaos-resilience/load-tester.test.ts +0 -559
  521. package/tests/unit/domains/chaos-resilience/performance-profiler.test.ts +0 -490
  522. package/tests/unit/domains/code-intelligence/impact-analyzer.test.ts +0 -560
  523. package/tests/unit/domains/code-intelligence/knowledge-graph.test.ts +0 -460
  524. package/tests/unit/domains/code-intelligence/semantic-analyzer.test.ts +0 -584
  525. package/tests/unit/domains/contract-testing/api-compatibility.test.ts +0 -483
  526. package/tests/unit/domains/contract-testing/contract-validator.test.ts +0 -370
  527. package/tests/unit/domains/contract-testing/schema-validator.test.ts +0 -610
  528. package/tests/unit/domains/coverage-analysis/coverage-embedder.test.ts +0 -298
  529. package/tests/unit/domains/coverage-analysis/hnsw-index.test.ts +0 -292
  530. package/tests/unit/domains/coverage-analysis/sublinear-analyzer.test.ts +0 -506
  531. package/tests/unit/domains/defect-intelligence/defect-predictor.test.ts +0 -370
  532. package/tests/unit/domains/defect-intelligence/pattern-learner.test.ts +0 -546
  533. package/tests/unit/domains/defect-intelligence/root-cause-analyzer.test.ts +0 -534
  534. package/tests/unit/domains/learning-optimization/learning-coordinator.test.ts +0 -541
  535. package/tests/unit/domains/learning-optimization/metrics-optimizer.test.ts +0 -552
  536. package/tests/unit/domains/learning-optimization/production-intel.test.ts +0 -589
  537. package/tests/unit/domains/learning-optimization/transfer-specialist.test.ts +0 -453
  538. package/tests/unit/domains/quality-assessment/coherence-gate.test.ts +0 -1006
  539. package/tests/unit/domains/quality-assessment/deployment-advisor.test.ts +0 -515
  540. package/tests/unit/domains/quality-assessment/quality-analyzer.test.ts +0 -401
  541. package/tests/unit/domains/quality-assessment/quality-gate.test.ts +0 -324
  542. package/tests/unit/domains/requirements-validation/bdd-scenario-writer.test.ts +0 -479
  543. package/tests/unit/domains/requirements-validation/requirements-validator.test.ts +0 -452
  544. package/tests/unit/domains/requirements-validation/testability-scorer.test.ts +0 -505
  545. package/tests/unit/domains/security-compliance/compliance-validator.test.ts +0 -500
  546. package/tests/unit/domains/security-compliance/security-auditor.test.ts +0 -498
  547. package/tests/unit/domains/security-compliance/security-scanner.test.ts +0 -412
  548. package/tests/unit/domains/visual-accessibility/accessibility-tester.test.ts +0 -432
  549. package/tests/unit/domains/visual-accessibility/responsive-tester.test.ts +0 -506
  550. package/tests/unit/domains/visual-accessibility/visual-tester.test.ts +0 -412
  551. package/tests/unit/early-exit/early-exit-controller.test.ts +0 -548
  552. package/tests/unit/early-exit/early-exit-decision.test.ts +0 -617
  553. package/tests/unit/early-exit/index.test.ts +0 -254
  554. package/tests/unit/early-exit/quality-signal.test.ts +0 -589
  555. package/tests/unit/early-exit/speculative-executor.test.ts +0 -453
  556. package/tests/unit/feedback/coverage-learner.test.ts +0 -288
  557. package/tests/unit/feedback/feedback-loop.test.ts +0 -458
  558. package/tests/unit/feedback/pattern-promotion.test.ts +0 -390
  559. package/tests/unit/feedback/quality-score-calculator.test.ts +0 -364
  560. package/tests/unit/feedback/test-outcome-tracker.test.ts +0 -243
  561. package/tests/unit/init/init-wizard.test.ts +0 -881
  562. package/tests/unit/init/project-analyzer.test.ts +0 -807
  563. package/tests/unit/init/self-configurator.test.ts +0 -493
  564. package/tests/unit/integrations/ruvector/ast-complexity.test.ts +0 -240
  565. package/tests/unit/integrations/ruvector/coverage-router.test.ts +0 -366
  566. package/tests/unit/integrations/ruvector/diff-risk-classifier.test.ts +0 -340
  567. package/tests/unit/integrations/ruvector/graph-boundaries.test.ts +0 -355
  568. package/tests/unit/integrations/ruvector/q-learning-router.test.ts +0 -314
  569. package/tests/unit/kernel/agent-coordinator.test.ts +0 -220
  570. package/tests/unit/kernel/event-bus.test.ts +0 -197
  571. package/tests/unit/learning/qe-reasoning-bank.test.ts +0 -666
  572. package/tests/unit/learning/real-qe-reasoning-bank.benchmark.test.ts +0 -415
  573. package/tests/unit/mcp/mcp-server.test.ts +0 -544
  574. package/tests/unit/mcp/metrics/metrics-collector.test.ts +0 -340
  575. package/tests/unit/mcp/security/cve-prevention.test.ts +0 -512
  576. package/tests/unit/mcp/security/oauth21-provider.test.ts +0 -624
  577. package/tests/unit/mcp/security/rate-limiter.test.ts +0 -410
  578. package/tests/unit/mcp/security/sampling-server.test.ts +0 -420
  579. package/tests/unit/mcp/security/schema-validator.test.ts +0 -494
  580. package/tests/unit/mcp/tools/base.test.ts +0 -336
  581. package/tests/unit/mcp/tools/domain-tools.test.ts +0 -759
  582. package/tests/unit/mcp/tools/registry.test.ts +0 -240
  583. package/tests/unit/neural-optimizer/replay-buffer.test.ts +0 -403
  584. package/tests/unit/neural-optimizer/swarm-topology.test.ts +0 -473
  585. package/tests/unit/neural-optimizer/topology-optimizer.test.ts +0 -595
  586. package/tests/unit/neural-optimizer/value-network.test.ts +0 -343
  587. package/tests/unit/optimization/auto-tuner.test.ts +0 -506
  588. package/tests/unit/optimization/metric-collectors.test.ts +0 -352
  589. package/tests/unit/optimization/qe-workers.test.ts +0 -407
  590. package/tests/unit/optimization/tuning-algorithm.test.ts +0 -467
  591. package/tests/unit/routing/qe-agent-registry.test.ts +0 -229
  592. package/tests/unit/routing/qe-task-router.test.ts +0 -390
  593. package/tests/unit/routing/routing-feedback.test.ts +0 -339
  594. package/tests/unit/shared/embeddings/nomic-embedder.test.ts +0 -419
  595. package/tests/unit/shared/http/http-client.test.ts +0 -719
  596. package/tests/unit/shared/io/file-reader.test.ts +0 -511
  597. package/tests/unit/shared/llm/cache.test.ts +0 -391
  598. package/tests/unit/shared/llm/circuit-breaker.test.ts +0 -293
  599. package/tests/unit/shared/llm/cost-tracker.test.ts +0 -431
  600. package/tests/unit/shared/llm/provider-manager.test.ts +0 -550
  601. package/tests/unit/shared/llm/providers.test.ts +0 -532
  602. package/tests/unit/shared/parsers/typescript-parser.test.ts +0 -693
  603. package/tests/unit/shared/value-objects.test.ts +0 -184
  604. package/tests/unit/strange-loop/strange-loop.test.ts +0 -1170
  605. package/tests/unit/workers/base-worker.test.ts +0 -341
  606. package/tests/unit/workers/daemon.test.ts +0 -291
  607. package/tests/unit/workers/worker-manager.test.ts +0 -284
  608. package/tsconfig.json +0 -32
  609. 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
- }