@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.
- package/README.md +29 -20
- package/dist/agent/config.d.ts +3 -0
- package/dist/agent/config.d.ts.map +1 -1
- package/dist/agent/config.js +38 -0
- package/dist/agent/operational_insights.d.ts +1 -1
- package/dist/agent/operational_insights.d.ts.map +1 -1
- package/dist/agent/operational_insights.js +2 -1
- package/dist/agent/pipeline.d.ts +8 -1
- package/dist/agent/pipeline.d.ts.map +1 -1
- package/dist/agent/pipeline.js +844 -33
- package/dist/agent/plan.d.ts +39 -0
- package/dist/agent/plan.d.ts.map +1 -1
- package/dist/agent/plan.js +146 -0
- package/dist/agent/report.d.ts +16 -0
- package/dist/agent/report.d.ts.map +1 -1
- package/dist/agent/report.js +12 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +66 -11
- package/dist/agent/tests.d.ts.map +1 -1
- package/dist/agent/tests.js +12 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -0
- package/dist/cli.js +111 -7
- package/dist/esm/agent/config.js +38 -0
- package/dist/esm/agent/operational_insights.js +2 -1
- package/dist/esm/agent/pipeline.js +844 -33
- package/dist/esm/agent/plan.js +145 -1
- package/dist/esm/agent/report.js +12 -0
- package/dist/esm/agent/runner.js +66 -11
- package/dist/esm/agent/tests.js +12 -2
- package/dist/esm/api.js +2 -1
- package/dist/esm/cli.js +112 -8
- package/package.json +1 -1
- package/schemas/impact.schema.json +37 -0
- package/schemas/plan.schema.json +48 -0
- package/dist/agent/cache_utils.d.ts +0 -38
- package/dist/agent/cache_utils.d.ts.map +0 -1
- package/dist/agent/cache_utils.js +0 -67
- package/dist/agent/impact-analyzer.d.ts +0 -114
- package/dist/agent/impact-analyzer.d.ts.map +0 -1
- package/dist/agent/impact-analyzer.js +0 -557
- package/dist/agent/index.d.ts +0 -21
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -38
- package/dist/agent/model-router.d.ts +0 -57
- package/dist/agent/model-router.d.ts.map +0 -1
- package/dist/agent/model-router.js +0 -154
- package/dist/agent/report-generator.d.ts +0 -24
- package/dist/agent/report-generator.d.ts.map +0 -1
- package/dist/agent/report-generator.js +0 -250
- package/dist/agent/spec-bridge.d.ts +0 -101
- package/dist/agent/spec-bridge.d.ts.map +0 -1
- package/dist/agent/spec-bridge.js +0 -273
- package/dist/agent/spec-builder.d.ts +0 -102
- package/dist/agent/spec-builder.d.ts.map +0 -1
- package/dist/agent/spec-builder.js +0 -273
- package/dist/agent/telemetry.d.ts +0 -84
- package/dist/agent/telemetry.d.ts.map +0 -1
- package/dist/agent/telemetry.js +0 -220
- package/dist/agent/validators/selector-validator.d.ts +0 -74
- package/dist/agent/validators/selector-validator.d.ts.map +0 -1
- package/dist/agent/validators/selector-validator.js +0 -165
- package/dist/e2e-test-gen/index.d.ts +0 -51
- package/dist/e2e-test-gen/index.d.ts.map +0 -1
- package/dist/e2e-test-gen/index.js +0 -57
- package/dist/e2e-test-gen/spec_parser.d.ts +0 -142
- package/dist/e2e-test-gen/spec_parser.d.ts.map +0 -1
- package/dist/e2e-test-gen/spec_parser.js +0 -786
- package/dist/e2e-test-gen/types.d.ts +0 -185
- package/dist/e2e-test-gen/types.d.ts.map +0 -1
- package/dist/e2e-test-gen/types.js +0 -4
- package/dist/esm/agent/cache_utils.js +0 -63
- package/dist/esm/agent/impact-analyzer.js +0 -548
- package/dist/esm/agent/index.js +0 -22
- package/dist/esm/agent/model-router.js +0 -150
- package/dist/esm/agent/report-generator.js +0 -247
- package/dist/esm/agent/spec-bridge.js +0 -267
- package/dist/esm/agent/spec-builder.js +0 -267
- package/dist/esm/agent/telemetry.js +0 -216
- package/dist/esm/agent/validators/selector-validator.js +0 -160
- package/dist/esm/e2e-test-gen/index.js +0 -50
- package/dist/esm/e2e-test-gen/spec_parser.js +0 -782
- package/dist/esm/e2e-test-gen/types.js +0 -3
- package/dist/esm/plan-and-test-constants.js +0 -126
- package/dist/plan-and-test-constants.d.ts +0 -110
- package/dist/plan-and-test-constants.d.ts.map +0 -1
- package/dist/plan-and-test-constants.js +0 -132
package/dist/agent/plan.d.ts
CHANGED
|
@@ -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
|
package/dist/agent/plan.d.ts.map
CHANGED
|
@@ -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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"}
|
package/dist/agent/plan.js
CHANGED
|
@@ -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);
|
package/dist/agent/report.d.ts
CHANGED
|
@@ -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":"AAKA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,sBAAsB,CAAC;AAG5D,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAEtC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE;QACV,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC;QACrC,WAAW,EAAE,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;QACtD,eAAe,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;QAC3C,YAAY,CAAC,EAAE;YACX,MAAM,EAAE,UAAU,CAAC;YACnB,OAAO,EAAE,OAAO,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,aAAa,EAAE,OAAO,CAAC;YACvB,aAAa,EAAE,MAAM,CAAC;YACtB,aAAa,EAAE,MAAM,CAAC;YACtB,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,YAAY,EAAE,MAAM,CAAC;YACrB,aAAa,EAAE,MAAM,CAAC;SACzB,CAAC;QACF,eAAe,CAAC,EAAE;YACd,MAAM,EAAE,yBAAyB,CAAC;YAClC,OAAO,EAAE,OAAO,CAAC;YACjB,SAAS,EAAE,MAAM,CAAC;YAClB,aAAa,EAAE,MAAM,CAAC;YACtB,aAAa,EAAE,MAAM,CAAC;YACtB,aAAa,EAAE,MAAM,CAAC;YACtB,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,EAAE,OAAO,CAAC;SACtB,CAAC;QACF,aAAa,CAAC,EAAE;YACZ,MAAM,EAAE,KAAK,CAAC;YACd,OAAO,EAAE,OAAO,CAAC;YACjB,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,OAAO,CAAC;YAClB,WAAW,EAAE,MAAM,CAAC;YACpB,YAAY,EAAE,MAAM,CAAC;YACrB,WAAW,EAAE,MAAM,CAAC;YACpB,YAAY,EAAE,MAAM,CAAC;SACxB,CAAC;KACL,CAAC;IACF,QAAQ,CAAC,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,KAAK,CAAC;YACX,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,cAAc,EAAE,MAAM,CAAC;YACvB,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/report.js
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -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
|
-
|
|
88
|
-
|
|
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(
|
|
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
|
-
|
|
118
|
-
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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;
|
|
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"}
|
package/dist/agent/tests.js
CHANGED
|
@@ -70,9 +70,19 @@ function resolveExpectedTests(testsRoot, expectedTests) {
|
|
|
70
70
|
if (!entry) {
|
|
71
71
|
continue;
|
|
72
72
|
}
|
|
73
|
-
|
|
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,
|
|
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,
|