@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,292 @@
|
|
|
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.analyzeFiles = analyzeFiles;
|
|
6
|
+
exports.isTestFilePath = isTestFilePath;
|
|
7
|
+
exports.scanRepositoryFlows = scanRepositoryFlows;
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const glob_1 = require("glob");
|
|
11
|
+
const flags_js_1 = require("./flags.js");
|
|
12
|
+
const utils_js_1 = require("./utils.js");
|
|
13
|
+
const subsystem_risk_js_1 = require("./subsystem_risk.js");
|
|
14
|
+
const TEST_PATH_PATTERN = /(^|\/)__tests__(\/|$)|(^|\/)tests?(\/|$)|\.(spec|test)\.[a-z0-9]+$/i;
|
|
15
|
+
const SCREEN_DIRS = new Set(['pages', 'screens', 'views', 'routes']);
|
|
16
|
+
const FEATURE_DIRS = new Set(['features', 'modules', 'flows']);
|
|
17
|
+
const COMPONENT_DIRS = new Set(['components', 'widgets', 'ui']);
|
|
18
|
+
const STATE_DIRS = new Set(['state', 'store', 'stores', 'reducers', 'actions', 'context', 'hooks']);
|
|
19
|
+
const STYLE_EXTS = new Set(['css', 'scss', 'sass', 'less', 'styl']);
|
|
20
|
+
const UI_EXTS = new Set(['tsx', 'jsx']);
|
|
21
|
+
const CODE_EXTS = new Set(['ts', 'js', 'tsx', 'jsx']);
|
|
22
|
+
const INTERACTION_PATTERN = /(onClick|onSubmit|onChange|type=['"]submit['"]|role=['"]button['"]|aria-label=)/;
|
|
23
|
+
const PRIORITY_RANK = {
|
|
24
|
+
P0: 0,
|
|
25
|
+
P1: 1,
|
|
26
|
+
P2: 2,
|
|
27
|
+
};
|
|
28
|
+
function deriveFlowFromPath(relativePath) {
|
|
29
|
+
const segments = (0, utils_js_1.normalizePath)(relativePath).split('/').filter(Boolean);
|
|
30
|
+
const baseName = (0, utils_js_1.baseNameWithoutExt)(relativePath);
|
|
31
|
+
const base = baseName.toLowerCase() === 'index' && segments.length > 1 ? segments[segments.length - 2] : baseName;
|
|
32
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
33
|
+
const segment = segments[i].toLowerCase();
|
|
34
|
+
if (SCREEN_DIRS.has(segment)) {
|
|
35
|
+
const next = segments[i + 1] ? segments[i + 1] : base;
|
|
36
|
+
return { id: (0, utils_js_1.normalizePath)(next), name: (0, utils_js_1.titleCase)(next), kind: 'screen' };
|
|
37
|
+
}
|
|
38
|
+
if (FEATURE_DIRS.has(segment)) {
|
|
39
|
+
const next = segments[i + 1] ? segments[i + 1] : base;
|
|
40
|
+
return { id: (0, utils_js_1.normalizePath)(next), name: (0, utils_js_1.titleCase)(next), kind: 'flow' };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { id: (0, utils_js_1.normalizePath)(base), name: (0, utils_js_1.titleCase)(base), kind: 'flow' };
|
|
44
|
+
}
|
|
45
|
+
function extractKeywords(relativePath) {
|
|
46
|
+
const segments = (0, utils_js_1.normalizePath)(relativePath).split('/').filter(Boolean);
|
|
47
|
+
const base = (0, utils_js_1.baseNameWithoutExt)(relativePath);
|
|
48
|
+
const tokens = segments.flatMap((segment) => (0, utils_js_1.tokenize)(segment));
|
|
49
|
+
tokens.push(...(0, utils_js_1.tokenize)(base));
|
|
50
|
+
return (0, utils_js_1.uniqueTokens)(tokens);
|
|
51
|
+
}
|
|
52
|
+
function detectInteractions(content) {
|
|
53
|
+
if (!content)
|
|
54
|
+
return false;
|
|
55
|
+
return INTERACTION_PATTERN.test(content);
|
|
56
|
+
}
|
|
57
|
+
function isScreenPath(relativePath) {
|
|
58
|
+
const segments = (0, utils_js_1.normalizePath)(relativePath).split('/').map((segment) => segment.toLowerCase());
|
|
59
|
+
if (segments.some((segment) => segment === 'selectors' || segment === 'reducers' || segment === 'actions')) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return segments.some((segment) => SCREEN_DIRS.has(segment));
|
|
63
|
+
}
|
|
64
|
+
function isComponentPath(relativePath) {
|
|
65
|
+
const segments = (0, utils_js_1.normalizePath)(relativePath).split('/').map((segment) => segment.toLowerCase());
|
|
66
|
+
return segments.some((segment) => COMPONENT_DIRS.has(segment));
|
|
67
|
+
}
|
|
68
|
+
function isStatePath(relativePath) {
|
|
69
|
+
const segments = (0, utils_js_1.normalizePath)(relativePath).split('/').map((segment) => segment.toLowerCase());
|
|
70
|
+
return segments.some((segment) => STATE_DIRS.has(segment));
|
|
71
|
+
}
|
|
72
|
+
function scoreFile(file, risk) {
|
|
73
|
+
let score = 1;
|
|
74
|
+
const reasons = [];
|
|
75
|
+
if (file.isScreen) {
|
|
76
|
+
score += 3;
|
|
77
|
+
reasons.push('Screen-level change');
|
|
78
|
+
}
|
|
79
|
+
if (file.isComponent) {
|
|
80
|
+
score += 2;
|
|
81
|
+
reasons.push('Shared component change');
|
|
82
|
+
}
|
|
83
|
+
if (file.isUI) {
|
|
84
|
+
score += 2;
|
|
85
|
+
reasons.push('UI logic change');
|
|
86
|
+
}
|
|
87
|
+
if (file.isState) {
|
|
88
|
+
score += 2;
|
|
89
|
+
reasons.push('State or data flow change');
|
|
90
|
+
}
|
|
91
|
+
if (file.isStyle) {
|
|
92
|
+
score += 1;
|
|
93
|
+
reasons.push('Visual styling change');
|
|
94
|
+
}
|
|
95
|
+
if (file.hasInteractions) {
|
|
96
|
+
score += 2;
|
|
97
|
+
reasons.push('Interactive element change');
|
|
98
|
+
}
|
|
99
|
+
const keywordHit = file.keywords.find((keyword) => risk.criticalKeywords.includes(keyword));
|
|
100
|
+
if (keywordHit) {
|
|
101
|
+
score += 2;
|
|
102
|
+
reasons.push(`Critical keyword: ${keywordHit}`);
|
|
103
|
+
}
|
|
104
|
+
if (file.subsystemRisk) {
|
|
105
|
+
const scoreDelta = file.subsystemRisk.scoreDelta;
|
|
106
|
+
if (scoreDelta !== 0) {
|
|
107
|
+
score += scoreDelta;
|
|
108
|
+
reasons.push(`Subsystem risk adjustment: ${scoreDelta > 0 ? '+' : ''}${scoreDelta}`);
|
|
109
|
+
}
|
|
110
|
+
reasons.push(...file.subsystemRisk.reasons);
|
|
111
|
+
}
|
|
112
|
+
return { score, reasons };
|
|
113
|
+
}
|
|
114
|
+
function mergePriorityFloor(current, candidate) {
|
|
115
|
+
if (!candidate) {
|
|
116
|
+
return current;
|
|
117
|
+
}
|
|
118
|
+
if (!current) {
|
|
119
|
+
return candidate;
|
|
120
|
+
}
|
|
121
|
+
return PRIORITY_RANK[candidate] < PRIORITY_RANK[current] ? candidate : current;
|
|
122
|
+
}
|
|
123
|
+
function analyzeFiles(appRoot, relativePaths, config) {
|
|
124
|
+
const files = [];
|
|
125
|
+
const defaultAudience = config.audience.defaultRoles;
|
|
126
|
+
const defaultFlagState = config.flags.defaultState;
|
|
127
|
+
const warnings = [];
|
|
128
|
+
const subsystemRisk = (0, subsystem_risk_js_1.loadSubsystemRiskResolver)(config.impact.subsystemRisk);
|
|
129
|
+
warnings.push(...subsystemRisk.warnings);
|
|
130
|
+
let subsystemRiskMatchedFiles = 0;
|
|
131
|
+
let subsystemRiskRuleMatches = 0;
|
|
132
|
+
for (const relativePath of relativePaths) {
|
|
133
|
+
if (isTestFilePath(relativePath)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const fullPath = (0, path_1.join)(appRoot, relativePath);
|
|
137
|
+
const exists = (0, fs_1.existsSync)(fullPath);
|
|
138
|
+
const extension = (0, utils_js_1.fileExtension)(relativePath);
|
|
139
|
+
const content = exists && CODE_EXTS.has(extension) ? (0, utils_js_1.safeReadTextFile)(fullPath) : null;
|
|
140
|
+
const { id, name, kind } = deriveFlowFromPath(relativePath);
|
|
141
|
+
const audience = (0, flags_js_1.inferAudienceFromPath)(relativePath, config);
|
|
142
|
+
const flags = (0, flags_js_1.extractFlagHits)(content, config);
|
|
143
|
+
const subsystemRiskMatches = subsystemRisk.matchFile((0, utils_js_1.normalizePath)(relativePath));
|
|
144
|
+
let subsystemRiskScoreDelta = 0;
|
|
145
|
+
let subsystemRiskPriorityFloor;
|
|
146
|
+
const subsystemRiskRules = (0, utils_js_1.uniqueTokens)(subsystemRiskMatches.map((entry) => entry.ruleId));
|
|
147
|
+
const subsystemRiskReasons = (0, utils_js_1.uniqueTokens)(subsystemRiskMatches.flatMap((entry) => entry.reasons));
|
|
148
|
+
if (subsystemRiskMatches.length > 0) {
|
|
149
|
+
subsystemRiskMatchedFiles += 1;
|
|
150
|
+
subsystemRiskRuleMatches += subsystemRiskMatches.length;
|
|
151
|
+
subsystemRiskScoreDelta = subsystemRiskMatches.reduce((acc, entry) => acc + entry.scoreDelta, 0);
|
|
152
|
+
for (const match of subsystemRiskMatches) {
|
|
153
|
+
subsystemRiskPriorityFloor = mergePriorityFloor(subsystemRiskPriorityFloor, match.priorityFloor);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const subsystemKeywords = (0, utils_js_1.uniqueTokens)(subsystemRiskMatches.flatMap((entry) => entry.keywords));
|
|
157
|
+
const analysis = {
|
|
158
|
+
relativePath: (0, utils_js_1.normalizePath)(relativePath),
|
|
159
|
+
extension,
|
|
160
|
+
exists,
|
|
161
|
+
content,
|
|
162
|
+
isUI: UI_EXTS.has(extension),
|
|
163
|
+
isScreen: isScreenPath(relativePath),
|
|
164
|
+
isComponent: isComponentPath(relativePath),
|
|
165
|
+
isState: isStatePath(relativePath),
|
|
166
|
+
isStyle: STYLE_EXTS.has(extension),
|
|
167
|
+
hasInteractions: detectInteractions(content),
|
|
168
|
+
keywords: (0, utils_js_1.uniqueTokens)([...extractKeywords(relativePath), ...subsystemKeywords]),
|
|
169
|
+
flowId: id,
|
|
170
|
+
flowName: name,
|
|
171
|
+
flowKind: kind,
|
|
172
|
+
audience,
|
|
173
|
+
flags,
|
|
174
|
+
subsystemRisk: subsystemRiskMatches.length > 0
|
|
175
|
+
? {
|
|
176
|
+
rules: subsystemRiskRules,
|
|
177
|
+
scoreDelta: subsystemRiskScoreDelta,
|
|
178
|
+
priorityFloor: subsystemRiskPriorityFloor,
|
|
179
|
+
reasons: subsystemRiskReasons,
|
|
180
|
+
}
|
|
181
|
+
: undefined,
|
|
182
|
+
};
|
|
183
|
+
files.push(analysis);
|
|
184
|
+
}
|
|
185
|
+
const flowMap = new Map();
|
|
186
|
+
for (const file of files) {
|
|
187
|
+
const { score, reasons } = scoreFile(file, config.risk);
|
|
188
|
+
const existing = flowMap.get(file.flowId);
|
|
189
|
+
if (!existing) {
|
|
190
|
+
flowMap.set(file.flowId, {
|
|
191
|
+
id: file.flowId,
|
|
192
|
+
name: file.flowName,
|
|
193
|
+
kind: file.flowKind,
|
|
194
|
+
score,
|
|
195
|
+
priority: 'P2',
|
|
196
|
+
reasons: [...reasons],
|
|
197
|
+
keywords: [...file.keywords],
|
|
198
|
+
files: [file.relativePath],
|
|
199
|
+
audience: file.audience,
|
|
200
|
+
flags: file.flags,
|
|
201
|
+
priorityFloor: file.subsystemRisk?.priorityFloor,
|
|
202
|
+
subsystemRiskBoost: file.subsystemRisk?.scoreDelta || 0,
|
|
203
|
+
subsystemRiskRules: file.subsystemRisk?.rules || [],
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
existing.score += score;
|
|
208
|
+
existing.files.push(file.relativePath);
|
|
209
|
+
existing.reasons.push(...reasons);
|
|
210
|
+
existing.keywords.push(...file.keywords);
|
|
211
|
+
existing.audience = (0, flags_js_1.normalizeRoles)([...(existing.audience || []), ...file.audience], defaultAudience);
|
|
212
|
+
existing.flags = (0, flags_js_1.mergeFlags)([...(existing.flags || []), ...file.flags], defaultFlagState);
|
|
213
|
+
existing.priorityFloor = mergePriorityFloor(existing.priorityFloor, file.subsystemRisk?.priorityFloor);
|
|
214
|
+
existing.subsystemRiskBoost = (existing.subsystemRiskBoost || 0) + (file.subsystemRisk?.scoreDelta || 0);
|
|
215
|
+
existing.subsystemRiskRules = (0, utils_js_1.uniqueTokens)([...(existing.subsystemRiskRules || []), ...(file.subsystemRisk?.rules || [])]);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
let boostedFlows = 0;
|
|
219
|
+
const flows = Array.from(flowMap.values()).map((flow) => {
|
|
220
|
+
const uniqueReason = (0, utils_js_1.uniqueTokens)(flow.reasons);
|
|
221
|
+
const uniqueKeywords = (0, utils_js_1.uniqueTokens)(flow.keywords);
|
|
222
|
+
const computedPriority = flow.score >= config.risk.p0Threshold
|
|
223
|
+
? 'P0'
|
|
224
|
+
: flow.score >= config.risk.p1Threshold
|
|
225
|
+
? 'P1'
|
|
226
|
+
: 'P2';
|
|
227
|
+
const priority = mergePriorityFloor(computedPriority, flow.priorityFloor) || computedPriority;
|
|
228
|
+
if ((flow.subsystemRiskBoost || 0) !== 0 || (flow.priorityFloor && flow.priorityFloor !== computedPriority)) {
|
|
229
|
+
boostedFlows += 1;
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
...flow,
|
|
233
|
+
reasons: uniqueReason.map((reason) => reason),
|
|
234
|
+
keywords: uniqueKeywords,
|
|
235
|
+
priority,
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
files,
|
|
240
|
+
flows,
|
|
241
|
+
warnings,
|
|
242
|
+
subsystemRisk: {
|
|
243
|
+
source: 'map',
|
|
244
|
+
enabled: subsystemRisk.info.enabled,
|
|
245
|
+
mapPath: subsystemRisk.info.mapPath,
|
|
246
|
+
mapFound: subsystemRisk.info.mapFound,
|
|
247
|
+
rulesLoaded: subsystemRisk.info.rulesLoaded,
|
|
248
|
+
filesMatched: subsystemRiskMatchedFiles,
|
|
249
|
+
ruleMatches: subsystemRiskRuleMatches,
|
|
250
|
+
boostedFlows,
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function isTestFilePath(relativePath) {
|
|
255
|
+
return TEST_PATH_PATTERN.test((0, utils_js_1.normalizePath)(relativePath));
|
|
256
|
+
}
|
|
257
|
+
function scanRepositoryFlows(appRoot, limit = 250, patterns, exclude) {
|
|
258
|
+
const defaultPatterns = [
|
|
259
|
+
'**/pages/**/*.{tsx,jsx,ts,js}',
|
|
260
|
+
'**/screens/**/*.{tsx,jsx,ts,js}',
|
|
261
|
+
'**/views/**/*.{tsx,jsx,ts,js}',
|
|
262
|
+
'**/routes/**/*.{tsx,jsx,ts,js}',
|
|
263
|
+
];
|
|
264
|
+
const useDefaults = !(patterns && patterns.length > 0);
|
|
265
|
+
const activePatterns = useDefaults ? defaultPatterns : patterns;
|
|
266
|
+
const matches = new Set();
|
|
267
|
+
const ignorePatterns = [
|
|
268
|
+
'**/node_modules/**',
|
|
269
|
+
'**/.git/**',
|
|
270
|
+
'**/__tests__/**',
|
|
271
|
+
'**/tests/**',
|
|
272
|
+
...(useDefaults ? ['**/selectors/**', '**/reducers/**', '**/actions/**'] : []),
|
|
273
|
+
...(exclude || []),
|
|
274
|
+
];
|
|
275
|
+
for (const pattern of activePatterns) {
|
|
276
|
+
const files = (0, glob_1.globSync)(pattern, {
|
|
277
|
+
cwd: appRoot,
|
|
278
|
+
ignore: ignorePatterns,
|
|
279
|
+
nodir: true,
|
|
280
|
+
});
|
|
281
|
+
for (const file of files) {
|
|
282
|
+
matches.add((0, utils_js_1.normalizePath)(file));
|
|
283
|
+
if (matches.size >= limit) {
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (matches.size >= limit) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return Array.from(matches);
|
|
292
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentConfig } from './config.js';
|
|
2
|
+
import type { FileAnalysis, FlowImpact } from './analysis.js';
|
|
3
|
+
export declare function applyBlastRadius(flows: FlowImpact[], files: FileAnalysis[], config: AgentConfig): FlowImpact[];
|
|
4
|
+
//# sourceMappingURL=blast_radius.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blast_radius.d.ts","sourceRoot":"","sources":["../../src/agent/blast_radius.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,WAAW,EAAe,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAC,YAAY,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAG5D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,UAAU,EAAE,CAmC9G"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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.applyBlastRadius = applyBlastRadius;
|
|
6
|
+
const flags_js_1 = require("./flags.js");
|
|
7
|
+
function applyBlastRadius(flows, files, config) {
|
|
8
|
+
if (flows.length === 0) {
|
|
9
|
+
return flows;
|
|
10
|
+
}
|
|
11
|
+
const fileMap = new Map();
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
fileMap.set(file.relativePath, file);
|
|
14
|
+
}
|
|
15
|
+
return flows.map((flow) => {
|
|
16
|
+
const collectedFlags = [...(flow.flags || [])];
|
|
17
|
+
const collectedAudience = [...(flow.audience || [])];
|
|
18
|
+
for (const filePath of flow.files) {
|
|
19
|
+
const file = fileMap.get(filePath);
|
|
20
|
+
if (!file) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
collectedFlags.push(...file.flags);
|
|
24
|
+
collectedAudience.push(...file.audience);
|
|
25
|
+
}
|
|
26
|
+
const mergedFlags = (0, flags_js_1.mergeFlags)(collectedFlags, config.flags.defaultState);
|
|
27
|
+
const mergedAudience = (0, flags_js_1.normalizeRoles)(collectedAudience, config.audience.defaultRoles);
|
|
28
|
+
const blastRadius = (0, flags_js_1.computeBlastRadius)(mergedAudience, mergedFlags, config);
|
|
29
|
+
return {
|
|
30
|
+
...flow,
|
|
31
|
+
audience: mergedAudience,
|
|
32
|
+
flags: mergedFlags,
|
|
33
|
+
blastRadius,
|
|
34
|
+
score: flow.score + blastRadius.scoreDelta,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple TTL cache for repository context and file reads
|
|
3
|
+
* Provides 90% faster access on cache hits
|
|
4
|
+
* Default TTL: 5 minutes
|
|
5
|
+
*/
|
|
6
|
+
export interface CacheEntry<T> {
|
|
7
|
+
value: T;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class SimpleCache<T> {
|
|
11
|
+
private cache;
|
|
12
|
+
private ttlMs;
|
|
13
|
+
constructor(ttlMs?: number);
|
|
14
|
+
/**
|
|
15
|
+
* Get value from cache if it exists and hasn't expired
|
|
16
|
+
*/
|
|
17
|
+
get(key: string): T | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Set value in cache with current timestamp
|
|
20
|
+
*/
|
|
21
|
+
set(key: string, value: T): void;
|
|
22
|
+
/**
|
|
23
|
+
* Clear all entries from cache
|
|
24
|
+
*/
|
|
25
|
+
clear(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Get cache size
|
|
28
|
+
*/
|
|
29
|
+
size(): number;
|
|
30
|
+
/**
|
|
31
|
+
* Get cache statistics
|
|
32
|
+
*/
|
|
33
|
+
stats(): {
|
|
34
|
+
size: number;
|
|
35
|
+
entries: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=cache_utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache_utils.d.ts","sourceRoot":"","sources":["../../src/agent/cache_utils.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,WAAW,CAAC,CAAC;IACtB,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,GAAE,MAAsB;IAKzC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAe/B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAOhC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,KAAK,IAAI;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC;CAgB3C"}
|
|
@@ -0,0 +1,67 @@
|
|
|
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.SimpleCache = void 0;
|
|
6
|
+
class SimpleCache {
|
|
7
|
+
constructor(ttlMs = 5 * 60 * 1000) {
|
|
8
|
+
this.cache = new Map();
|
|
9
|
+
// Default: 5 minutes
|
|
10
|
+
this.ttlMs = ttlMs;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get value from cache if it exists and hasn't expired
|
|
14
|
+
*/
|
|
15
|
+
get(key) {
|
|
16
|
+
const entry = this.cache.get(key);
|
|
17
|
+
if (!entry) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
// Check if entry has expired
|
|
21
|
+
if (Date.now() - entry.timestamp > this.ttlMs) {
|
|
22
|
+
this.cache.delete(key);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return entry.value;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Set value in cache with current timestamp
|
|
29
|
+
*/
|
|
30
|
+
set(key, value) {
|
|
31
|
+
this.cache.set(key, {
|
|
32
|
+
value,
|
|
33
|
+
timestamp: Date.now(),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Clear all entries from cache
|
|
38
|
+
*/
|
|
39
|
+
clear() {
|
|
40
|
+
this.cache.clear();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get cache size
|
|
44
|
+
*/
|
|
45
|
+
size() {
|
|
46
|
+
return this.cache.size;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get cache statistics
|
|
50
|
+
*/
|
|
51
|
+
stats() {
|
|
52
|
+
// Clean expired entries
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
let expired = 0;
|
|
55
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
56
|
+
if (now - entry.timestamp > this.ttlMs) {
|
|
57
|
+
this.cache.delete(key);
|
|
58
|
+
expired++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
size: this.cache.size,
|
|
63
|
+
entries: this.cache.size,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.SimpleCache = SimpleCache;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export type AnalysisMode = 'impact' | 'gap';
|
|
2
|
+
export type FrameworkType = 'auto' | 'playwright' | 'cypress' | 'selenium' | 'unknown';
|
|
3
|
+
export type ArtifactMode = 'commit' | 'keep-local' | 'none';
|
|
4
|
+
export interface BudgetConfig {
|
|
5
|
+
maxUSD?: number;
|
|
6
|
+
maxTokens?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ArtifactConfig {
|
|
9
|
+
mode: ArtifactMode;
|
|
10
|
+
specsDir: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SelectorConfig {
|
|
13
|
+
patchOnApply: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface TestDiscoveryConfig {
|
|
16
|
+
patterns?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface FlowDiscoveryConfig {
|
|
19
|
+
patterns?: string[];
|
|
20
|
+
exclude?: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface CatalogScoringConfig {
|
|
23
|
+
priorityScores: {
|
|
24
|
+
P0: number;
|
|
25
|
+
P1: number;
|
|
26
|
+
P2: number;
|
|
27
|
+
};
|
|
28
|
+
fileMatchWeight: number;
|
|
29
|
+
}
|
|
30
|
+
export type FlagState = 'on' | 'off' | 'unknown';
|
|
31
|
+
export type AudienceRole = 'system_admin' | 'team_admin' | 'channel_admin' | 'member' | 'guest' | 'deactivated';
|
|
32
|
+
export interface FlagConfig {
|
|
33
|
+
defaultState: FlagState;
|
|
34
|
+
}
|
|
35
|
+
export interface AudienceConfig {
|
|
36
|
+
defaultRoles: AudienceRole[];
|
|
37
|
+
}
|
|
38
|
+
export interface BlastRadiusConfig {
|
|
39
|
+
memberBonus: number;
|
|
40
|
+
guestBonus: number;
|
|
41
|
+
adminOnlyPenalty: number;
|
|
42
|
+
flagOffPenalty: number;
|
|
43
|
+
}
|
|
44
|
+
export interface PipelineConfig {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
scenarios: number;
|
|
47
|
+
outputDir: string;
|
|
48
|
+
heal: boolean;
|
|
49
|
+
baseUrl?: string;
|
|
50
|
+
browser?: 'chrome' | 'chromium' | 'firefox' | 'webkit';
|
|
51
|
+
headless?: boolean;
|
|
52
|
+
project?: string;
|
|
53
|
+
parallel?: boolean;
|
|
54
|
+
dryRun?: boolean;
|
|
55
|
+
mcp?: boolean;
|
|
56
|
+
}
|
|
57
|
+
export interface LLMConfig {
|
|
58
|
+
provider?: string;
|
|
59
|
+
fallback?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface RiskConfig {
|
|
62
|
+
p0Threshold: number;
|
|
63
|
+
p1Threshold: number;
|
|
64
|
+
criticalKeywords: string[];
|
|
65
|
+
}
|
|
66
|
+
export interface PolicyConfig {
|
|
67
|
+
minConfidenceForTargeted: number;
|
|
68
|
+
safeMergeMinConfidence: number;
|
|
69
|
+
forceFullOnWarningsAtOrAbove: number;
|
|
70
|
+
forceFullOnP0WithGaps: boolean;
|
|
71
|
+
forceFullOnRiskyFiles: boolean;
|
|
72
|
+
riskyFilePatterns: string[];
|
|
73
|
+
}
|
|
74
|
+
export interface DependencyGraphImpactConfig {
|
|
75
|
+
enabled: boolean;
|
|
76
|
+
maxDepth: number;
|
|
77
|
+
maxExpandedFiles: number;
|
|
78
|
+
filePatterns: string[];
|
|
79
|
+
excludePatterns: string[];
|
|
80
|
+
aliasRoots: string[];
|
|
81
|
+
pathAliases: Record<string, string[]>;
|
|
82
|
+
}
|
|
83
|
+
export interface TraceabilityImpactConfig {
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
manifestPath: string;
|
|
86
|
+
minSignalsPerTest: number;
|
|
87
|
+
}
|
|
88
|
+
export interface SubsystemRiskImpactConfig {
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
mapPath: string;
|
|
91
|
+
maxRulesPerFile: number;
|
|
92
|
+
}
|
|
93
|
+
export interface GitConfig {
|
|
94
|
+
since: string;
|
|
95
|
+
includeUncommitted?: boolean;
|
|
96
|
+
}
|
|
97
|
+
export interface AgentConfig {
|
|
98
|
+
path: string;
|
|
99
|
+
testsRoot?: string;
|
|
100
|
+
flowCatalogPath?: string;
|
|
101
|
+
mode: AnalysisMode;
|
|
102
|
+
framework: FrameworkType;
|
|
103
|
+
timeLimitMinutes: number;
|
|
104
|
+
budget: BudgetConfig;
|
|
105
|
+
artifacts: ArtifactConfig;
|
|
106
|
+
selectors: SelectorConfig;
|
|
107
|
+
testDiscovery: TestDiscoveryConfig;
|
|
108
|
+
flowDiscovery: FlowDiscoveryConfig;
|
|
109
|
+
catalogScoring: CatalogScoringConfig;
|
|
110
|
+
impact: {
|
|
111
|
+
allowFallback: boolean;
|
|
112
|
+
dependencyGraph: DependencyGraphImpactConfig;
|
|
113
|
+
traceability: TraceabilityImpactConfig;
|
|
114
|
+
subsystemRisk: SubsystemRiskImpactConfig;
|
|
115
|
+
};
|
|
116
|
+
pipeline: PipelineConfig;
|
|
117
|
+
llm: LLMConfig;
|
|
118
|
+
specPDF?: string;
|
|
119
|
+
risk: RiskConfig;
|
|
120
|
+
policy: PolicyConfig;
|
|
121
|
+
flags: FlagConfig;
|
|
122
|
+
audience: AudienceConfig;
|
|
123
|
+
blastRadius: BlastRadiusConfig;
|
|
124
|
+
git: GitConfig;
|
|
125
|
+
}
|
|
126
|
+
export interface ResolvedConfig {
|
|
127
|
+
config: AgentConfig;
|
|
128
|
+
configPath?: string;
|
|
129
|
+
rootDir: string;
|
|
130
|
+
}
|
|
131
|
+
export interface ConfigOverrides {
|
|
132
|
+
path?: string;
|
|
133
|
+
testsRoot?: string;
|
|
134
|
+
flowCatalogPath?: string;
|
|
135
|
+
mode?: AnalysisMode;
|
|
136
|
+
framework?: FrameworkType;
|
|
137
|
+
timeLimitMinutes?: number;
|
|
138
|
+
budget?: BudgetConfig;
|
|
139
|
+
testPatterns?: string[];
|
|
140
|
+
flowPatterns?: string[];
|
|
141
|
+
flowExclude?: string[];
|
|
142
|
+
specPDF?: string;
|
|
143
|
+
gitSince?: string;
|
|
144
|
+
pipeline?: Partial<PipelineConfig>;
|
|
145
|
+
policy?: Partial<PolicyConfig>;
|
|
146
|
+
}
|
|
147
|
+
export declare function resolveConfig(cwd: string, configPath?: string, overrides?: ConfigOverrides): ResolvedConfig;
|
|
148
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/agent/config.ts"],"names":[],"mappings":"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"}
|