@yasserkhanorg/e2e-agents 0.3.2 → 0.3.4

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 (87) hide show
  1. package/README.md +29 -20
  2. package/dist/agent/config.d.ts +3 -0
  3. package/dist/agent/config.d.ts.map +1 -1
  4. package/dist/agent/config.js +38 -0
  5. package/dist/agent/operational_insights.d.ts +1 -1
  6. package/dist/agent/operational_insights.d.ts.map +1 -1
  7. package/dist/agent/operational_insights.js +2 -1
  8. package/dist/agent/pipeline.d.ts +8 -1
  9. package/dist/agent/pipeline.d.ts.map +1 -1
  10. package/dist/agent/pipeline.js +844 -33
  11. package/dist/agent/plan.d.ts +39 -0
  12. package/dist/agent/plan.d.ts.map +1 -1
  13. package/dist/agent/plan.js +146 -0
  14. package/dist/agent/report.d.ts +16 -0
  15. package/dist/agent/report.d.ts.map +1 -1
  16. package/dist/agent/report.js +12 -0
  17. package/dist/agent/runner.d.ts.map +1 -1
  18. package/dist/agent/runner.js +66 -11
  19. package/dist/agent/tests.d.ts.map +1 -1
  20. package/dist/agent/tests.js +12 -2
  21. package/dist/api.d.ts.map +1 -1
  22. package/dist/api.js +1 -0
  23. package/dist/cli.js +111 -7
  24. package/dist/esm/agent/config.js +38 -0
  25. package/dist/esm/agent/operational_insights.js +2 -1
  26. package/dist/esm/agent/pipeline.js +844 -33
  27. package/dist/esm/agent/plan.js +145 -1
  28. package/dist/esm/agent/report.js +12 -0
  29. package/dist/esm/agent/runner.js +66 -11
  30. package/dist/esm/agent/tests.js +12 -2
  31. package/dist/esm/api.js +2 -1
  32. package/dist/esm/cli.js +112 -8
  33. package/package.json +1 -1
  34. package/schemas/impact.schema.json +37 -0
  35. package/schemas/plan.schema.json +48 -0
  36. package/dist/agent/cache_utils.d.ts +0 -38
  37. package/dist/agent/cache_utils.d.ts.map +0 -1
  38. package/dist/agent/cache_utils.js +0 -67
  39. package/dist/agent/impact-analyzer.d.ts +0 -114
  40. package/dist/agent/impact-analyzer.d.ts.map +0 -1
  41. package/dist/agent/impact-analyzer.js +0 -557
  42. package/dist/agent/index.d.ts +0 -21
  43. package/dist/agent/index.d.ts.map +0 -1
  44. package/dist/agent/index.js +0 -38
  45. package/dist/agent/model-router.d.ts +0 -57
  46. package/dist/agent/model-router.d.ts.map +0 -1
  47. package/dist/agent/model-router.js +0 -154
  48. package/dist/agent/report-generator.d.ts +0 -24
  49. package/dist/agent/report-generator.d.ts.map +0 -1
  50. package/dist/agent/report-generator.js +0 -250
  51. package/dist/agent/spec-bridge.d.ts +0 -101
  52. package/dist/agent/spec-bridge.d.ts.map +0 -1
  53. package/dist/agent/spec-bridge.js +0 -273
  54. package/dist/agent/spec-builder.d.ts +0 -102
  55. package/dist/agent/spec-builder.d.ts.map +0 -1
  56. package/dist/agent/spec-builder.js +0 -273
  57. package/dist/agent/telemetry.d.ts +0 -84
  58. package/dist/agent/telemetry.d.ts.map +0 -1
  59. package/dist/agent/telemetry.js +0 -220
  60. package/dist/agent/validators/selector-validator.d.ts +0 -74
  61. package/dist/agent/validators/selector-validator.d.ts.map +0 -1
  62. package/dist/agent/validators/selector-validator.js +0 -165
  63. package/dist/e2e-test-gen/index.d.ts +0 -51
  64. package/dist/e2e-test-gen/index.d.ts.map +0 -1
  65. package/dist/e2e-test-gen/index.js +0 -57
  66. package/dist/e2e-test-gen/spec_parser.d.ts +0 -142
  67. package/dist/e2e-test-gen/spec_parser.d.ts.map +0 -1
  68. package/dist/e2e-test-gen/spec_parser.js +0 -786
  69. package/dist/e2e-test-gen/types.d.ts +0 -185
  70. package/dist/e2e-test-gen/types.d.ts.map +0 -1
  71. package/dist/e2e-test-gen/types.js +0 -4
  72. package/dist/esm/agent/cache_utils.js +0 -63
  73. package/dist/esm/agent/impact-analyzer.js +0 -548
  74. package/dist/esm/agent/index.js +0 -22
  75. package/dist/esm/agent/model-router.js +0 -150
  76. package/dist/esm/agent/report-generator.js +0 -247
  77. package/dist/esm/agent/spec-bridge.js +0 -267
  78. package/dist/esm/agent/spec-builder.js +0 -267
  79. package/dist/esm/agent/telemetry.js +0 -216
  80. package/dist/esm/agent/validators/selector-validator.js +0 -160
  81. package/dist/esm/e2e-test-gen/index.js +0 -50
  82. package/dist/esm/e2e-test-gen/spec_parser.js +0 -782
  83. package/dist/esm/e2e-test-gen/types.js +0 -3
  84. package/dist/esm/plan-and-test-constants.js +0 -126
  85. package/dist/plan-and-test-constants.d.ts +0 -110
  86. package/dist/plan-and-test-constants.d.ts.map +0 -1
  87. package/dist/plan-and-test-constants.js +0 -132
