@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.
- package/LICENSE +168 -0
- package/README.md +620 -0
- package/dist/agent/analysis.d.ts +62 -0
- package/dist/agent/analysis.d.ts.map +1 -0
- package/dist/agent/analysis.js +292 -0
- package/dist/agent/blast_radius.d.ts +4 -0
- package/dist/agent/blast_radius.d.ts.map +1 -0
- package/dist/agent/blast_radius.js +37 -0
- package/dist/agent/cache_utils.d.ts +38 -0
- package/dist/agent/cache_utils.d.ts.map +1 -0
- package/dist/agent/cache_utils.js +67 -0
- package/dist/agent/config.d.ts +148 -0
- package/dist/agent/config.d.ts.map +1 -0
- package/dist/agent/config.js +640 -0
- package/dist/agent/dependency_graph.d.ts +14 -0
- package/dist/agent/dependency_graph.d.ts.map +1 -0
- package/dist/agent/dependency_graph.js +227 -0
- package/dist/agent/feedback.d.ts +55 -0
- package/dist/agent/feedback.d.ts.map +1 -0
- package/dist/agent/feedback.js +257 -0
- package/dist/agent/flags.d.ts +23 -0
- package/dist/agent/flags.d.ts.map +1 -0
- package/dist/agent/flags.js +171 -0
- package/dist/agent/flow_catalog.d.ts +25 -0
- package/dist/agent/flow_catalog.d.ts.map +1 -0
- package/dist/agent/flow_catalog.js +106 -0
- package/dist/agent/flow_mapping.d.ts +10 -0
- package/dist/agent/flow_mapping.d.ts.map +1 -0
- package/dist/agent/flow_mapping.js +84 -0
- package/dist/agent/framework.d.ts +13 -0
- package/dist/agent/framework.d.ts.map +1 -0
- package/dist/agent/framework.js +149 -0
- package/dist/agent/gap_suggestions.d.ts +14 -0
- package/dist/agent/gap_suggestions.d.ts.map +1 -0
- package/dist/agent/gap_suggestions.js +101 -0
- package/dist/agent/generator.d.ts +10 -0
- package/dist/agent/generator.d.ts.map +1 -0
- package/dist/agent/generator.js +115 -0
- package/dist/agent/git.d.ts +11 -0
- package/dist/agent/git.d.ts.map +1 -0
- package/dist/agent/git.js +90 -0
- package/dist/agent/handoff.d.ts +22 -0
- package/dist/agent/handoff.d.ts.map +1 -0
- package/dist/agent/handoff.js +180 -0
- package/dist/agent/impact-analyzer.d.ts +114 -0
- package/dist/agent/impact-analyzer.d.ts.map +1 -0
- package/dist/agent/impact-analyzer.js +557 -0
- package/dist/agent/index.d.ts +21 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +38 -0
- package/dist/agent/model-router.d.ts +57 -0
- package/dist/agent/model-router.d.ts.map +1 -0
- package/dist/agent/model-router.js +154 -0
- package/dist/agent/operational_insights.d.ts +41 -0
- package/dist/agent/operational_insights.d.ts.map +1 -0
- package/dist/agent/operational_insights.js +126 -0
- package/dist/agent/pipeline.d.ts +23 -0
- package/dist/agent/pipeline.d.ts.map +1 -0
- package/dist/agent/pipeline.js +609 -0
- package/dist/agent/plan.d.ts +91 -0
- package/dist/agent/plan.d.ts.map +1 -0
- package/dist/agent/plan.js +331 -0
- package/dist/agent/playwright_report.d.ts +8 -0
- package/dist/agent/playwright_report.d.ts.map +1 -0
- package/dist/agent/playwright_report.js +126 -0
- package/dist/agent/report-generator.d.ts +24 -0
- package/dist/agent/report-generator.d.ts.map +1 -0
- package/dist/agent/report-generator.js +250 -0
- package/dist/agent/report.d.ts +81 -0
- package/dist/agent/report.d.ts.map +1 -0
- package/dist/agent/report.js +147 -0
- package/dist/agent/runner.d.ts +7 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +576 -0
- package/dist/agent/selectors.d.ts +10 -0
- package/dist/agent/selectors.d.ts.map +1 -0
- package/dist/agent/selectors.js +75 -0
- package/dist/agent/spec-bridge.d.ts +101 -0
- package/dist/agent/spec-bridge.d.ts.map +1 -0
- package/dist/agent/spec-bridge.js +273 -0
- package/dist/agent/spec-builder.d.ts +102 -0
- package/dist/agent/spec-builder.d.ts.map +1 -0
- package/dist/agent/spec-builder.js +273 -0
- package/dist/agent/subsystem_risk.d.ts +23 -0
- package/dist/agent/subsystem_risk.d.ts.map +1 -0
- package/dist/agent/subsystem_risk.js +207 -0
- package/dist/agent/telemetry.d.ts +84 -0
- package/dist/agent/telemetry.d.ts.map +1 -0
- package/dist/agent/telemetry.js +220 -0
- package/dist/agent/test_path.d.ts +2 -0
- package/dist/agent/test_path.d.ts.map +1 -0
- package/dist/agent/test_path.js +23 -0
- package/dist/agent/tests.d.ts +18 -0
- package/dist/agent/tests.d.ts.map +1 -0
- package/dist/agent/tests.js +106 -0
- package/dist/agent/traceability.d.ts +22 -0
- package/dist/agent/traceability.d.ts.map +1 -0
- package/dist/agent/traceability.js +183 -0
- package/dist/agent/traceability_capture.d.ts +18 -0
- package/dist/agent/traceability_capture.d.ts.map +1 -0
- package/dist/agent/traceability_capture.js +313 -0
- package/dist/agent/traceability_ingest.d.ts +21 -0
- package/dist/agent/traceability_ingest.d.ts.map +1 -0
- package/dist/agent/traceability_ingest.js +237 -0
- package/dist/agent/utils.d.ts +13 -0
- package/dist/agent/utils.d.ts.map +1 -0
- package/dist/agent/utils.js +152 -0
- package/dist/agent/validators/selector-validator.d.ts +74 -0
- package/dist/agent/validators/selector-validator.d.ts.map +1 -0
- package/dist/agent/validators/selector-validator.js +165 -0
- package/dist/anthropic_provider.d.ts +65 -0
- package/dist/anthropic_provider.d.ts.map +1 -0
- package/dist/anthropic_provider.js +332 -0
- package/dist/api.d.ts +48 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +113 -0
- package/dist/base_provider.d.ts +53 -0
- package/dist/base_provider.d.ts.map +1 -0
- package/dist/base_provider.js +81 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +843 -0
- package/dist/custom_provider.d.ts +20 -0
- package/dist/custom_provider.d.ts.map +1 -0
- package/dist/custom_provider.js +276 -0
- package/dist/e2e-test-gen/index.d.ts +51 -0
- package/dist/e2e-test-gen/index.d.ts.map +1 -0
- package/dist/e2e-test-gen/index.js +57 -0
- package/dist/e2e-test-gen/spec_parser.d.ts +142 -0
- package/dist/e2e-test-gen/spec_parser.d.ts.map +1 -0
- package/dist/e2e-test-gen/spec_parser.js +786 -0
- package/dist/e2e-test-gen/types.d.ts +185 -0
- package/dist/e2e-test-gen/types.d.ts.map +1 -0
- package/dist/e2e-test-gen/types.js +4 -0
- package/dist/esm/agent/analysis.js +287 -0
- package/dist/esm/agent/blast_radius.js +34 -0
- package/dist/esm/agent/cache_utils.js +63 -0
- package/dist/esm/agent/config.js +637 -0
- package/dist/esm/agent/dependency_graph.js +224 -0
- package/dist/esm/agent/feedback.js +253 -0
- package/dist/esm/agent/flags.js +160 -0
- package/dist/esm/agent/flow_catalog.js +103 -0
- package/dist/esm/agent/flow_mapping.js +81 -0
- package/dist/esm/agent/framework.js +145 -0
- package/dist/esm/agent/gap_suggestions.js +98 -0
- package/dist/esm/agent/generator.js +112 -0
- package/dist/esm/agent/git.js +87 -0
- package/dist/esm/agent/handoff.js +177 -0
- package/dist/esm/agent/impact-analyzer.js +548 -0
- package/dist/esm/agent/index.js +22 -0
- package/dist/esm/agent/model-router.js +150 -0
- package/dist/esm/agent/operational_insights.js +123 -0
- package/dist/esm/agent/pipeline.js +605 -0
- package/dist/esm/agent/plan.js +324 -0
- package/dist/esm/agent/playwright_report.js +123 -0
- package/dist/esm/agent/report-generator.js +247 -0
- package/dist/esm/agent/report.js +144 -0
- package/dist/esm/agent/runner.js +572 -0
- package/dist/esm/agent/selectors.js +71 -0
- package/dist/esm/agent/spec-bridge.js +267 -0
- package/dist/esm/agent/spec-builder.js +267 -0
- package/dist/esm/agent/subsystem_risk.js +204 -0
- package/dist/esm/agent/telemetry.js +216 -0
- package/dist/esm/agent/test_path.js +20 -0
- package/dist/esm/agent/tests.js +101 -0
- package/dist/esm/agent/traceability.js +180 -0
- package/dist/esm/agent/traceability_capture.js +310 -0
- package/dist/esm/agent/traceability_ingest.js +234 -0
- package/dist/esm/agent/utils.js +138 -0
- package/dist/esm/agent/validators/selector-validator.js +160 -0
- package/dist/esm/anthropic_provider.js +324 -0
- package/dist/esm/api.js +105 -0
- package/dist/esm/base_provider.js +77 -0
- package/dist/esm/cli.js +841 -0
- package/dist/esm/custom_provider.js +272 -0
- package/dist/esm/e2e-test-gen/index.js +50 -0
- package/dist/esm/e2e-test-gen/spec_parser.js +782 -0
- package/dist/esm/e2e-test-gen/types.js +3 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/logger.js +89 -0
- package/dist/esm/mcp-server.js +465 -0
- package/dist/esm/ollama_provider.js +300 -0
- package/dist/esm/openai_provider.js +242 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/plan-and-test-constants.js +126 -0
- package/dist/esm/provider_factory.js +336 -0
- package/dist/esm/provider_interface.js +23 -0
- package/dist/esm/provider_utils.js +96 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/logger.d.ts +23 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +93 -0
- package/dist/mcp-server.d.ts +35 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +469 -0
- package/dist/ollama_provider.d.ts +65 -0
- package/dist/ollama_provider.d.ts.map +1 -0
- package/dist/ollama_provider.js +308 -0
- package/dist/openai_provider.d.ts +23 -0
- package/dist/openai_provider.d.ts.map +1 -0
- package/dist/openai_provider.js +250 -0
- package/dist/plan-and-test-constants.d.ts +110 -0
- package/dist/plan-and-test-constants.d.ts.map +1 -0
- package/dist/plan-and-test-constants.js +132 -0
- package/dist/provider_factory.d.ts +99 -0
- package/dist/provider_factory.d.ts.map +1 -0
- package/dist/provider_factory.js +341 -0
- package/dist/provider_interface.d.ts +358 -0
- package/dist/provider_interface.d.ts.map +1 -0
- package/dist/provider_interface.js +28 -0
- package/dist/provider_utils.d.ts +39 -0
- package/dist/provider_utils.d.ts.map +1 -0
- package/dist/provider_utils.js +103 -0
- package/package.json +101 -0
- package/schemas/gap.schema.json +18 -0
- package/schemas/impact.schema.json +418 -0
- package/schemas/plan.schema.json +285 -0
- package/schemas/subsystem-risk-map.schema.json +62 -0
- package/schemas/traceability-input.schema.json +122 -0
|
@@ -0,0 +1,220 @@
|
|
|
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.TelemetryCollector = void 0;
|
|
6
|
+
/**
|
|
7
|
+
* Telemetry Collection System (Phase A2)
|
|
8
|
+
*
|
|
9
|
+
* Tracks costs, performance, and success metrics for test generation operations.
|
|
10
|
+
* Provides visibility into:
|
|
11
|
+
* - Cost per operation (input/output tokens * model rate)
|
|
12
|
+
* - Model usage breakdown (Haiku, Sonnet, Opus)
|
|
13
|
+
* - Success rate by operation
|
|
14
|
+
* - Performance metrics (duration, tokens used)
|
|
15
|
+
*
|
|
16
|
+
* Data stored in: `.e2e-ai-agents/metrics/YYYY-MM-DD.json`
|
|
17
|
+
*/
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const crypto_1 = require("crypto");
|
|
21
|
+
const MODEL_RATES = {
|
|
22
|
+
'claude-haiku-4-0-20250430': 0.25 / 1000000, // per input token
|
|
23
|
+
'claude-sonnet-4-5-20250929': 3 / 1000000,
|
|
24
|
+
'claude-opus-4-6-20250820': 15 / 1000000,
|
|
25
|
+
};
|
|
26
|
+
class TelemetryCollector {
|
|
27
|
+
constructor(metricsDir = '.e2e-ai-agents/metrics') {
|
|
28
|
+
this.metrics = new Map();
|
|
29
|
+
this.metricsDir = metricsDir;
|
|
30
|
+
this.ensureMetricsDir();
|
|
31
|
+
this.loadTodayMetrics();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Ensure metrics directory exists
|
|
35
|
+
*/
|
|
36
|
+
ensureMetricsDir() {
|
|
37
|
+
if (!(0, fs_1.existsSync)(this.metricsDir)) {
|
|
38
|
+
(0, fs_1.mkdirSync)(this.metricsDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get today's metrics file path
|
|
43
|
+
*/
|
|
44
|
+
getTodayPath() {
|
|
45
|
+
const now = new Date();
|
|
46
|
+
const date = now.toISOString().split('T')[0]; // YYYY-MM-DD
|
|
47
|
+
return (0, path_1.join)(this.metricsDir, `${date}.json`);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Load metrics from disk
|
|
51
|
+
*/
|
|
52
|
+
loadTodayMetrics() {
|
|
53
|
+
const path = this.getTodayPath();
|
|
54
|
+
if ((0, fs_1.existsSync)(path)) {
|
|
55
|
+
try {
|
|
56
|
+
const data = JSON.parse((0, fs_1.readFileSync)(path, 'utf-8'));
|
|
57
|
+
this.metrics.set(path, data);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(`Failed to load metrics from ${path}:`, error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Track a metric
|
|
66
|
+
*/
|
|
67
|
+
track(metric) {
|
|
68
|
+
const fullMetric = {
|
|
69
|
+
id: (0, crypto_1.randomUUID)().substring(0, 8),
|
|
70
|
+
...metric,
|
|
71
|
+
};
|
|
72
|
+
const path = this.getTodayPath();
|
|
73
|
+
const metrics = this.metrics.get(path) || [];
|
|
74
|
+
metrics.push(fullMetric);
|
|
75
|
+
this.metrics.set(path, metrics);
|
|
76
|
+
// Persist to disk
|
|
77
|
+
this.saveMetrics();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Save metrics to disk
|
|
81
|
+
*/
|
|
82
|
+
saveMetrics() {
|
|
83
|
+
this.metrics.forEach((metrics, path) => {
|
|
84
|
+
(0, fs_1.writeFileSync)(path, JSON.stringify(metrics, null, 2), 'utf-8');
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Calculate cost for a metric
|
|
89
|
+
*/
|
|
90
|
+
static calculateCost(model, tokensInput, tokensOutput) {
|
|
91
|
+
const inputRate = MODEL_RATES[model] || 0.003 / 1000000; // Default estimate
|
|
92
|
+
const outputRate = inputRate * 3; // Output usually 3x input cost
|
|
93
|
+
return tokensInput * inputRate + tokensOutput * outputRate;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Generate report for a date range
|
|
97
|
+
*/
|
|
98
|
+
generateReport(since, until) {
|
|
99
|
+
const start = since || new Date(new Date().setDate(new Date().getDate() - 7)); // Default: last 7 days
|
|
100
|
+
const end = until || new Date();
|
|
101
|
+
// Collect all metrics in date range
|
|
102
|
+
const allMetrics = [];
|
|
103
|
+
this.metrics.forEach((metrics) => {
|
|
104
|
+
metrics.forEach((m) => {
|
|
105
|
+
const metricDate = new Date(m.timestamp);
|
|
106
|
+
if (metricDate >= start && metricDate <= end) {
|
|
107
|
+
allMetrics.push(m);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
// Calculate summary
|
|
112
|
+
const successCount = allMetrics.filter((m) => m.success).length;
|
|
113
|
+
const failureCount = allMetrics.length - successCount;
|
|
114
|
+
const totalCost = allMetrics.reduce((sum, m) => sum + m.costUsd, 0);
|
|
115
|
+
const avgCost = allMetrics.length > 0 ? totalCost / allMetrics.length : 0;
|
|
116
|
+
const totalTokens = allMetrics.reduce((sum, m) => sum + (m.tokensInput + m.tokensOutput), 0);
|
|
117
|
+
const avgDuration = allMetrics.length > 0 ? allMetrics.reduce((sum, m) => sum + m.durationMs, 0) / allMetrics.length / 1000 : 0;
|
|
118
|
+
// By model
|
|
119
|
+
const byModel = {};
|
|
120
|
+
allMetrics.forEach((m) => {
|
|
121
|
+
if (!byModel[m.model]) {
|
|
122
|
+
byModel[m.model] = { count: 0, totalCost: 0, successCount: 0 };
|
|
123
|
+
}
|
|
124
|
+
byModel[m.model].count += 1;
|
|
125
|
+
byModel[m.model].totalCost += m.costUsd;
|
|
126
|
+
if (m.success)
|
|
127
|
+
byModel[m.model].successCount += 1;
|
|
128
|
+
});
|
|
129
|
+
Object.keys(byModel).forEach((model) => {
|
|
130
|
+
const data = byModel[model];
|
|
131
|
+
byModel[model] = {
|
|
132
|
+
count: data.count,
|
|
133
|
+
totalCost: data.totalCost,
|
|
134
|
+
avgCost: data.totalCost / data.count,
|
|
135
|
+
successRate: (data.successCount / data.count) * 100,
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
// By operation
|
|
139
|
+
const byOperation = {};
|
|
140
|
+
allMetrics.forEach((m) => {
|
|
141
|
+
if (!byOperation[m.operation]) {
|
|
142
|
+
byOperation[m.operation] = { count: 0, totalCost: 0, totalDuration: 0, successCount: 0 };
|
|
143
|
+
}
|
|
144
|
+
byOperation[m.operation].count += 1;
|
|
145
|
+
byOperation[m.operation].totalCost += m.costUsd;
|
|
146
|
+
byOperation[m.operation].totalDuration += m.durationMs;
|
|
147
|
+
if (m.success)
|
|
148
|
+
byOperation[m.operation].successCount += 1;
|
|
149
|
+
});
|
|
150
|
+
Object.keys(byOperation).forEach((op) => {
|
|
151
|
+
const data = byOperation[op];
|
|
152
|
+
byOperation[op] = {
|
|
153
|
+
count: data.count,
|
|
154
|
+
totalCost: data.totalCost,
|
|
155
|
+
avgDuration: data.totalDuration / data.count / 1000,
|
|
156
|
+
successRate: (data.successCount / data.count) * 100,
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
period: {
|
|
161
|
+
start: start.toISOString().split('T')[0],
|
|
162
|
+
end: end.toISOString().split('T')[0],
|
|
163
|
+
},
|
|
164
|
+
summary: {
|
|
165
|
+
totalOperations: allMetrics.length,
|
|
166
|
+
successCount,
|
|
167
|
+
failureCount,
|
|
168
|
+
successRate: allMetrics.length > 0 ? (successCount / allMetrics.length) * 100 : 0,
|
|
169
|
+
totalCost,
|
|
170
|
+
avgCost,
|
|
171
|
+
totalTokens,
|
|
172
|
+
avgDuration,
|
|
173
|
+
},
|
|
174
|
+
byModel,
|
|
175
|
+
byOperation,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Format report for console output
|
|
180
|
+
*/
|
|
181
|
+
static formatReport(report) {
|
|
182
|
+
const lines = [
|
|
183
|
+
'',
|
|
184
|
+
'📊 Test Generation Metrics',
|
|
185
|
+
`Period: ${report.period.start} to ${report.period.end}`,
|
|
186
|
+
'═'.repeat(50),
|
|
187
|
+
'',
|
|
188
|
+
`Total Operations: ${report.summary.totalOperations}`,
|
|
189
|
+
`Success Rate: ${report.summary.successRate.toFixed(1)}% (${report.summary.successCount}/${report.summary.totalOperations})`,
|
|
190
|
+
`Total Cost: $${report.summary.totalCost.toFixed(2)}`,
|
|
191
|
+
`Avg Cost/Op: $${report.summary.avgCost.toFixed(4)}`,
|
|
192
|
+
`Avg Duration: ${report.summary.avgDuration.toFixed(1)}s`,
|
|
193
|
+
`Total Tokens: ${report.summary.totalTokens.toLocaleString()}`,
|
|
194
|
+
'',
|
|
195
|
+
'Model Usage:',
|
|
196
|
+
];
|
|
197
|
+
Object.entries(report.byModel).forEach(([model, data]) => {
|
|
198
|
+
const shortName = model.includes('haiku') ? 'Haiku' : model.includes('sonnet') ? 'Sonnet' : 'Opus';
|
|
199
|
+
lines.push(` ${shortName}: ${data.count} ops - $${data.totalCost.toFixed(2)} (avg $${data.avgCost.toFixed(4)}, ${data.successRate.toFixed(0)}% success)`);
|
|
200
|
+
});
|
|
201
|
+
lines.push('', 'By Operation:');
|
|
202
|
+
Object.entries(report.byOperation).forEach(([op, data]) => {
|
|
203
|
+
lines.push(` ${op}: ${data.count} ops - $${data.totalCost.toFixed(2)} (${data.avgDuration.toFixed(1)}s avg, ${data.successRate.toFixed(0)}% success)`);
|
|
204
|
+
});
|
|
205
|
+
lines.push('');
|
|
206
|
+
return lines.join('\n');
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Export metrics as JSON
|
|
210
|
+
*/
|
|
211
|
+
exportJson(filepath) {
|
|
212
|
+
const allMetrics = [];
|
|
213
|
+
this.metrics.forEach((metrics) => {
|
|
214
|
+
allMetrics.push(...metrics);
|
|
215
|
+
});
|
|
216
|
+
(0, fs_1.writeFileSync)(filepath, JSON.stringify(allMetrics, null, 2), 'utf-8');
|
|
217
|
+
console.log(` ✓ Exported ${allMetrics.length} metrics to ${filepath}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
exports.TelemetryCollector = TelemetryCollector;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test_path.d.ts","sourceRoot":"","sources":["../../src/agent/test_path.ts"],"names":[],"mappings":"AAOA,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiB/D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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.inferSubsystemFromTestPath = inferSubsystemFromTestPath;
|
|
6
|
+
function normalizeTestName(test) {
|
|
7
|
+
return test.replace(/ \(flags:.*\)$/, '').trim();
|
|
8
|
+
}
|
|
9
|
+
function inferSubsystemFromTestPath(test) {
|
|
10
|
+
const normalized = normalizeTestName(test).replace(/^\/+/, '');
|
|
11
|
+
const parts = normalized.split('/').filter(Boolean);
|
|
12
|
+
if (parts.length === 0) {
|
|
13
|
+
return 'unknown';
|
|
14
|
+
}
|
|
15
|
+
const specsIdx = parts.findIndex((part) => part === 'specs' || part === 'tests');
|
|
16
|
+
if (specsIdx >= 0 && specsIdx + 1 < parts.length) {
|
|
17
|
+
return parts[specsIdx + 1] || 'unknown';
|
|
18
|
+
}
|
|
19
|
+
if (parts.length >= 2 && (parts[0] === 'e2e-tests' || parts[0] === 'playwright')) {
|
|
20
|
+
return parts[1] || 'unknown';
|
|
21
|
+
}
|
|
22
|
+
return parts[0] || 'unknown';
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FlowImpact } from './analysis.js';
|
|
2
|
+
export interface TestFile {
|
|
3
|
+
path: string;
|
|
4
|
+
content: string | null;
|
|
5
|
+
}
|
|
6
|
+
export interface FlowCoverage {
|
|
7
|
+
flowId: string;
|
|
8
|
+
flowName: string;
|
|
9
|
+
priority: string;
|
|
10
|
+
coveredBy: string[];
|
|
11
|
+
score: number;
|
|
12
|
+
expectedTests?: string[];
|
|
13
|
+
source?: 'catalog' | 'traceability' | 'heuristic';
|
|
14
|
+
}
|
|
15
|
+
export declare function discoverTests(appRoot: string, patterns: string[]): TestFile[];
|
|
16
|
+
export declare function mapTestsToFlows(flows: FlowImpact[], tests: TestFile[]): FlowCoverage[];
|
|
17
|
+
export declare function mapCatalogTestsToFlows(flows: FlowImpact[], testsRoot: string, testsByFlow: Map<string, string[]>): FlowCoverage[];
|
|
18
|
+
//# sourceMappingURL=tests.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
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.discoverTests = discoverTests;
|
|
6
|
+
exports.mapTestsToFlows = mapTestsToFlows;
|
|
7
|
+
exports.mapCatalogTestsToFlows = mapCatalogTestsToFlows;
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const glob_1 = require("glob");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const utils_js_1 = require("./utils.js");
|
|
12
|
+
function discoverTests(appRoot, patterns) {
|
|
13
|
+
const files = new Set();
|
|
14
|
+
for (const pattern of patterns) {
|
|
15
|
+
const matches = (0, glob_1.globSync)(pattern, {
|
|
16
|
+
cwd: appRoot,
|
|
17
|
+
ignore: ['**/node_modules/**', '**/.git/**'],
|
|
18
|
+
nodir: true,
|
|
19
|
+
});
|
|
20
|
+
for (const match of matches) {
|
|
21
|
+
files.add((0, utils_js_1.normalizePath)(match));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return Array.from(files).map((relativePath) => {
|
|
25
|
+
const fullPath = (0, path_1.join)(appRoot, relativePath);
|
|
26
|
+
const content = (0, utils_js_1.safeReadTextFile)(fullPath);
|
|
27
|
+
return { path: relativePath, content };
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function buildFlowKeywords(flow) {
|
|
31
|
+
const tokens = [];
|
|
32
|
+
tokens.push(...(0, utils_js_1.tokenize)(flow.id));
|
|
33
|
+
tokens.push(...(0, utils_js_1.tokenize)(flow.name));
|
|
34
|
+
tokens.push(...flow.keywords);
|
|
35
|
+
return (0, utils_js_1.uniqueTokens)(tokens);
|
|
36
|
+
}
|
|
37
|
+
function mapTestsToFlows(flows, tests) {
|
|
38
|
+
const coverage = [];
|
|
39
|
+
for (const flow of flows) {
|
|
40
|
+
const keywords = buildFlowKeywords(flow);
|
|
41
|
+
const matched = [];
|
|
42
|
+
let score = 0;
|
|
43
|
+
for (const test of tests) {
|
|
44
|
+
const haystack = `${test.path} ${test.content || ''}`.toLowerCase();
|
|
45
|
+
let localScore = 0;
|
|
46
|
+
for (const keyword of keywords) {
|
|
47
|
+
if (keyword && haystack.includes(keyword.toLowerCase())) {
|
|
48
|
+
localScore += 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (localScore > 0) {
|
|
52
|
+
matched.push(test.path);
|
|
53
|
+
score += localScore;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
coverage.push({
|
|
57
|
+
flowId: flow.id,
|
|
58
|
+
flowName: flow.name,
|
|
59
|
+
priority: flow.priority,
|
|
60
|
+
coveredBy: matched,
|
|
61
|
+
score,
|
|
62
|
+
source: 'heuristic',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return coverage;
|
|
66
|
+
}
|
|
67
|
+
function resolveExpectedTests(testsRoot, expectedTests) {
|
|
68
|
+
const resolved = [];
|
|
69
|
+
for (const entry of expectedTests) {
|
|
70
|
+
if (!entry) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
resolved.push((0, utils_js_1.normalizePath)(entry));
|
|
74
|
+
}
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
|
77
|
+
function mapCatalogTestsToFlows(flows, testsRoot, testsByFlow) {
|
|
78
|
+
return flows.map((flow) => {
|
|
79
|
+
const expectedTests = resolveExpectedTests(testsRoot, testsByFlow.get(flow.id) || []);
|
|
80
|
+
const coveredBy = [];
|
|
81
|
+
for (const expected of expectedTests) {
|
|
82
|
+
const isAbsolute = expected.startsWith('/');
|
|
83
|
+
const globTarget = isAbsolute ? expected : expected;
|
|
84
|
+
if (expected.includes('*') || expected.includes('?') || expected.includes('{')) {
|
|
85
|
+
const matches = (0, glob_1.globSync)(globTarget, { cwd: isAbsolute ? undefined : testsRoot, nodir: true });
|
|
86
|
+
if (matches.length > 0) {
|
|
87
|
+
coveredBy.push(...matches.map((match) => (0, utils_js_1.normalizePath)(match)));
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const fullPath = isAbsolute ? expected : (0, path_1.join)(testsRoot, expected);
|
|
92
|
+
if ((0, fs_1.existsSync)(fullPath)) {
|
|
93
|
+
coveredBy.push(isAbsolute ? (0, utils_js_1.normalizePath)(expected) : expected);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
flowId: flow.id,
|
|
98
|
+
flowName: flow.name,
|
|
99
|
+
priority: flow.priority,
|
|
100
|
+
coveredBy: Array.from(new Set(coveredBy)),
|
|
101
|
+
score: coveredBy.length,
|
|
102
|
+
expectedTests,
|
|
103
|
+
source: 'catalog',
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FlowImpact } from './analysis.js';
|
|
2
|
+
import type { TraceabilityImpactConfig } from './config.js';
|
|
3
|
+
import type { FlowCoverage } from './tests.js';
|
|
4
|
+
export interface TraceabilityStats {
|
|
5
|
+
source: 'manifest';
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
manifestPath: string;
|
|
8
|
+
manifestFound: boolean;
|
|
9
|
+
manifestTests: number;
|
|
10
|
+
manifestEdges: number;
|
|
11
|
+
matchedFlows: number;
|
|
12
|
+
totalFlows: number;
|
|
13
|
+
matchedTests: number;
|
|
14
|
+
coverageRatio: number;
|
|
15
|
+
}
|
|
16
|
+
export interface TraceabilityMappingResult {
|
|
17
|
+
coverage: FlowCoverage[];
|
|
18
|
+
stats: TraceabilityStats;
|
|
19
|
+
warnings: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function mapTraceabilityToFlows(appRoot: string, config: TraceabilityImpactConfig, flows: FlowImpact[]): TraceabilityMappingResult;
|
|
22
|
+
//# sourceMappingURL=traceability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceability.d.ts","sourceRoot":"","sources":["../../src/agent/traceability.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAoB7C,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACtC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAsFD,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,UAAU,EAAE,GACpB,yBAAyB,CAiH3B"}
|
|
@@ -0,0 +1,183 @@
|
|
|
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.mapTraceabilityToFlows = mapTraceabilityToFlows;
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const utils_js_1 = require("./utils.js");
|
|
9
|
+
function ratio(numerator, denominator) {
|
|
10
|
+
if (denominator <= 0) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
return Number((numerator / denominator).toFixed(4));
|
|
14
|
+
}
|
|
15
|
+
function resolveManifestPath(root, configuredPath) {
|
|
16
|
+
if ((0, path_1.isAbsolute)(configuredPath)) {
|
|
17
|
+
return configuredPath;
|
|
18
|
+
}
|
|
19
|
+
return (0, path_1.join)(root, configuredPath);
|
|
20
|
+
}
|
|
21
|
+
function safeReadManifest(path) {
|
|
22
|
+
if (!(0, fs_1.existsSync)(path)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse((0, fs_1.readFileSync)(path, 'utf-8'));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function normalizeFiles(files) {
|
|
33
|
+
if (!files) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
return files.map((file) => (0, utils_js_1.normalizePath)(file)).filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
function normalizeTests(tests) {
|
|
39
|
+
if (!tests) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
return tests.map((test) => (0, utils_js_1.normalizePath)(test)).filter(Boolean);
|
|
43
|
+
}
|
|
44
|
+
function buildFileToTestsMap(manifest) {
|
|
45
|
+
const fileToTests = new Map();
|
|
46
|
+
const setMapping = (file, test) => {
|
|
47
|
+
if (!file || !test) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const key = (0, utils_js_1.normalizePath)(file);
|
|
51
|
+
const value = (0, utils_js_1.normalizePath)(test);
|
|
52
|
+
if (!fileToTests.has(key)) {
|
|
53
|
+
fileToTests.set(key, new Set());
|
|
54
|
+
}
|
|
55
|
+
fileToTests.get(key)?.add(value);
|
|
56
|
+
};
|
|
57
|
+
if (manifest.tests) {
|
|
58
|
+
for (const entry of manifest.tests) {
|
|
59
|
+
const files = normalizeFiles(entry.touchedFiles);
|
|
60
|
+
for (const file of files) {
|
|
61
|
+
setMapping(file, entry.test);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (manifest.fileToTests) {
|
|
66
|
+
for (const [file, tests] of Object.entries(manifest.fileToTests)) {
|
|
67
|
+
const normalizedTests = normalizeTests(tests);
|
|
68
|
+
for (const test of normalizedTests) {
|
|
69
|
+
setMapping(file, test);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (manifest.mappings) {
|
|
74
|
+
for (const entry of manifest.mappings) {
|
|
75
|
+
const normalizedTests = normalizeTests(entry.tests);
|
|
76
|
+
for (const test of normalizedTests) {
|
|
77
|
+
setMapping(entry.file, test);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return fileToTests;
|
|
82
|
+
}
|
|
83
|
+
function mapTraceabilityToFlows(appRoot, config, flows) {
|
|
84
|
+
const manifestPath = resolveManifestPath(appRoot, config.manifestPath);
|
|
85
|
+
const warnings = [];
|
|
86
|
+
const fallbackStats = {
|
|
87
|
+
source: 'manifest',
|
|
88
|
+
enabled: config.enabled,
|
|
89
|
+
manifestPath,
|
|
90
|
+
manifestFound: false,
|
|
91
|
+
manifestTests: 0,
|
|
92
|
+
manifestEdges: 0,
|
|
93
|
+
matchedFlows: 0,
|
|
94
|
+
totalFlows: flows.length,
|
|
95
|
+
matchedTests: 0,
|
|
96
|
+
coverageRatio: 0,
|
|
97
|
+
};
|
|
98
|
+
if (!config.enabled) {
|
|
99
|
+
return {
|
|
100
|
+
coverage: [],
|
|
101
|
+
warnings,
|
|
102
|
+
stats: fallbackStats,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const manifest = safeReadManifest(manifestPath);
|
|
106
|
+
if (!manifest) {
|
|
107
|
+
warnings.push(`Traceability manifest not found or invalid: ${manifestPath}`);
|
|
108
|
+
return {
|
|
109
|
+
coverage: [],
|
|
110
|
+
warnings,
|
|
111
|
+
stats: fallbackStats,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const fileToTests = buildFileToTestsMap(manifest);
|
|
115
|
+
let manifestEdges = 0;
|
|
116
|
+
for (const tests of fileToTests.values()) {
|
|
117
|
+
manifestEdges += tests.size;
|
|
118
|
+
}
|
|
119
|
+
const manifestTests = new Set();
|
|
120
|
+
const coverage = [];
|
|
121
|
+
const matchedTests = new Set();
|
|
122
|
+
let matchedFlows = 0;
|
|
123
|
+
for (const tests of fileToTests.values()) {
|
|
124
|
+
for (const test of tests) {
|
|
125
|
+
manifestTests.add(test);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const flow of flows) {
|
|
129
|
+
const signalCounts = new Map();
|
|
130
|
+
const files = flow.files.map((file) => (0, utils_js_1.normalizePath)(file));
|
|
131
|
+
for (const file of files) {
|
|
132
|
+
const tests = fileToTests.get(file);
|
|
133
|
+
if (!tests) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
for (const test of tests) {
|
|
137
|
+
signalCounts.set(test, (signalCounts.get(test) || 0) + 1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const coveredBy = Array.from(signalCounts.entries())
|
|
141
|
+
.filter(([, count]) => count >= Math.max(1, config.minSignalsPerTest))
|
|
142
|
+
.map(([test]) => test)
|
|
143
|
+
.sort();
|
|
144
|
+
const score = Array.from(signalCounts.values()).reduce((acc, value) => acc + value, 0);
|
|
145
|
+
if (coveredBy.length > 0) {
|
|
146
|
+
matchedFlows += 1;
|
|
147
|
+
for (const test of coveredBy) {
|
|
148
|
+
matchedTests.add(test);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
coverage.push({
|
|
152
|
+
flowId: flow.id,
|
|
153
|
+
flowName: flow.name,
|
|
154
|
+
priority: flow.priority,
|
|
155
|
+
coveredBy,
|
|
156
|
+
score,
|
|
157
|
+
source: 'traceability',
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const stats = {
|
|
161
|
+
source: 'manifest',
|
|
162
|
+
enabled: config.enabled,
|
|
163
|
+
manifestPath,
|
|
164
|
+
manifestFound: true,
|
|
165
|
+
manifestTests: manifestTests.size,
|
|
166
|
+
manifestEdges,
|
|
167
|
+
matchedFlows,
|
|
168
|
+
totalFlows: flows.length,
|
|
169
|
+
matchedTests: matchedTests.size,
|
|
170
|
+
coverageRatio: ratio(matchedFlows, flows.length),
|
|
171
|
+
};
|
|
172
|
+
if (manifestEdges === 0) {
|
|
173
|
+
warnings.push(`Traceability manifest has no file-to-test mappings: ${manifestPath}`);
|
|
174
|
+
}
|
|
175
|
+
else if (stats.coverageRatio < 0.4) {
|
|
176
|
+
warnings.push(`Traceability coverage is low (${stats.matchedFlows}/${stats.totalFlows} flows mapped). Recommendations may require heuristic fallback.`);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
coverage,
|
|
180
|
+
warnings,
|
|
181
|
+
stats,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface TraceabilityCaptureOptions {
|
|
2
|
+
appPath: string;
|
|
3
|
+
testsRoot: string;
|
|
4
|
+
reportPath: string;
|
|
5
|
+
sinceRef: string;
|
|
6
|
+
outputPath?: string;
|
|
7
|
+
coverageMapPath?: string;
|
|
8
|
+
changedFilesPath?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface TraceabilityCaptureResult {
|
|
11
|
+
outputPath: string;
|
|
12
|
+
testsSeen: number;
|
|
13
|
+
runsGenerated: number;
|
|
14
|
+
changedFilesUsed: number;
|
|
15
|
+
warnings: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function captureTraceabilityInput(options: TraceabilityCaptureOptions): TraceabilityCaptureResult;
|
|
18
|
+
//# sourceMappingURL=traceability_capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceability_capture.d.ts","sourceRoot":"","sources":["../../src/agent/traceability_capture.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAgRD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,0BAA0B,GAAG,yBAAyB,CAgFvG"}
|