@yasserkhanorg/e2e-agents 0.3.2

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 (221) hide show
  1. package/LICENSE +168 -0
  2. package/README.md +620 -0
  3. package/dist/agent/analysis.d.ts +62 -0
  4. package/dist/agent/analysis.d.ts.map +1 -0
  5. package/dist/agent/analysis.js +292 -0
  6. package/dist/agent/blast_radius.d.ts +4 -0
  7. package/dist/agent/blast_radius.d.ts.map +1 -0
  8. package/dist/agent/blast_radius.js +37 -0
  9. package/dist/agent/cache_utils.d.ts +38 -0
  10. package/dist/agent/cache_utils.d.ts.map +1 -0
  11. package/dist/agent/cache_utils.js +67 -0
  12. package/dist/agent/config.d.ts +148 -0
  13. package/dist/agent/config.d.ts.map +1 -0
  14. package/dist/agent/config.js +640 -0
  15. package/dist/agent/dependency_graph.d.ts +14 -0
  16. package/dist/agent/dependency_graph.d.ts.map +1 -0
  17. package/dist/agent/dependency_graph.js +227 -0
  18. package/dist/agent/feedback.d.ts +55 -0
  19. package/dist/agent/feedback.d.ts.map +1 -0
  20. package/dist/agent/feedback.js +257 -0
  21. package/dist/agent/flags.d.ts +23 -0
  22. package/dist/agent/flags.d.ts.map +1 -0
  23. package/dist/agent/flags.js +171 -0
  24. package/dist/agent/flow_catalog.d.ts +25 -0
  25. package/dist/agent/flow_catalog.d.ts.map +1 -0
  26. package/dist/agent/flow_catalog.js +106 -0
  27. package/dist/agent/flow_mapping.d.ts +10 -0
  28. package/dist/agent/flow_mapping.d.ts.map +1 -0
  29. package/dist/agent/flow_mapping.js +84 -0
  30. package/dist/agent/framework.d.ts +13 -0
  31. package/dist/agent/framework.d.ts.map +1 -0
  32. package/dist/agent/framework.js +149 -0
  33. package/dist/agent/gap_suggestions.d.ts +14 -0
  34. package/dist/agent/gap_suggestions.d.ts.map +1 -0
  35. package/dist/agent/gap_suggestions.js +101 -0
  36. package/dist/agent/generator.d.ts +10 -0
  37. package/dist/agent/generator.d.ts.map +1 -0
  38. package/dist/agent/generator.js +115 -0
  39. package/dist/agent/git.d.ts +11 -0
  40. package/dist/agent/git.d.ts.map +1 -0
  41. package/dist/agent/git.js +90 -0
  42. package/dist/agent/handoff.d.ts +22 -0
  43. package/dist/agent/handoff.d.ts.map +1 -0
  44. package/dist/agent/handoff.js +180 -0
  45. package/dist/agent/impact-analyzer.d.ts +114 -0
  46. package/dist/agent/impact-analyzer.d.ts.map +1 -0
  47. package/dist/agent/impact-analyzer.js +557 -0
  48. package/dist/agent/index.d.ts +21 -0
  49. package/dist/agent/index.d.ts.map +1 -0
  50. package/dist/agent/index.js +38 -0
  51. package/dist/agent/model-router.d.ts +57 -0
  52. package/dist/agent/model-router.d.ts.map +1 -0
  53. package/dist/agent/model-router.js +154 -0
  54. package/dist/agent/operational_insights.d.ts +41 -0
  55. package/dist/agent/operational_insights.d.ts.map +1 -0
  56. package/dist/agent/operational_insights.js +126 -0
  57. package/dist/agent/pipeline.d.ts +23 -0
  58. package/dist/agent/pipeline.d.ts.map +1 -0
  59. package/dist/agent/pipeline.js +609 -0
  60. package/dist/agent/plan.d.ts +91 -0
  61. package/dist/agent/plan.d.ts.map +1 -0
  62. package/dist/agent/plan.js +331 -0
  63. package/dist/agent/playwright_report.d.ts +8 -0
  64. package/dist/agent/playwright_report.d.ts.map +1 -0
  65. package/dist/agent/playwright_report.js +126 -0
  66. package/dist/agent/report-generator.d.ts +24 -0
  67. package/dist/agent/report-generator.d.ts.map +1 -0
  68. package/dist/agent/report-generator.js +250 -0
  69. package/dist/agent/report.d.ts +81 -0
  70. package/dist/agent/report.d.ts.map +1 -0
  71. package/dist/agent/report.js +147 -0
  72. package/dist/agent/runner.d.ts +7 -0
  73. package/dist/agent/runner.d.ts.map +1 -0
  74. package/dist/agent/runner.js +576 -0
  75. package/dist/agent/selectors.d.ts +10 -0
  76. package/dist/agent/selectors.d.ts.map +1 -0
  77. package/dist/agent/selectors.js +75 -0
  78. package/dist/agent/spec-bridge.d.ts +101 -0
  79. package/dist/agent/spec-bridge.d.ts.map +1 -0
  80. package/dist/agent/spec-bridge.js +273 -0
  81. package/dist/agent/spec-builder.d.ts +102 -0
  82. package/dist/agent/spec-builder.d.ts.map +1 -0
  83. package/dist/agent/spec-builder.js +273 -0
  84. package/dist/agent/subsystem_risk.d.ts +23 -0
  85. package/dist/agent/subsystem_risk.d.ts.map +1 -0
  86. package/dist/agent/subsystem_risk.js +207 -0
  87. package/dist/agent/telemetry.d.ts +84 -0
  88. package/dist/agent/telemetry.d.ts.map +1 -0
  89. package/dist/agent/telemetry.js +220 -0
  90. package/dist/agent/test_path.d.ts +2 -0
  91. package/dist/agent/test_path.d.ts.map +1 -0
  92. package/dist/agent/test_path.js +23 -0
  93. package/dist/agent/tests.d.ts +18 -0
  94. package/dist/agent/tests.d.ts.map +1 -0
  95. package/dist/agent/tests.js +106 -0
  96. package/dist/agent/traceability.d.ts +22 -0
  97. package/dist/agent/traceability.d.ts.map +1 -0
  98. package/dist/agent/traceability.js +183 -0
  99. package/dist/agent/traceability_capture.d.ts +18 -0
  100. package/dist/agent/traceability_capture.d.ts.map +1 -0
  101. package/dist/agent/traceability_capture.js +313 -0
  102. package/dist/agent/traceability_ingest.d.ts +21 -0
  103. package/dist/agent/traceability_ingest.d.ts.map +1 -0
  104. package/dist/agent/traceability_ingest.js +237 -0
  105. package/dist/agent/utils.d.ts +13 -0
  106. package/dist/agent/utils.d.ts.map +1 -0
  107. package/dist/agent/utils.js +152 -0
  108. package/dist/agent/validators/selector-validator.d.ts +74 -0
  109. package/dist/agent/validators/selector-validator.d.ts.map +1 -0
  110. package/dist/agent/validators/selector-validator.js +165 -0
  111. package/dist/anthropic_provider.d.ts +65 -0
  112. package/dist/anthropic_provider.d.ts.map +1 -0
  113. package/dist/anthropic_provider.js +332 -0
  114. package/dist/api.d.ts +48 -0
  115. package/dist/api.d.ts.map +1 -0
  116. package/dist/api.js +113 -0
  117. package/dist/base_provider.d.ts +53 -0
  118. package/dist/base_provider.d.ts.map +1 -0
  119. package/dist/base_provider.js +81 -0
  120. package/dist/cli.d.ts +3 -0
  121. package/dist/cli.d.ts.map +1 -0
  122. package/dist/cli.js +843 -0
  123. package/dist/custom_provider.d.ts +20 -0
  124. package/dist/custom_provider.d.ts.map +1 -0
  125. package/dist/custom_provider.js +276 -0
  126. package/dist/e2e-test-gen/index.d.ts +51 -0
  127. package/dist/e2e-test-gen/index.d.ts.map +1 -0
  128. package/dist/e2e-test-gen/index.js +57 -0
  129. package/dist/e2e-test-gen/spec_parser.d.ts +142 -0
  130. package/dist/e2e-test-gen/spec_parser.d.ts.map +1 -0
  131. package/dist/e2e-test-gen/spec_parser.js +786 -0
  132. package/dist/e2e-test-gen/types.d.ts +185 -0
  133. package/dist/e2e-test-gen/types.d.ts.map +1 -0
  134. package/dist/e2e-test-gen/types.js +4 -0
  135. package/dist/esm/agent/analysis.js +287 -0
  136. package/dist/esm/agent/blast_radius.js +34 -0
  137. package/dist/esm/agent/cache_utils.js +63 -0
  138. package/dist/esm/agent/config.js +637 -0
  139. package/dist/esm/agent/dependency_graph.js +224 -0
  140. package/dist/esm/agent/feedback.js +253 -0
  141. package/dist/esm/agent/flags.js +160 -0
  142. package/dist/esm/agent/flow_catalog.js +103 -0
  143. package/dist/esm/agent/flow_mapping.js +81 -0
  144. package/dist/esm/agent/framework.js +145 -0
  145. package/dist/esm/agent/gap_suggestions.js +98 -0
  146. package/dist/esm/agent/generator.js +112 -0
  147. package/dist/esm/agent/git.js +87 -0
  148. package/dist/esm/agent/handoff.js +177 -0
  149. package/dist/esm/agent/impact-analyzer.js +548 -0
  150. package/dist/esm/agent/index.js +22 -0
  151. package/dist/esm/agent/model-router.js +150 -0
  152. package/dist/esm/agent/operational_insights.js +123 -0
  153. package/dist/esm/agent/pipeline.js +605 -0
  154. package/dist/esm/agent/plan.js +324 -0
  155. package/dist/esm/agent/playwright_report.js +123 -0
  156. package/dist/esm/agent/report-generator.js +247 -0
  157. package/dist/esm/agent/report.js +144 -0
  158. package/dist/esm/agent/runner.js +572 -0
  159. package/dist/esm/agent/selectors.js +71 -0
  160. package/dist/esm/agent/spec-bridge.js +267 -0
  161. package/dist/esm/agent/spec-builder.js +267 -0
  162. package/dist/esm/agent/subsystem_risk.js +204 -0
  163. package/dist/esm/agent/telemetry.js +216 -0
  164. package/dist/esm/agent/test_path.js +20 -0
  165. package/dist/esm/agent/tests.js +101 -0
  166. package/dist/esm/agent/traceability.js +180 -0
  167. package/dist/esm/agent/traceability_capture.js +310 -0
  168. package/dist/esm/agent/traceability_ingest.js +234 -0
  169. package/dist/esm/agent/utils.js +138 -0
  170. package/dist/esm/agent/validators/selector-validator.js +160 -0
  171. package/dist/esm/anthropic_provider.js +324 -0
  172. package/dist/esm/api.js +105 -0
  173. package/dist/esm/base_provider.js +77 -0
  174. package/dist/esm/cli.js +841 -0
  175. package/dist/esm/custom_provider.js +272 -0
  176. package/dist/esm/e2e-test-gen/index.js +50 -0
  177. package/dist/esm/e2e-test-gen/spec_parser.js +782 -0
  178. package/dist/esm/e2e-test-gen/types.js +3 -0
  179. package/dist/esm/index.js +16 -0
  180. package/dist/esm/logger.js +89 -0
  181. package/dist/esm/mcp-server.js +465 -0
  182. package/dist/esm/ollama_provider.js +300 -0
  183. package/dist/esm/openai_provider.js +242 -0
  184. package/dist/esm/package.json +3 -0
  185. package/dist/esm/plan-and-test-constants.js +126 -0
  186. package/dist/esm/provider_factory.js +336 -0
  187. package/dist/esm/provider_interface.js +23 -0
  188. package/dist/esm/provider_utils.js +96 -0
  189. package/dist/index.d.ts +31 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +41 -0
  192. package/dist/logger.d.ts +23 -0
  193. package/dist/logger.d.ts.map +1 -0
  194. package/dist/logger.js +93 -0
  195. package/dist/mcp-server.d.ts +35 -0
  196. package/dist/mcp-server.d.ts.map +1 -0
  197. package/dist/mcp-server.js +469 -0
  198. package/dist/ollama_provider.d.ts +65 -0
  199. package/dist/ollama_provider.d.ts.map +1 -0
  200. package/dist/ollama_provider.js +308 -0
  201. package/dist/openai_provider.d.ts +23 -0
  202. package/dist/openai_provider.d.ts.map +1 -0
  203. package/dist/openai_provider.js +250 -0
  204. package/dist/plan-and-test-constants.d.ts +110 -0
  205. package/dist/plan-and-test-constants.d.ts.map +1 -0
  206. package/dist/plan-and-test-constants.js +132 -0
  207. package/dist/provider_factory.d.ts +99 -0
  208. package/dist/provider_factory.d.ts.map +1 -0
  209. package/dist/provider_factory.js +341 -0
  210. package/dist/provider_interface.d.ts +358 -0
  211. package/dist/provider_interface.d.ts.map +1 -0
  212. package/dist/provider_interface.js +28 -0
  213. package/dist/provider_utils.d.ts +39 -0
  214. package/dist/provider_utils.d.ts.map +1 -0
  215. package/dist/provider_utils.js +103 -0
  216. package/package.json +101 -0
  217. package/schemas/gap.schema.json +18 -0
  218. package/schemas/impact.schema.json +418 -0
  219. package/schemas/plan.schema.json +285 -0
  220. package/schemas/subsystem-risk-map.schema.json +62 -0
  221. package/schemas/traceability-input.schema.json +122 -0
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.ModelRouter = void 0;
6
+ const MODEL_RATES = {
7
+ 'claude-haiku-4-0-20250430': 0.25 / 1000000,
8
+ 'claude-sonnet-4-5-20250929': 3 / 1000000,
9
+ 'claude-opus-4-6-20250820': 15 / 1000000,
10
+ };
11
+ class ModelRouter {
12
+ constructor(config = {}) {
13
+ this.modelConfig = {
14
+ simpleModel: config.simpleModel || 'claude-haiku-4-0-20250430',
15
+ moderateModel: config.moderateModel || 'claude-sonnet-4-5-20250929',
16
+ complexModel: config.complexModel || 'claude-opus-4-6-20250820',
17
+ criticalModel: config.criticalModel || 'claude-opus-4-6-20250820',
18
+ };
19
+ }
20
+ /**
21
+ * Classify task complexity based on operation, attempt number, and context
22
+ */
23
+ classifyTask(context) {
24
+ // Healing: Haiku for attempts 1-2, Sonnet for attempt 3
25
+ if (context.operation === 'heal') {
26
+ if (context.attemptNumber && context.attemptNumber <= 2) {
27
+ // First two healing attempts use simple classification
28
+ return {
29
+ type: 'simple',
30
+ confidence: 95,
31
+ reasoning: `Healing attempt ${context.attemptNumber}/3 - re-exploration with targeted fixes`,
32
+ };
33
+ }
34
+ // Final healing attempt is more complex
35
+ return {
36
+ type: 'moderate',
37
+ confidence: 90,
38
+ reasoning: 'Final healing attempt - may need comprehensive refactoring',
39
+ };
40
+ }
41
+ // Validation: Always simple (use Haiku)
42
+ if (context.operation === 'validate') {
43
+ return {
44
+ type: 'simple',
45
+ confidence: 100,
46
+ reasoning: 'Selector/code validation is lightweight',
47
+ };
48
+ }
49
+ // Scoring: Simple (quick analysis)
50
+ if (context.operation === 'score') {
51
+ return {
52
+ type: 'simple',
53
+ confidence: 95,
54
+ reasoning: 'Test quality scoring via static analysis',
55
+ };
56
+ }
57
+ // Exploration: Simple (just navigation and snapshot)
58
+ if (context.operation === 'explore') {
59
+ return {
60
+ type: 'simple',
61
+ confidence: 90,
62
+ reasoning: 'UI exploration is mostly navigation',
63
+ };
64
+ }
65
+ // Generation: Varies by UI map coverage
66
+ if (context.operation === 'generate') {
67
+ // Strong signal: Use Sonnet but can optimize
68
+ if (context.uiMapCoverage && context.uiMapCoverage >= 75) {
69
+ return {
70
+ type: 'moderate',
71
+ confidence: 90,
72
+ reasoning: `Strong UI signal (${context.uiMapCoverage}% coverage) - moderate complexity generation`,
73
+ };
74
+ }
75
+ // Moderate signal: Use Sonnet
76
+ if (context.uiMapCoverage && context.uiMapCoverage >= 50) {
77
+ return {
78
+ type: 'moderate',
79
+ confidence: 75,
80
+ reasoning: `Moderate UI signal (${context.uiMapCoverage}% coverage) - standard generation`,
81
+ };
82
+ }
83
+ // Weak signal: Complex task (need better reasoning)
84
+ if (context.uiMapCoverage && context.uiMapCoverage < 50) {
85
+ return {
86
+ type: 'complex',
87
+ confidence: 70,
88
+ reasoning: `Weak UI signal (${context.uiMapCoverage}% coverage) - requires advanced reasoning`,
89
+ };
90
+ }
91
+ // Unknown coverage: Assume moderate
92
+ return {
93
+ type: 'moderate',
94
+ confidence: 50,
95
+ reasoning: 'Generation with unknown UI coverage - use standard model',
96
+ };
97
+ }
98
+ // Default to moderate
99
+ return {
100
+ type: 'moderate',
101
+ confidence: 50,
102
+ reasoning: 'Unknown operation - defaulting to moderate complexity',
103
+ };
104
+ }
105
+ /**
106
+ * Select appropriate model based on task complexity
107
+ */
108
+ selectModel(complexity) {
109
+ switch (complexity.type) {
110
+ case 'simple':
111
+ return this.modelConfig.simpleModel;
112
+ case 'moderate':
113
+ return this.modelConfig.moderateModel;
114
+ case 'complex':
115
+ return this.modelConfig.complexModel;
116
+ case 'critical':
117
+ return this.modelConfig.criticalModel;
118
+ }
119
+ }
120
+ /**
121
+ * Get estimated cost for a task
122
+ */
123
+ estimateCost(complexity, estimatedTokens = 5000) {
124
+ const model = this.selectModel(complexity);
125
+ const rate = MODEL_RATES[model] || 0.003 / 1000000;
126
+ return estimatedTokens * rate;
127
+ }
128
+ /**
129
+ * Get cost savings vs always using Sonnet
130
+ */
131
+ estimateSavings(complexity, estimatedTokens = 5000) {
132
+ const selectedModel = this.selectModel(complexity);
133
+ const selectedRate = MODEL_RATES[selectedModel] || 0.003 / 1000000;
134
+ const sonnetRate = MODEL_RATES['claude-sonnet-4-5-20250929'];
135
+ const selectedCost = estimatedTokens * selectedRate;
136
+ const sonnetCost = estimatedTokens * sonnetRate;
137
+ const savedCost = sonnetCost - selectedCost;
138
+ const savingsPercent = (savedCost / sonnetCost) * 100;
139
+ return { savedCost, savingsPercent };
140
+ }
141
+ /**
142
+ * Format complexity for logging
143
+ */
144
+ formatComplexity(complexity, tokensUsed) {
145
+ const model = this.selectModel(complexity);
146
+ const modelShort = model.includes('haiku') ? 'Haiku' : model.includes('sonnet') ? 'Sonnet' : 'Opus';
147
+ const confidence = `${complexity.confidence}%`;
148
+ const cost = tokensUsed
149
+ ? ` ($${(tokensUsed * (MODEL_RATES[model] || 0)).toFixed(4)})`
150
+ : '';
151
+ return `${complexity.type.toUpperCase()}/${modelShort}/${confidence}${cost} - ${complexity.reasoning}`;
152
+ }
153
+ }
154
+ exports.ModelRouter = ModelRouter;
@@ -0,0 +1,41 @@
1
+ import type { PlanReport } from './plan.js';
2
+ import type { CalibrationSummary } from './feedback.js';
3
+ export interface FlakyTestRecord {
4
+ test: string;
5
+ flakeRate: number;
6
+ flakeRate7d?: number;
7
+ flakeRate30d?: number;
8
+ trend?: 'up' | 'down' | 'stable';
9
+ subsystem?: string;
10
+ owners?: string[];
11
+ quarantine?: boolean;
12
+ quarantineState?: 'none' | 'active' | 'retire-candidate';
13
+ lastFailureAt?: string;
14
+ }
15
+ export interface FlakyManifest {
16
+ schemaVersion?: string;
17
+ tests: FlakyTestRecord[];
18
+ }
19
+ export interface QualityGateRecord {
20
+ name: string;
21
+ status: 'pass' | 'warn' | 'fail';
22
+ details?: string;
23
+ }
24
+ export interface QualityGateManifest {
25
+ schemaVersion?: string;
26
+ gates: QualityGateRecord[];
27
+ }
28
+ export interface OperationalInsights {
29
+ flaky?: {
30
+ highRiskRecommendedTests: FlakyTestRecord[];
31
+ quarantinedRecommendedTests: string[];
32
+ ownerMentions?: string[];
33
+ };
34
+ qualityGates?: {
35
+ failed: QualityGateRecord[];
36
+ warnings: QualityGateRecord[];
37
+ };
38
+ calibration?: CalibrationSummary['overall'];
39
+ }
40
+ export declare function applyOperationalInsights(plan: PlanReport, appRoot: string): PlanReport;
41
+ //# sourceMappingURL=operational_insights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operational_insights.d.ts","sourceRoot":"","sources":["../../src/agent/operational_insights.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,kBAAkB,CAAC;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE;QACJ,wBAAwB,EAAE,eAAe,EAAE,CAAC;QAC5C,2BAA2B,EAAE,MAAM,EAAE,CAAC;QACtC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,YAAY,CAAC,EAAE;QACX,MAAM,EAAE,iBAAiB,EAAE,CAAC;QAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;KACjC,CAAC;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CAC/C;AA2CD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CA4FtF"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.applyOperationalInsights = applyOperationalInsights;
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ const test_path_js_1 = require("./test_path.js");
9
+ function readJson(path) {
10
+ if (!(0, fs_1.existsSync)(path)) {
11
+ return null;
12
+ }
13
+ try {
14
+ return JSON.parse((0, fs_1.readFileSync)(path, 'utf-8'));
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ function normalizeTestName(test) {
21
+ return test.replace(/ \(flags:.*\)$/, '').trim();
22
+ }
23
+ function subsystemForTest(test) {
24
+ return (0, test_path_js_1.inferSubsystemFromTestPath)(test);
25
+ }
26
+ function riskyRate(entry) {
27
+ if (entry.flakeRate30d !== undefined) {
28
+ return entry.flakeRate30d;
29
+ }
30
+ return entry.flakeRate;
31
+ }
32
+ function loadFlakyManifest(appRoot) {
33
+ const path = (0, path_1.join)(appRoot, '.e2e-ai-agents', 'flaky-tests.json');
34
+ return readJson(path);
35
+ }
36
+ function loadQualityGates(appRoot) {
37
+ const path = (0, path_1.join)(appRoot, '.e2e-ai-agents', 'quality-gates.json');
38
+ return readJson(path);
39
+ }
40
+ function loadCalibration(appRoot) {
41
+ const path = (0, path_1.join)(appRoot, '.e2e-ai-agents', 'calibration.json');
42
+ return readJson(path);
43
+ }
44
+ function applyOperationalInsights(plan, appRoot) {
45
+ const enhanced = { ...plan };
46
+ const insights = {};
47
+ const flaky = loadFlakyManifest(appRoot);
48
+ if (flaky && Array.isArray(flaky.tests)) {
49
+ const recommended = new Set(plan.recommendedTests.map(normalizeTestName));
50
+ const risky = flaky.tests
51
+ .filter((entry) => recommended.has(normalizeTestName(entry.test)) && riskyRate(entry) >= 0.2)
52
+ .sort((a, b) => riskyRate(b) - riskyRate(a))
53
+ .slice(0, 10);
54
+ const quarantined = risky.filter((entry) => entry.quarantine).map((entry) => entry.test);
55
+ const owners = Array.from(new Set(risky
56
+ .flatMap((entry) => entry.owners || [])
57
+ .filter(Boolean)));
58
+ insights.flaky = {
59
+ highRiskRecommendedTests: risky,
60
+ quarantinedRecommendedTests: quarantined,
61
+ ownerMentions: owners,
62
+ };
63
+ if (quarantined.length > 0) {
64
+ enhanced.reasons = [...enhanced.reasons, `Quarantined flaky tests in recommendation: ${quarantined.join(', ')}`];
65
+ }
66
+ if (owners.length > 0) {
67
+ enhanced.reasons = [...enhanced.reasons, `Subsystem owners to notify for flaky risk: ${owners.join(', ')}`];
68
+ }
69
+ }
70
+ const gates = loadQualityGates(appRoot);
71
+ if (gates && Array.isArray(gates.gates)) {
72
+ const failed = gates.gates.filter((gate) => gate.status === 'fail');
73
+ const warnings = gates.gates.filter((gate) => gate.status === 'warn');
74
+ insights.qualityGates = { failed, warnings };
75
+ if (failed.length > 0 && enhanced.runSet !== 'full') {
76
+ enhanced.runSet = 'full';
77
+ enhanced.reasons = [...enhanced.reasons, `Quality gates failed: ${failed.map((gate) => gate.name).join(', ')}`];
78
+ enhanced.policy.triggeredRules = [...new Set([...enhanced.policy.triggeredRules, 'quality-gate-failed'])];
79
+ enhanced.decision = {
80
+ action: 'run-now',
81
+ title: 'Run now',
82
+ summary: 'Quality gate failures detected. Full suite is required before merge.',
83
+ };
84
+ }
85
+ }
86
+ const calibration = loadCalibration(appRoot);
87
+ if (calibration) {
88
+ insights.calibration = calibration.overall;
89
+ if (calibration.overall.falseNegativeRate >= 0.2 && enhanced.runSet !== 'full') {
90
+ enhanced.runSet = 'full';
91
+ enhanced.reasons = [...enhanced.reasons, 'Historical false-negative rate is high; escalating to full suite.'];
92
+ enhanced.policy.triggeredRules = [...new Set([...enhanced.policy.triggeredRules, 'historical-fnr-high'])];
93
+ }
94
+ const recommendedSubsystems = Array.from(new Set(plan.recommendedTests.map(subsystemForTest)));
95
+ const highRiskSubsystems = recommendedSubsystems
96
+ .map((subsystem) => {
97
+ const metric = calibration.bySubsystem[subsystem];
98
+ if (!metric) {
99
+ return null;
100
+ }
101
+ if (metric.samples < 5) {
102
+ return null;
103
+ }
104
+ if (metric.recent30d.falseNegativeRate >= 0.2 || metric.falseNegativeRate >= 0.25) {
105
+ return { subsystem, fnr: metric.recent30d.falseNegativeRate || metric.falseNegativeRate };
106
+ }
107
+ return null;
108
+ })
109
+ .filter(Boolean);
110
+ if (highRiskSubsystems.length > 0 && enhanced.runSet !== 'full') {
111
+ enhanced.runSet = 'full';
112
+ enhanced.reasons = [
113
+ ...enhanced.reasons,
114
+ `Historical subsystem false-negative risk is high: ${highRiskSubsystems.map((entry) => `${entry.subsystem}(${entry.fnr})`).join(', ')}`,
115
+ ];
116
+ enhanced.policy.triggeredRules = [...new Set([...enhanced.policy.triggeredRules, 'subsystem-fnr-high'])];
117
+ enhanced.decision = {
118
+ action: 'run-now',
119
+ title: 'Run now',
120
+ summary: 'Subsystem calibration risk is high. Full suite is required before merge.',
121
+ };
122
+ }
123
+ }
124
+ enhanced.insights = insights;
125
+ return enhanced;
126
+ }
@@ -0,0 +1,23 @@
1
+ import type { PipelineConfig } from './config.js';
2
+ import type { FlowImpact } from './analysis.js';
3
+ export interface PipelineResult {
4
+ flowId: string;
5
+ flowName: string;
6
+ generatedDir: string;
7
+ generateStatus: 'success' | 'skipped' | 'failed';
8
+ healStatus?: 'success' | 'skipped' | 'failed';
9
+ error?: string;
10
+ }
11
+ export interface PipelineSummary {
12
+ runner: 'e2e-test-gen' | 'package-native' | 'unknown';
13
+ results: PipelineResult[];
14
+ warnings: string[];
15
+ }
16
+ export interface SpecHealTarget {
17
+ specPath: string;
18
+ status?: 'failed' | 'flaky';
19
+ reason?: string;
20
+ }
21
+ export declare function runTargetedSpecHeal(testsRoot: string, targets: SpecHealTarget[], pipeline: PipelineConfig): PipelineSummary;
22
+ export declare function runPlaywrightPipeline(testsRoot: string, flows: FlowImpact[], pipeline: PipelineConfig): PipelineSummary;
23
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/agent/pipeline.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACtD,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAmeD,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EAAE,EACzB,QAAQ,EAAE,cAAc,GACzB,eAAe,CAsFjB;AAwBD,wBAAgB,qBAAqB,CACjC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EAAE,EACnB,QAAQ,EAAE,cAAc,GACzB,eAAe,CAyHjB"}