@@ -14,6 +14,8 @@ export interface DecisionSummary {
14
14
  }
15
15
  export interface PlanReport {
16
16
  schemaVersion: '1.0.0';
17
+ runId: string;
18
+ sourceRunId?: string;
17
19
  generatedAt: string;
18
20
  source: 'impact';
19
21
  runSet: RecommendedRunSet;
@@ -23,6 +25,13 @@ export interface PlanReport {
23
25
  requiredNewTests: string[];
24
26
  policy: PolicyEvaluation;
25
27
  decision: DecisionSummary;
28
+ enforcement: {
29
+ mode: PolicyConfig['enforcementMode'];
30
+ blockOnActions: CiAction[];
31
+ matchedAction: boolean;
32
+ shouldFail: boolean;
33
+ summary: string;
34
+ };
26
35
  insights?: {
27
36
  flaky?: {
28
37
  highRiskRecommendedTests: Array<{
@@ -79,6 +88,7 @@ export interface PlanReport {
79
88
  warnings: number;
80
89
  };
81
90
  }
91
+ export declare function refreshPlanEnforcement(plan: PlanReport): PlanReport;
82
92
  export declare function buildPlanFromImpactReport(impact: ReportData, policyOverride?: Partial<PolicyConfig>): PlanReport;
83
93
  export declare function attachDeveloperActions(plan: PlanReport, context: {
84
94
  appPath: string;
@@ -87,5 +97,34 @@ export declare function attachDeveloperActions(plan: PlanReport, context: {
87
97
  }): PlanReport;
88
98
  export declare function writePlanReport(appRoot: string, plan: PlanReport): string;
89
99
  export declare function renderCiSummaryMarkdown(plan: PlanReport): string;
100
+ export interface PlanMetricEvent {
101
+ schemaVersion: '1.0.0';
102
+ timestamp: string;
103
+ runId: string;
104
+ sourceRunId?: string;
105
+ action: CiAction;
106
+ runSet: RecommendedRunSet;
107
+ confidence: number;
108
+ changedFiles: number;
109
+ impactedFlows: number;
110
+ uncoveredP0P1Flows: number;
111
+ warnings: number;
112
+ enforcementMode: PolicyConfig['enforcementMode'];
113
+ enforcementShouldFail: boolean;
114
+ }
115
+ export interface PlanMetricsSummary {
116
+ schemaVersion: '1.0.0';
117
+ generatedAt: string;
118
+ totalRuns: number;
119
+ averageConfidence: number;
120
+ byAction: Record<CiAction, number>;
121
+ byRunSet: Record<RecommendedRunSet, number>;
122
+ blockingRecommendations: number;
123
+ blockingRate: number;
124
+ }
125
+ export declare function appendPlanMetrics(appRoot: string, plan: PlanReport): {
126
+ eventsPath: string;
127
+ summaryPath: string;
128
+ };
90
129
  export declare function writeCiSummary(appRoot: string, markdown: string, relativePath?: string): string;
91
130
  //# sourceMappingURL=plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/agent/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/agent/plan.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,12 @@
2
2
  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
3
  // See LICENSE.txt for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.refreshPlanEnforcement = refreshPlanEnforcement;
5
6
  exports.buildPlanFromImpactReport = buildPlanFromImpactReport;
6
7
  exports.attachDeveloperActions = attachDeveloperActions;
7
8
  exports.writePlanReport = writePlanReport;
8
9
  exports.renderCiSummaryMarkdown = renderCiSummaryMarkdown;
10
+ exports.appendPlanMetrics = appendPlanMetrics;
9
11
  exports.writeCiSummary = writeCiSummary;
10
12
  const fs_1 = require("fs");
11
13
  const path_1 = require("path");
@@ -27,6 +29,8 @@ const DEFAULT_POLICY = {
27
29
  '**/*.sql',
28
30
  '**/webhook/**',
29
31
  ],
32
+ enforcementMode: 'advisory',
33
+ blockOnActions: ['must-add-tests'],
30
34
  };
31
35
  function countPriority(flows) {
32
36
  const counts = { p0: 0, p1: 0, p2: 0 };
@@ -172,6 +176,61 @@ function buildDecision(runSet, confidence, impact, policy) {
172
176
  summary: `Execute the ${runSet} suite for this change set.`,
173
177
  };
174
178
  }
179
+ function evaluateEnforcement(decision, policy) {
180
+ const blockOnActions = (policy.blockOnActions && policy.blockOnActions.length > 0)
181
+ ? [...policy.blockOnActions]
182
+ : ['must-add-tests'];
183
+ const matchedAction = blockOnActions.includes(decision.action);
184
+ if (policy.enforcementMode === 'block' && matchedAction) {
185
+ return {
186
+ mode: policy.enforcementMode,
187
+ blockOnActions,
188
+ matchedAction,
189
+ shouldFail: true,
190
+ summary: `Blocking mode active: decision "${decision.action}" is configured to fail CI.`,
191
+ };
192
+ }
193
+ if (policy.enforcementMode === 'warn' && matchedAction) {
194
+ return {
195
+ mode: policy.enforcementMode,
196
+ blockOnActions,
197
+ matchedAction,
198
+ shouldFail: false,
199
+ summary: `Warning mode active: decision "${decision.action}" is advisory-only for CI.`,
200
+ };
201
+ }
202
+ if (policy.enforcementMode === 'block') {
203
+ return {
204
+ mode: policy.enforcementMode,
205
+ blockOnActions,
206
+ matchedAction,
207
+ shouldFail: false,
208
+ summary: `Blocking mode active, but decision "${decision.action}" is not configured for CI failure.`,
209
+ };
210
+ }
211
+ if (policy.enforcementMode === 'warn') {
212
+ return {
213
+ mode: policy.enforcementMode,
214
+ blockOnActions,
215
+ matchedAction,
216
+ shouldFail: false,
217
+ summary: `Warning mode active, but decision "${decision.action}" is not configured for warning.`,
218
+ };
219
+ }
220
+ return {
221
+ mode: policy.enforcementMode,
222
+ blockOnActions,
223
+ matchedAction,
224
+ shouldFail: false,
225
+ summary: 'Advisory mode active: recommendations do not fail CI by default.',
226
+ };
227
+ }
228
+ function refreshPlanEnforcement(plan) {
229
+ return {
230
+ ...plan,
231
+ enforcement: evaluateEnforcement(plan.decision, plan.policy.applied),
232
+ };
233
+ }
175
234
  function buildPlanFromImpactReport(impact, policyOverride) {
176
235
  if (impact.mode !== 'impact') {
177
236
  throw new Error(`Plan generation requires impact report data, received mode=${impact.mode}`);
@@ -181,9 +240,14 @@ function buildPlanFromImpactReport(impact, policyOverride) {
181
240
  const confidence = computeConfidence(impact, p0, p1);
182
241
  const runSet = pickRunSet(impact, p0, confidence, policy);
183
242
  const decision = buildDecision(runSet.runSet, confidence, impact, policy);
243
+ const enforcement = evaluateEnforcement(decision, policy);
184
244
  const requiredNewTests = impact.gaps.map((flow) => `${flow.id}: ${flow.name}`);
245
+ const sourceRunId = impact.runMetadata?.runId;
246
+ const runId = `plan-${sourceRunId || Date.now().toString(36)}`;
185
247
  return {
186
248
  schemaVersion: '1.0.0',
249
+ runId,
250
+ sourceRunId,
187
251
  generatedAt: new Date().toISOString(),
188
252
  source: 'impact',
189
253
  runSet: runSet.runSet,
@@ -197,6 +261,7 @@ function buildPlanFromImpactReport(impact, policyOverride) {
197
261
  applied: policy,
198
262
  },
199
263
  decision,
264
+ enforcement,
200
265
  metrics: {
201
266
  changedFiles: impact.changedFiles.length,
202
267
  impactedFlows: impact.flows.length,
@@ -243,6 +308,8 @@ function renderCiSummaryMarkdown(plan) {
243
308
  lines.push(`- Run set: \`${plan.runSet}\``);
244
309
  lines.push(`- Confidence: \`${plan.confidence}\``);
245
310
  lines.push(`- Summary: ${plan.decision.summary}`);
311
+ lines.push(`- Enforcement: mode=\`${plan.enforcement.mode}\`, shouldFail=\`${plan.enforcement.shouldFail}\``);
312
+ lines.push(`- Enforcement detail: ${plan.enforcement.summary}`);
246
313
  if (plan.policy.triggeredRules.length > 0) {
247
314
  lines.push(`- Policy triggers: ${plan.policy.triggeredRules.join(', ')}`);
248
315
  }
@@ -322,6 +389,85 @@ function renderCiSummaryMarkdown(plan) {
322
389
  }
323
390
  return lines.join('\n');
324
391
  }
392
+ const PLAN_METRICS_EVENTS_PATH = '.e2e-ai-agents/metrics.jsonl';
393
+ const PLAN_METRICS_SUMMARY_PATH = '.e2e-ai-agents/metrics-summary.json';
394
+ function parsePlanMetricLine(line) {
395
+ const trimmed = line.trim();
396
+ if (!trimmed) {
397
+ return null;
398
+ }
399
+ try {
400
+ const parsed = JSON.parse(trimmed);
401
+ if (!parsed || parsed.schemaVersion !== '1.0.0' || typeof parsed.runId !== 'string') {
402
+ return null;
403
+ }
404
+ return parsed;
405
+ }
406
+ catch {
407
+ return null;
408
+ }
409
+ }
410
+ function appendPlanMetrics(appRoot, plan) {
411
+ const baseDir = (0, path_1.join)(appRoot, '.e2e-ai-agents');
412
+ (0, fs_1.mkdirSync)(baseDir, { recursive: true });
413
+ const eventsPath = (0, path_1.join)(appRoot, PLAN_METRICS_EVENTS_PATH);
414
+ const summaryPath = (0, path_1.join)(appRoot, PLAN_METRICS_SUMMARY_PATH);
415
+ const event = {
416
+ schemaVersion: '1.0.0',
417
+ timestamp: new Date().toISOString(),
418
+ runId: plan.runId,
419
+ sourceRunId: plan.sourceRunId,
420
+ action: plan.decision.action,
421
+ runSet: plan.runSet,
422
+ confidence: plan.confidence,
423
+ changedFiles: plan.metrics.changedFiles,
424
+ impactedFlows: plan.metrics.impactedFlows,
425
+ uncoveredP0P1Flows: plan.metrics.uncoveredP0P1Flows,
426
+ warnings: plan.metrics.warnings,
427
+ enforcementMode: plan.enforcement.mode,
428
+ enforcementShouldFail: plan.enforcement.shouldFail,
429
+ };
430
+ (0, fs_1.appendFileSync)(eventsPath, `${JSON.stringify(event)}\n`, 'utf-8');
431
+ const allEvents = (0, fs_1.existsSync)(eventsPath)
432
+ ? (0, fs_1.readFileSync)(eventsPath, 'utf-8')
433
+ .split('\n')
434
+ .map(parsePlanMetricLine)
435
+ .filter((item) => Boolean(item))
436
+ : [event];
437
+ const byAction = {
438
+ 'run-now': 0,
439
+ 'must-add-tests': 0,
440
+ 'safe-to-merge': 0,
441
+ };
442
+ const byRunSet = {
443
+ smoke: 0,
444
+ targeted: 0,
445
+ full: 0,
446
+ };
447
+ let totalConfidence = 0;
448
+ let blockingRecommendations = 0;
449
+ for (const metricEvent of allEvents) {
450
+ byAction[metricEvent.action] += 1;
451
+ byRunSet[metricEvent.runSet] += 1;
452
+ totalConfidence += metricEvent.confidence;
453
+ if (metricEvent.enforcementShouldFail) {
454
+ blockingRecommendations += 1;
455
+ }
456
+ }
457
+ const totalRuns = allEvents.length;
458
+ const summary = {
459
+ schemaVersion: '1.0.0',
460
+ generatedAt: new Date().toISOString(),
461
+ totalRuns,
462
+ averageConfidence: totalRuns > 0 ? Number((totalConfidence / totalRuns).toFixed(2)) : 0,
463
+ byAction,
464
+ byRunSet,
465
+ blockingRecommendations,
466
+ blockingRate: totalRuns > 0 ? Number((blockingRecommendations / totalRuns).toFixed(4)) : 0,
467
+ };
468
+ (0, fs_1.writeFileSync)(summaryPath, JSON.stringify(summary, null, 2), 'utf-8');
469
+ return { eventsPath, summaryPath };
470
+ }
325
471
  function writeCiSummary(appRoot, markdown, relativePath = '.e2e-ai-agents/ci-summary.md') {
326
472
  const fullPath = (0, path_1.join)(appRoot, relativePath);
327
473
  const dir = (0, path_1.dirname)(fullPath);
@@ -5,6 +5,15 @@ import type { DataTestIdSuggestion } from './selectors.js';
5
5
  import type { GapTestSuggestion } from './gap_suggestions.js';
6
6
  export interface ReportData {
7
7
  mode: 'impact' | 'gap';
8
+ runMetadata?: {
9
+ runId: string;
10
+ startedAt: string;
11
+ completedAt: string;
12
+ durationMs: number;
13
+ sinceRef: string;
14
+ appPath: string;
15
+ testsRoot: string;
16
+ };
8
17
  changedFiles: string[];
9
18
  flows: FlowImpact[];
10
19
  coverage: FlowCoverage[];
@@ -65,8 +74,15 @@ export interface ReportData {
65
74
  generateStatus: string;
66
75
  healStatus?: string;
67
76
  error?: string;
77
+ failureCategory?: string;
78
+ failureCode?: string;
68
79
  }>;
69
80
  warnings: string[];
81
+ mcp?: {
82
+ requested: boolean;
83
+ active: boolean;
84
+ backend: string;
85
+ };
70
86
  };
71
87
  applied?: {
72
88
  patchedFiles: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,12 @@ function writeReport(appRoot, config, data) {
45
45
  const markdownLines = [];
46
46
  markdownLines.push(`# ${data.mode === 'impact' ? 'Impact Analysis' : 'Gap Analysis'} Report`);
47
47
  markdownLines.push('');
48
+ if (data.runMetadata) {
49
+ markdownLines.push(`Run ID: ${data.runMetadata.runId}`);
50
+ markdownLines.push(`Run window: ${data.runMetadata.startedAt} -> ${data.runMetadata.completedAt}`);
51
+ markdownLines.push(`Run duration (ms): ${data.runMetadata.durationMs}`);
52
+ markdownLines.push(`Since ref: ${data.runMetadata.sinceRef}`);
53
+ }
48
54
  markdownLines.push(`Framework: ${data.framework}`);
49
55
  markdownLines.push(`Test Patterns: ${data.testPatterns.join(', ') || 'None'}`);
50
56
  if (data.flowCatalog) {
@@ -94,12 +100,18 @@ function writeReport(appRoot, config, data) {
94
100
  markdownLines.push('');
95
101
  markdownLines.push('Pipeline Results:');
96
102
  markdownLines.push(`- Runner: ${data.pipeline.runner}`);
103
+ if (data.pipeline.mcp) {
104
+ markdownLines.push(`- MCP: requested=${data.pipeline.mcp.requested} active=${data.pipeline.mcp.active} backend=${data.pipeline.mcp.backend}`);
105
+ }
97
106
  for (const result of data.pipeline.results) {
98
107
  const status = result.healStatus ? `${result.generateStatus}/${result.healStatus}` : result.generateStatus;
99
108
  markdownLines.push(`- ${result.flowId} (${result.flowName}): ${status} -> ${result.generatedDir}`);
100
109
  if (result.error) {
101
110
  markdownLines.push(` Error: ${result.error}`);
102
111
  }
112
+ if (result.failureCategory || result.failureCode) {
113
+ markdownLines.push(` Failure taxonomy: category=${result.failureCategory || 'unknown'} code=${result.failureCode || 'unknown'}`);
114
+ }
103
115
  }
104
116
  if (data.pipeline.warnings.length > 0) {
105
117
  markdownLines.push('Pipeline warnings:');
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AA6M7C,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4LzF;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4LtF"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAoN7C,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,OAAO,CAAC;CAClB;AAYD,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAyMzF;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsNtF"}
@@ -21,6 +21,7 @@ const pipeline_js_1 = require("./pipeline.js");
21
21
  const gap_suggestions_js_1 = require("./gap_suggestions.js");
22
22
  const dependency_graph_js_1 = require("./dependency_graph.js");
23
23
  const traceability_js_1 = require("./traceability.js");
24
+ const utils_js_1 = require("./utils.js");
24
25
  const PRIORITY_RANK = {
25
26
  P0: 0,
26
27
  P1: 1,
@@ -84,11 +85,14 @@ function buildRecommendedTestsWithFlags(flows, testsByFlow) {
84
85
  const tests = testsByFlow.get(flow.id) || [];
85
86
  const flagSummary = (0, flags_js_1.formatFlags)(flow.flags || []);
86
87
  for (const test of tests) {
87
- if (!testNotes.has(test)) {
88
- testNotes.set(test, new Set());
88
+ const normalizedTest = (0, utils_js_1.normalizePath)(test)
89
+ .replace(/^\.\//, '')
90
+ .replace(/^e2e-tests\/playwright\//, '');
91
+ if (!testNotes.has(normalizedTest)) {
92
+ testNotes.set(normalizedTest, new Set());
89
93
  }
90
94
  if (flagSummary !== 'none') {
91
- testNotes.get(test)?.add(flagSummary);
95
+ testNotes.get(normalizedTest)?.add(flagSummary);
92
96
  }
93
97
  }
94
98
  }
@@ -114,11 +118,14 @@ function buildRecommendedTestsFromCoverage(flows, coverage) {
114
118
  const flow = flowMap.get(entry.flowId);
115
119
  const flagSummary = (0, flags_js_1.formatFlags)(flow?.flags || []);
116
120
  for (const test of entry.coveredBy) {
117
- if (!testNotes.has(test)) {
118
- testNotes.set(test, new Set());
121
+ const normalizedTest = (0, utils_js_1.normalizePath)(test)
122
+ .replace(/^\.\//, '')
123
+ .replace(/^e2e-tests\/playwright\//, '');
124
+ if (!testNotes.has(normalizedTest)) {
125
+ testNotes.set(normalizedTest, new Set());
119
126
  }
120
127
  if (flagSummary !== 'none') {
121
- testNotes.get(test)?.add(flagSummary);
128
+ testNotes.get(normalizedTest)?.add(flagSummary);
122
129
  }
123
130
  }
124
131
  }
@@ -190,12 +197,24 @@ function classifyImpactModelConfidence(flowMapping, testMapping, dependencyGraph
190
197
  }
191
198
  return 'low';
192
199
  }
200
+ function createRunId(mode) {
201
+ const ciRunId = process.env.GITHUB_RUN_ID;
202
+ const entropy = Math.random().toString(36).slice(2, 8);
203
+ const ts = Date.now().toString(36);
204
+ if (ciRunId) {
205
+ return `${mode}-gh-${ciRunId}-${ts}-${entropy}`;
206
+ }
207
+ return `${mode}-local-${ts}-${entropy}`;
208
+ }
193
209
  async function runImpact(_config, _options) {
194
210
  ensureAppRoot(_config.path);
195
211
  if (_config.testsRoot) {
196
212
  ensureAppRoot(_config.testsRoot);
197
213
  }
198
214
  const deadline = Date.now() + _config.timeLimitMinutes * 60 * 1000;
215
+ const runStartedAt = new Date().toISOString();
216
+ const runStartedTs = Date.now();
217
+ const runId = createRunId('impact');
199
218
  const warnings = [];
200
219
  const testsRoot = _config.testsRoot || _config.path;
201
220
  const frameworkDetection = (0, framework_js_1.detectFramework)(testsRoot, _config.framework);
@@ -213,7 +232,8 @@ async function runImpact(_config, _options) {
213
232
  if (changedFiles.length === 0 && !_config.impact.allowFallback) {
214
233
  throw new Error('No changed files detected. Provide --since or use gap mode (or --allow-fallback).');
215
234
  }
216
- let analysisTargets = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
235
+ const changedAppFiles = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
236
+ let analysisTargets = [...changedAppFiles];
217
237
  if (analysisTargets.length === 0 && _config.impact.allowFallback) {
218
238
  warnings.push('No changed files detected. Falling back to repository scan for screens.');
219
239
  analysisTargets = (0, analysis_js_1.scanRepositoryFlows)(_config.path, 250, _config.flowDiscovery.patterns, _config.flowDiscovery.exclude);
@@ -267,7 +287,7 @@ async function runImpact(_config, _options) {
267
287
  coverageMap.set(entry.flowId, entry.coveredBy);
268
288
  }
269
289
  gaps = computeGaps(flows, coverageMap);
270
- recommendedTests = buildRecommendedTestsWithFlags(flows, testsByFlow);
290
+ recommendedTests = buildRecommendedTestsFromCoverage(flows, coverage);
271
291
  }
272
292
  else {
273
293
  const traceability = (0, traceability_js_1.mapTraceabilityToFlows)(testsRoot, _config.impact.traceability, flows);
@@ -319,6 +339,15 @@ async function runImpact(_config, _options) {
319
339
  const reportRoot = testsRoot;
320
340
  const report = (0, report_js_1.writeReport)(reportRoot, _config, {
321
341
  mode: 'impact',
342
+ runMetadata: {
343
+ runId,
344
+ startedAt: runStartedAt,
345
+ completedAt: new Date().toISOString(),
346
+ durationMs: Date.now() - runStartedTs,
347
+ sinceRef: _config.git.since,
348
+ appPath: _config.path,
349
+ testsRoot,
350
+ },
322
351
  changedFiles,
323
352
  flows: sortFlows(flows),
324
353
  coverage,
@@ -365,6 +394,9 @@ async function runGap(_config, _options) {
365
394
  ensureAppRoot(_config.testsRoot);
366
395
  }
367
396
  const deadline = Date.now() + _config.timeLimitMinutes * 60 * 1000;
397
+ const runStartedAt = new Date().toISOString();
398
+ const runStartedTs = Date.now();
399
+ const runId = createRunId('gap');
368
400
  const warnings = [];
369
401
  const testsRoot = _config.testsRoot || _config.path;
370
402
  const frameworkDetection = (0, framework_js_1.detectFramework)(testsRoot, _config.framework);
@@ -379,7 +411,8 @@ async function runGap(_config, _options) {
379
411
  if (gitResult.error) {
380
412
  warnings.push(`Git diff failed: ${gitResult.error}`);
381
413
  }
382
- let analysisTargets = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
414
+ const changedAppFiles = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
415
+ let analysisTargets = [...changedAppFiles];
383
416
  if (analysisTargets.length === 0) {
384
417
  analysisTargets = (0, analysis_js_1.scanRepositoryFlows)(_config.path, 250, _config.flowDiscovery.patterns, _config.flowDiscovery.exclude);
385
418
  }
@@ -414,7 +447,20 @@ async function runGap(_config, _options) {
414
447
  let traceabilityStats;
415
448
  if (catalog) {
416
449
  flowCatalogSource = catalog.source;
417
- const mapping = (0, flow_mapping_js_1.mapChangesToCatalogFlows)(catalog, analysisTargets, 'gap', _config);
450
+ const catalogMode = changedAppFiles.length > 0 ? 'impact' : 'gap';
451
+ let mapping = (0, flow_mapping_js_1.mapChangesToCatalogFlows)(catalog, analysisTargets, catalogMode, _config);
452
+ if (catalogMode === 'impact' && mapping.flows.length === 0 && _config.impact.allowFallback) {
453
+ const fallbackMapping = (0, flow_mapping_js_1.mapChangesToCatalogFlows)(catalog, analysisTargets, 'gap', _config);
454
+ mapping = {
455
+ flows: fallbackMapping.flows,
456
+ testsByFlow: fallbackMapping.testsByFlow,
457
+ warnings: [
458
+ ...mapping.warnings,
459
+ ...fallbackMapping.warnings,
460
+ 'No catalog flow matched changed files; applied full-catalog fallback because allowFallback=true.',
461
+ ],
462
+ };
463
+ }
418
464
  flows = mapping.flows;
419
465
  testsByFlow = mapping.testsByFlow;
420
466
  warnings.push(...mapping.warnings);
@@ -435,7 +481,7 @@ async function runGap(_config, _options) {
435
481
  coverageMap.set(entry.flowId, entry.coveredBy);
436
482
  }
437
483
  gaps = computeGaps(flows, coverageMap);
438
- recommendedTests = buildRecommendedTestsWithFlags(flows, testsByFlow);
484
+ recommendedTests = buildRecommendedTestsFromCoverage(flows, coverage);
439
485
  }
440
486
  else {
441
487
  const traceability = (0, traceability_js_1.mapTraceabilityToFlows)(testsRoot, _config.impact.traceability, flows);
@@ -487,6 +533,15 @@ async function runGap(_config, _options) {
487
533
  const reportRoot = testsRoot;
488
534
  const report = (0, report_js_1.writeReport)(reportRoot, _config, {
489
535
  mode: 'gap',
536
+ runMetadata: {
537
+ runId,
538
+ startedAt: runStartedAt,
539
+ completedAt: new Date().toISOString(),
540
+ durationMs: Date.now() - runStartedTs,
541
+ sinceRef: _config.git.since,
542
+ appPath: _config.path,
543
+ testsRoot,
544
+ },
490
545
  changedFiles,
491
546
  flows: sortFlows(flows),
492
547
  coverage,
@@ -1 +1 @@
1
- {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../src/agent/tests.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;CACrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAkB7E;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAgCtF;AAaD,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,UAAU,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACnC,YAAY,EAAE,CA8BhB"}
1
+ {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../src/agent/tests.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;CACrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAkB7E;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAgCtF;AAuBD,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,UAAU,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACnC,YAAY,EAAE,CA8BhB"}
@@ -70,9 +70,19 @@ function resolveExpectedTests(testsRoot, expectedTests) {
70
70
  if (!entry) {
71
71
  continue;
72
72
  }
73
- resolved.push((0, utils_js_1.normalizePath)(entry));
73
+ const normalized = (0, utils_js_1.normalizePath)(entry).replace(/^\.\//, '');
74
+ if (normalized.startsWith('e2e-tests/playwright/')) {
75
+ resolved.push(normalized.slice('e2e-tests/playwright/'.length));
76
+ continue;
77
+ }
78
+ const specsIndex = normalized.indexOf('specs/');
79
+ if (specsIndex >= 0) {
80
+ resolved.push(normalized.slice(specsIndex));
81
+ continue;
82
+ }
83
+ resolved.push(normalized);
74
84
  }
75
- return resolved;
85
+ return Array.from(new Set(resolved));
76
86
  }
77
87
  function mapCatalogTestsToFlows(flows, testsRoot, testsByFlow) {
78
88
  return flows.map((flow) => {
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgB,KAAK,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAEtE,OAAO,EAMH,KAAK,UAAU,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAyB,KAAK,6BAA6B,EAAE,KAAK,4BAA4B,EAAC,MAAM,oBAAoB,CAAC;AACjI,OAAO,EAEH,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAChC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAGH,KAAK,yBAAyB,EACjC,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACvD,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED,MAAM,WAAW,6BAA6B;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AA0BD,wBAAsB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAOzF;AAED,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAOpF;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwBjG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,6BAA6B,GAAG,4BAA4B,CAE1G;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,4BAA4B,GAAG,wBAAwB,CASlG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,6BAA6B,GAAG,yBAAyB,CAkBrG"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgB,KAAK,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAEtE,OAAO,EAOH,KAAK,UAAU,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAyB,KAAK,6BAA6B,EAAE,KAAK,4BAA4B,EAAC,MAAM,oBAAoB,CAAC;AACjI,OAAO,EAEH,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAChC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAGH,KAAK,yBAAyB,EACjC,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACvD,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED,MAAM,WAAW,6BAA6B;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AA0BD,wBAAsB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAOzF;AAED,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAOpF;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAyBjG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,6BAA6B,GAAG,4BAA4B,CAE1G;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,4BAA4B,GAAG,wBAAwB,CASlG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,6BAA6B,GAAG,yBAAyB,CAkBrG"}
package/dist/api.js CHANGED
@@ -70,6 +70,7 @@ async function recommendTests(options = {}) {
70
70
  const planPath = (0, plan_js_1.writePlanReport)(reportRoot, plan);
71
71
  const ciSummaryMarkdown = (0, plan_js_1.renderCiSummaryMarkdown)(plan);
72
72
  const ciSummaryPath = (0, plan_js_1.writeCiSummary)(reportRoot, ciSummaryMarkdown);
73
+ (0, plan_js_1.appendPlanMetrics)(reportRoot, plan);
73
74
  return {
74
75
  report,
75
76
  reportPath: impactPath,