agentic-qe 3.7.5 → 3.7.6
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/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/cli/bundle.js +5199 -1335
- package/dist/cli/commands/security.d.ts.map +1 -1
- package/dist/cli/commands/security.js +66 -1
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/test.d.ts.map +1 -1
- package/dist/cli/commands/test.js +86 -3
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/index.js +119 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/coordination/workflow-orchestrator.d.ts.map +1 -1
- package/dist/coordination/workflow-orchestrator.js +2 -6
- package/dist/coordination/workflow-orchestrator.js.map +1 -1
- package/dist/mcp/bundle.js +3977 -153
- package/dist/mcp/handlers/core-handlers.d.ts.map +1 -1
- package/dist/mcp/handlers/core-handlers.js +35 -0
- package/dist/mcp/handlers/core-handlers.js.map +1 -1
- package/dist/mcp/protocol-server.d.ts.map +1 -1
- package/dist/mcp/protocol-server.js +4 -1
- package/dist/mcp/protocol-server.js.map +1 -1
- package/dist/mcp/qe-tool-bridge.d.ts +27 -0
- package/dist/mcp/qe-tool-bridge.d.ts.map +1 -0
- package/dist/mcp/qe-tool-bridge.js +87 -0
- package/dist/mcp/qe-tool-bridge.js.map +1 -0
- package/dist/mcp/tools/registry.d.ts +4 -0
- package/dist/mcp/tools/registry.d.ts.map +1 -1
- package/dist/mcp/tools/registry.js +20 -0
- package/dist/mcp/tools/registry.js.map +1 -1
- package/dist/mcp/tools/security-compliance/visual-security.d.ts +45 -0
- package/dist/mcp/tools/security-compliance/visual-security.d.ts.map +1 -0
- package/dist/mcp/tools/security-compliance/visual-security.js +218 -0
- package/dist/mcp/tools/security-compliance/visual-security.js.map +1 -0
- package/dist/mcp/tools/test-execution/browser-workflow.d.ts +50 -0
- package/dist/mcp/tools/test-execution/browser-workflow.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/browser-workflow.js +145 -0
- package/dist/mcp/tools/test-execution/browser-workflow.js.map +1 -0
- package/dist/mcp/tools/test-execution/load-test.d.ts +37 -0
- package/dist/mcp/tools/test-execution/load-test.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/load-test.js +98 -0
- package/dist/mcp/tools/test-execution/load-test.js.map +1 -0
- package/dist/mcp/tools/test-execution/schedule.d.ts +44 -0
- package/dist/mcp/tools/test-execution/schedule.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/schedule.js +96 -0
- package/dist/mcp/tools/test-execution/schedule.js.map +1 -0
- package/dist/planning/goap-planner.d.ts.map +1 -1
- package/dist/planning/goap-planner.js +7 -28
- package/dist/planning/goap-planner.js.map +1 -1
- package/dist/planning/plan-executor.d.ts.map +1 -1
- package/dist/planning/plan-executor.js +7 -28
- package/dist/planning/plan-executor.js.map +1 -1
- package/package.json +3 -10
- package/dist/cli/commands/qe-tools.d.ts +0 -27
- package/dist/cli/commands/qe-tools.d.ts.map +0 -1
- package/dist/cli/commands/qe-tools.js +0 -771
- package/dist/cli/commands/qe-tools.js.map +0 -1
- package/dist/neural-optimizer/index.d.ts +0 -55
- package/dist/neural-optimizer/index.d.ts.map +0 -1
- package/dist/neural-optimizer/index.js +0 -57
- package/dist/neural-optimizer/index.js.map +0 -1
- package/dist/neural-optimizer/replay-buffer.d.ts +0 -126
- package/dist/neural-optimizer/replay-buffer.d.ts.map +0 -1
- package/dist/neural-optimizer/replay-buffer.js +0 -356
- package/dist/neural-optimizer/replay-buffer.js.map +0 -1
- package/dist/neural-optimizer/swarm-topology.d.ts +0 -157
- package/dist/neural-optimizer/swarm-topology.d.ts.map +0 -1
- package/dist/neural-optimizer/swarm-topology.js +0 -384
- package/dist/neural-optimizer/swarm-topology.js.map +0 -1
- package/dist/neural-optimizer/topology-optimizer.d.ts +0 -137
- package/dist/neural-optimizer/topology-optimizer.d.ts.map +0 -1
- package/dist/neural-optimizer/topology-optimizer.js +0 -657
- package/dist/neural-optimizer/topology-optimizer.js.map +0 -1
- package/dist/neural-optimizer/types.d.ts +0 -333
- package/dist/neural-optimizer/types.d.ts.map +0 -1
- package/dist/neural-optimizer/types.js +0 -57
- package/dist/neural-optimizer/types.js.map +0 -1
- package/dist/neural-optimizer/value-network.d.ts +0 -129
- package/dist/neural-optimizer/value-network.d.ts.map +0 -1
- package/dist/neural-optimizer/value-network.js +0 -279
- package/dist/neural-optimizer/value-network.js.map +0 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL Security Validation MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Validates URLs for security threats (XSS, injection, unsafe protocols)
|
|
5
|
+
* and scans URL/query parameters for PII exposure (emails, SSNs, phone
|
|
6
|
+
* numbers, credit card numbers).
|
|
7
|
+
*/
|
|
8
|
+
import { MCPToolBase, } from '../base.js';
|
|
9
|
+
import { toErrorMessage } from '../../../shared/error-utils.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// PII Patterns
|
|
12
|
+
// ============================================================================
|
|
13
|
+
const PII_PATTERNS = [
|
|
14
|
+
{
|
|
15
|
+
type: 'email',
|
|
16
|
+
pattern: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
|
|
17
|
+
mask: (m) => m[0] + '***@' + m.split('@')[1],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
type: 'ssn',
|
|
21
|
+
pattern: /\b\d{3}-\d{2}-\d{4}\b/g,
|
|
22
|
+
mask: () => '***-**-****',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'credit-card',
|
|
26
|
+
pattern: /\b(?:\d[ -]*?){13,19}\b/g,
|
|
27
|
+
mask: (m) => '****-****-****-' + m.replace(/\D/g, '').slice(-4),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'phone',
|
|
31
|
+
pattern: /\b(?:\+?1[-.\s]?)?(?:\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}\b/g,
|
|
32
|
+
mask: (m) => m.slice(0, 3) + '***' + m.slice(-2),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: 'api-key',
|
|
36
|
+
// Common API key patterns: long hex/base64 strings in query params
|
|
37
|
+
pattern: /(?:key|token|api_key|apikey|secret|password|passwd|auth)=([A-Za-z0-9_\-]{16,})/gi,
|
|
38
|
+
mask: () => '***REDACTED***',
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Tool Implementation
|
|
43
|
+
// ============================================================================
|
|
44
|
+
export class VisualSecurityTool extends MCPToolBase {
|
|
45
|
+
config = {
|
|
46
|
+
name: 'qe/security/url-validate',
|
|
47
|
+
description: 'Validate URL security: checks for XSS/injection patterns, unsafe protocols, ' +
|
|
48
|
+
'and scans URL query parameters for PII exposure (emails, SSNs, credit cards, API keys).',
|
|
49
|
+
domain: 'security-compliance',
|
|
50
|
+
schema: this.buildSchema(),
|
|
51
|
+
};
|
|
52
|
+
buildSchema() {
|
|
53
|
+
return {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
url: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description: 'URL to validate for security threats and PII exposure',
|
|
59
|
+
},
|
|
60
|
+
enablePII: {
|
|
61
|
+
type: 'boolean',
|
|
62
|
+
description: 'Enable PII exposure scanning in URL and query parameters',
|
|
63
|
+
default: true,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
required: ['url'],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async execute(params, context) {
|
|
70
|
+
try {
|
|
71
|
+
const urlSecurity = this.validateURLSecurity(params.url);
|
|
72
|
+
const piiExposure = params.enablePII !== false
|
|
73
|
+
? this.scanForPII(params.url)
|
|
74
|
+
: { scanned: false, found: false, types: [], details: [] };
|
|
75
|
+
const issueCount = urlSecurity.issues.length + (piiExposure.found ? piiExposure.types.length : 0);
|
|
76
|
+
const summary = issueCount === 0
|
|
77
|
+
? `URL passed all checks (security: clean, PII: ${piiExposure.scanned ? 'none found' : 'not scanned'})`
|
|
78
|
+
: `URL has ${urlSecurity.issues.length} security issue(s)${piiExposure.found ? ` and ${piiExposure.types.length} PII type(s) exposed in URL` : ''}`;
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
data: {
|
|
82
|
+
url: params.url,
|
|
83
|
+
urlSecurity,
|
|
84
|
+
piiExposure,
|
|
85
|
+
summary,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
error: toErrorMessage(error),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
validateURLSecurity(url) {
|
|
97
|
+
const issues = [];
|
|
98
|
+
let riskLevel = 'none';
|
|
99
|
+
try {
|
|
100
|
+
const parsed = new URL(url);
|
|
101
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
102
|
+
issues.push({
|
|
103
|
+
type: 'unsafe-protocol',
|
|
104
|
+
description: `Protocol ${parsed.protocol} is not allowed`,
|
|
105
|
+
severity: 'high',
|
|
106
|
+
});
|
|
107
|
+
riskLevel = 'high';
|
|
108
|
+
}
|
|
109
|
+
// XSS patterns
|
|
110
|
+
const xssPatterns = [/<script/i, /javascript:/i, /on\w+=/i, /data:text\/html/i];
|
|
111
|
+
for (const pattern of xssPatterns) {
|
|
112
|
+
if (pattern.test(url)) {
|
|
113
|
+
issues.push({
|
|
114
|
+
type: 'xss',
|
|
115
|
+
description: 'Potential XSS pattern detected in URL',
|
|
116
|
+
severity: 'critical',
|
|
117
|
+
});
|
|
118
|
+
riskLevel = 'critical';
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// SQL injection patterns
|
|
123
|
+
const sqlPatterns = [/'.*or.*'/i, /union.*select/i, /drop.*table/i, /;\s*--/i];
|
|
124
|
+
for (const pattern of sqlPatterns) {
|
|
125
|
+
if (pattern.test(url)) {
|
|
126
|
+
issues.push({
|
|
127
|
+
type: 'sql-injection',
|
|
128
|
+
description: 'Potential SQL injection pattern detected in URL',
|
|
129
|
+
severity: 'critical',
|
|
130
|
+
});
|
|
131
|
+
riskLevel = 'critical';
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Path traversal
|
|
136
|
+
if (/\.\.[/\\]/.test(url)) {
|
|
137
|
+
issues.push({
|
|
138
|
+
type: 'path-traversal',
|
|
139
|
+
description: 'Potential path traversal pattern (../) detected',
|
|
140
|
+
severity: 'high',
|
|
141
|
+
});
|
|
142
|
+
if (riskLevel !== 'critical')
|
|
143
|
+
riskLevel = 'high';
|
|
144
|
+
}
|
|
145
|
+
// Open redirect via query param
|
|
146
|
+
const redirectParams = ['redirect', 'url', 'next', 'return', 'returnUrl', 'goto'];
|
|
147
|
+
for (const param of redirectParams) {
|
|
148
|
+
const value = parsed.searchParams.get(param);
|
|
149
|
+
if (value && /^https?:\/\//.test(value)) {
|
|
150
|
+
issues.push({
|
|
151
|
+
type: 'open-redirect',
|
|
152
|
+
description: `Query parameter "${param}" contains an external URL — potential open redirect`,
|
|
153
|
+
severity: 'medium',
|
|
154
|
+
});
|
|
155
|
+
if (riskLevel === 'none')
|
|
156
|
+
riskLevel = 'medium';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
issues.push({
|
|
162
|
+
type: 'invalid-url',
|
|
163
|
+
description: 'URL could not be parsed',
|
|
164
|
+
severity: 'critical',
|
|
165
|
+
});
|
|
166
|
+
riskLevel = 'critical';
|
|
167
|
+
}
|
|
168
|
+
return { valid: issues.length === 0, riskLevel, issues };
|
|
169
|
+
}
|
|
170
|
+
scanForPII(url) {
|
|
171
|
+
const details = [];
|
|
172
|
+
const typesFound = new Set();
|
|
173
|
+
// Decode URL to catch encoded PII
|
|
174
|
+
let decoded;
|
|
175
|
+
try {
|
|
176
|
+
decoded = decodeURIComponent(url);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
decoded = url;
|
|
180
|
+
}
|
|
181
|
+
// Determine which part of the URL the PII is in
|
|
182
|
+
let queryString = '';
|
|
183
|
+
let pathString = '';
|
|
184
|
+
try {
|
|
185
|
+
const parsed = new URL(decoded);
|
|
186
|
+
queryString = parsed.search;
|
|
187
|
+
pathString = parsed.pathname;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
queryString = decoded;
|
|
191
|
+
}
|
|
192
|
+
for (const { type, pattern, mask } of PII_PATTERNS) {
|
|
193
|
+
// Reset regex lastIndex for global patterns
|
|
194
|
+
pattern.lastIndex = 0;
|
|
195
|
+
let match;
|
|
196
|
+
while ((match = pattern.exec(decoded)) !== null) {
|
|
197
|
+
typesFound.add(type);
|
|
198
|
+
const location = queryString.includes(match[0])
|
|
199
|
+
? 'query-parameter'
|
|
200
|
+
: pathString.includes(match[0])
|
|
201
|
+
? 'path'
|
|
202
|
+
: 'url';
|
|
203
|
+
details.push({
|
|
204
|
+
type,
|
|
205
|
+
location,
|
|
206
|
+
masked: mask(match[0]),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
scanned: true,
|
|
212
|
+
found: typesFound.size > 0,
|
|
213
|
+
types: Array.from(typesFound),
|
|
214
|
+
details,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=visual-security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-security.js","sourceRoot":"","sources":["../../../../src/mcp/tools/security-compliance/visual-security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Workflow MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Loads, validates, and prepares browser automation workflows from inline YAML
|
|
5
|
+
* or built-in templates. Returns the resolved workflow definition with
|
|
6
|
+
* interpolated variables for execution by a browser client.
|
|
7
|
+
*/
|
|
8
|
+
import { MCPToolBase, MCPToolConfig, MCPToolContext } from '../base.js';
|
|
9
|
+
import { ToolResult } from '../../types.js';
|
|
10
|
+
export interface BrowserWorkflowParams {
|
|
11
|
+
workflowYaml?: string;
|
|
12
|
+
variables?: Record<string, string>;
|
|
13
|
+
templateName?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface BrowserWorkflowResult {
|
|
17
|
+
workflowName: string;
|
|
18
|
+
description: string;
|
|
19
|
+
source: 'template' | 'inline-yaml' | 'none';
|
|
20
|
+
templateUsed: string | null;
|
|
21
|
+
steps: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
action: string;
|
|
24
|
+
config: Record<string, unknown>;
|
|
25
|
+
optional: boolean;
|
|
26
|
+
assertionCount: number;
|
|
27
|
+
}>;
|
|
28
|
+
variables: {
|
|
29
|
+
defined: Array<{
|
|
30
|
+
name: string;
|
|
31
|
+
type: string;
|
|
32
|
+
required: boolean;
|
|
33
|
+
hasDefault: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
provided: Record<string, string>;
|
|
36
|
+
};
|
|
37
|
+
validation: {
|
|
38
|
+
valid: boolean;
|
|
39
|
+
errors: string[];
|
|
40
|
+
warnings: string[];
|
|
41
|
+
};
|
|
42
|
+
availableTemplates: string[];
|
|
43
|
+
summary: string;
|
|
44
|
+
}
|
|
45
|
+
export declare class BrowserWorkflowTool extends MCPToolBase<BrowserWorkflowParams, BrowserWorkflowResult> {
|
|
46
|
+
readonly config: MCPToolConfig;
|
|
47
|
+
private buildSchema;
|
|
48
|
+
execute(params: BrowserWorkflowParams, context: MCPToolContext): Promise<ToolResult<BrowserWorkflowResult>>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=browser-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-workflow.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/test-execution/browser-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,WAAW,EACX,aAAa,EACb,cAAc,EAEf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAO5C,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;IAC5C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,QAAQ,EAAE,OAAO,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,SAAS,EAAE;QACT,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAC;YAAC,UAAU,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACvF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,CAAC;IACF,UAAU,EAAE;QACV,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,qBAAa,mBAAoB,SAAQ,WAAW,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;IAChG,QAAQ,CAAC,MAAM,EAAE,aAAa,CAQ5B;IAEF,OAAO,CAAC,WAAW;IAyBb,OAAO,CACX,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;CA4G9C"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Workflow MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Loads, validates, and prepares browser automation workflows from inline YAML
|
|
5
|
+
* or built-in templates. Returns the resolved workflow definition with
|
|
6
|
+
* interpolated variables for execution by a browser client.
|
|
7
|
+
*/
|
|
8
|
+
import { MCPToolBase, } from '../base.js';
|
|
9
|
+
import { toErrorMessage } from '../../../shared/error-utils.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Tool Implementation
|
|
12
|
+
// ============================================================================
|
|
13
|
+
export class BrowserWorkflowTool extends MCPToolBase {
|
|
14
|
+
config = {
|
|
15
|
+
name: 'qe/workflows/browser-load',
|
|
16
|
+
description: 'Load, validate, and prepare browser automation workflows from inline YAML or built-in templates. ' +
|
|
17
|
+
'Returns the resolved workflow with steps and variable bindings, ready for browser execution. ' +
|
|
18
|
+
'Templates: login-flow, form-validation, visual-regression, oauth-flow, etc.',
|
|
19
|
+
domain: 'test-execution',
|
|
20
|
+
schema: this.buildSchema(),
|
|
21
|
+
};
|
|
22
|
+
buildSchema() {
|
|
23
|
+
return {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
workflowYaml: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: 'Inline YAML workflow definition. Mutually exclusive with templateName.',
|
|
29
|
+
},
|
|
30
|
+
templateName: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
description: 'Built-in template name to load.',
|
|
33
|
+
enum: [
|
|
34
|
+
'login-flow', 'oauth-flow', 'scraping-workflow', 'visual-regression',
|
|
35
|
+
'form-validation', 'navigation-flow', 'api-integration',
|
|
36
|
+
'performance-audit', 'accessibility-audit',
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
variables: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
description: 'Runtime variable overrides (e.g., { "baseUrl": "https://example.com" })',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async execute(params, context) {
|
|
47
|
+
try {
|
|
48
|
+
const { WorkflowLoader, WORKFLOW_TEMPLATES, WORKFLOW_DESCRIPTIONS, interpolateVariables, } = await import('../../../workflows/browser/index.js');
|
|
49
|
+
const { parse: parseYaml } = await import('yaml');
|
|
50
|
+
const loader = new WorkflowLoader();
|
|
51
|
+
const templateList = [...WORKFLOW_TEMPLATES];
|
|
52
|
+
const descriptions = WORKFLOW_DESCRIPTIONS;
|
|
53
|
+
// No input — list available templates
|
|
54
|
+
if (!params.workflowYaml && !params.templateName) {
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
data: {
|
|
58
|
+
workflowName: 'none',
|
|
59
|
+
description: 'No workflow specified. Use templateName or workflowYaml.',
|
|
60
|
+
source: 'none',
|
|
61
|
+
templateUsed: null,
|
|
62
|
+
steps: [],
|
|
63
|
+
variables: { defined: [], provided: {} },
|
|
64
|
+
validation: { valid: true, errors: [], warnings: [] },
|
|
65
|
+
availableTemplates: templateList,
|
|
66
|
+
summary: `Available templates: ${templateList.join(', ')}`,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Load workflow from inline YAML or template
|
|
71
|
+
let workflow;
|
|
72
|
+
let source;
|
|
73
|
+
let templateUsed = null;
|
|
74
|
+
if (params.workflowYaml) {
|
|
75
|
+
// Parse inline YAML
|
|
76
|
+
source = 'inline-yaml';
|
|
77
|
+
workflow = parseYaml(params.workflowYaml);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Load from template
|
|
81
|
+
source = 'template';
|
|
82
|
+
templateUsed = params.templateName;
|
|
83
|
+
workflow = await loader.load(params.templateName);
|
|
84
|
+
}
|
|
85
|
+
// Validate
|
|
86
|
+
const validation = await loader.validate(workflow);
|
|
87
|
+
// Interpolate variables into step configs if provided
|
|
88
|
+
const resolvedSteps = (workflow.steps ?? []).map(step => {
|
|
89
|
+
let config = step.config;
|
|
90
|
+
if (params.variables) {
|
|
91
|
+
// Interpolate each string value in the config
|
|
92
|
+
const interpolated = {};
|
|
93
|
+
for (const [k, v] of Object.entries(config)) {
|
|
94
|
+
interpolated[k] = typeof v === 'string'
|
|
95
|
+
? interpolateVariables(v, params.variables)
|
|
96
|
+
: v;
|
|
97
|
+
}
|
|
98
|
+
config = interpolated;
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
name: step.name,
|
|
102
|
+
action: step.action,
|
|
103
|
+
config,
|
|
104
|
+
optional: step.optional ?? false,
|
|
105
|
+
assertionCount: step.assertions?.length ?? 0,
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
data: {
|
|
111
|
+
workflowName: workflow.name || templateUsed || 'custom',
|
|
112
|
+
description: workflow.description || (templateUsed ? descriptions[templateUsed] || '' : ''),
|
|
113
|
+
source,
|
|
114
|
+
templateUsed,
|
|
115
|
+
steps: resolvedSteps,
|
|
116
|
+
variables: {
|
|
117
|
+
defined: (workflow.variables ?? []).map(v => ({
|
|
118
|
+
name: v.name,
|
|
119
|
+
type: v.type,
|
|
120
|
+
required: v.required,
|
|
121
|
+
hasDefault: v.default !== undefined,
|
|
122
|
+
})),
|
|
123
|
+
provided: params.variables || {},
|
|
124
|
+
},
|
|
125
|
+
validation: {
|
|
126
|
+
valid: validation.valid,
|
|
127
|
+
errors: validation.errors,
|
|
128
|
+
warnings: validation.warnings,
|
|
129
|
+
},
|
|
130
|
+
availableTemplates: templateList,
|
|
131
|
+
summary: validation.valid
|
|
132
|
+
? `Workflow "${workflow.name}" loaded (${source}): ${resolvedSteps.length} steps, ${(workflow.variables ?? []).length} variables`
|
|
133
|
+
: `Workflow "${workflow.name}" has validation errors: ${validation.errors.join('; ')}`,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
error: toErrorMessage(error),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=browser-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-workflow.js","sourceRoot":"","sources":["../../../../src/mcp/tools/test-execution/browser-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load Testing MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Exposes the agent load testing framework (AgentLoadTester, MetricsCollector,
|
|
5
|
+
* BottleneckAnalyzer) as an MCP tool.
|
|
6
|
+
*/
|
|
7
|
+
import { MCPToolBase, MCPToolConfig, MCPToolContext } from '../base.js';
|
|
8
|
+
import { ToolResult } from '../../types.js';
|
|
9
|
+
export interface LoadTestParams {
|
|
10
|
+
targetAgents?: number;
|
|
11
|
+
profile?: 'light' | 'medium' | 'heavy';
|
|
12
|
+
durationMs?: number;
|
|
13
|
+
mockMode?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface LoadTestResult {
|
|
17
|
+
testId: string;
|
|
18
|
+
profile: string;
|
|
19
|
+
targetAgents: number;
|
|
20
|
+
duration: number;
|
|
21
|
+
mockMode: boolean;
|
|
22
|
+
passed: boolean;
|
|
23
|
+
bottleneckCount: number;
|
|
24
|
+
report: {
|
|
25
|
+
overallSeverity: string;
|
|
26
|
+
hasCritical: boolean;
|
|
27
|
+
checksPerformed: number;
|
|
28
|
+
bottlenecksDetected: number;
|
|
29
|
+
};
|
|
30
|
+
summary: string;
|
|
31
|
+
}
|
|
32
|
+
export declare class LoadTestTool extends MCPToolBase<LoadTestParams, LoadTestResult> {
|
|
33
|
+
readonly config: MCPToolConfig;
|
|
34
|
+
private buildSchema;
|
|
35
|
+
execute(params: LoadTestParams, context: MCPToolContext): Promise<ToolResult<LoadTestResult>>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=load-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-test.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/test-execution/load-test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,WAAW,EACX,aAAa,EACb,cAAc,EAEf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAO5C,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE;QACN,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,OAAO,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,qBAAa,YAAa,SAAQ,WAAW,CAAC,cAAc,EAAE,cAAc,CAAC;IAC3E,QAAQ,CAAC,MAAM,EAAE,aAAa,CAS5B;IAEF,OAAO,CAAC,WAAW;IAiCb,OAAO,CACX,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;CA8CvC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load Testing MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Exposes the agent load testing framework (AgentLoadTester, MetricsCollector,
|
|
5
|
+
* BottleneckAnalyzer) as an MCP tool.
|
|
6
|
+
*/
|
|
7
|
+
import { MCPToolBase, } from '../base.js';
|
|
8
|
+
import { toErrorMessage } from '../../../shared/error-utils.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Tool Implementation
|
|
11
|
+
// ============================================================================
|
|
12
|
+
export class LoadTestTool extends MCPToolBase {
|
|
13
|
+
config = {
|
|
14
|
+
name: 'qe/tests/load',
|
|
15
|
+
description: 'Run agent load tests to validate fleet scalability. Supports light, medium, and heavy ' +
|
|
16
|
+
'workload profiles. Uses mock agents by default (safe); set mockMode=false to test with ' +
|
|
17
|
+
'real fleet agents (requires fleet_init). Reports bottlenecks and pass/fail criteria.',
|
|
18
|
+
domain: 'test-execution',
|
|
19
|
+
schema: this.buildSchema(),
|
|
20
|
+
timeout: 300000,
|
|
21
|
+
};
|
|
22
|
+
buildSchema() {
|
|
23
|
+
return {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
targetAgents: {
|
|
27
|
+
type: 'number',
|
|
28
|
+
description: 'Target number of concurrent agents to simulate',
|
|
29
|
+
default: 10,
|
|
30
|
+
minimum: 1,
|
|
31
|
+
maximum: 200,
|
|
32
|
+
},
|
|
33
|
+
profile: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Workload profile: light, medium, or heavy',
|
|
36
|
+
enum: ['light', 'medium', 'heavy'],
|
|
37
|
+
default: 'medium',
|
|
38
|
+
},
|
|
39
|
+
durationMs: {
|
|
40
|
+
type: 'number',
|
|
41
|
+
description: 'Test duration in milliseconds',
|
|
42
|
+
default: 30000,
|
|
43
|
+
minimum: 5000,
|
|
44
|
+
maximum: 300000,
|
|
45
|
+
},
|
|
46
|
+
mockMode: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
description: 'Use mock agents (true, default) or real fleet agents (false, requires fleet_init)',
|
|
49
|
+
default: true,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async execute(params, context) {
|
|
55
|
+
try {
|
|
56
|
+
const { createAgentLoadTester } = await import('../../../testing/load/index.js');
|
|
57
|
+
const profile = params.profile || 'medium';
|
|
58
|
+
const targetAgents = params.targetAgents || 10;
|
|
59
|
+
const durationMs = params.durationMs || 30000;
|
|
60
|
+
const mockMode = params.mockMode !== false; // default true
|
|
61
|
+
const tester = createAgentLoadTester({
|
|
62
|
+
maxAgents: targetAgents,
|
|
63
|
+
workloadProfile: profile,
|
|
64
|
+
mockMode,
|
|
65
|
+
});
|
|
66
|
+
const result = await tester.runTest(targetAgents, durationMs);
|
|
67
|
+
const bottlenecks = result.bottlenecks;
|
|
68
|
+
return {
|
|
69
|
+
success: true,
|
|
70
|
+
data: {
|
|
71
|
+
testId: context.requestId,
|
|
72
|
+
profile,
|
|
73
|
+
targetAgents,
|
|
74
|
+
duration: result.duration,
|
|
75
|
+
mockMode,
|
|
76
|
+
passed: result.success,
|
|
77
|
+
bottleneckCount: bottlenecks?.bottlenecks?.length ?? 0,
|
|
78
|
+
report: {
|
|
79
|
+
overallSeverity: bottlenecks?.overallSeverity ?? 'none',
|
|
80
|
+
hasCritical: bottlenecks?.hasCritical ?? false,
|
|
81
|
+
checksPerformed: bottlenecks?.summary?.totalChecks ?? 0,
|
|
82
|
+
bottlenecksDetected: bottlenecks?.summary?.detected ?? 0,
|
|
83
|
+
},
|
|
84
|
+
summary: `Load test (${profile}, ${mockMode ? 'mock' : 'real'}): ${targetAgents} agents, ${durationMs}ms` +
|
|
85
|
+
` — ${result.success ? 'PASSED' : 'FAILED'}` +
|
|
86
|
+
(bottlenecks?.hasCritical ? ' [CRITICAL BOTTLENECKS]' : ''),
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
error: toErrorMessage(error),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=load-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-test.js","sourceRoot":"","sources":["../../../../src/mcp/tools/test-execution/load-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Scheduling MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Exposes the test-scheduling pipeline (phase scheduler, git-aware selector,
|
|
5
|
+
* flaky tracker) as an MCP tool.
|
|
6
|
+
*/
|
|
7
|
+
import { MCPToolBase, MCPToolConfig, MCPToolContext } from '../base.js';
|
|
8
|
+
import { ToolResult } from '../../types.js';
|
|
9
|
+
export interface TestScheduleParams {
|
|
10
|
+
cwd?: string;
|
|
11
|
+
gitRef?: string;
|
|
12
|
+
useGitAware?: boolean;
|
|
13
|
+
trackFlaky?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface TestScheduleResult {
|
|
17
|
+
pipelineId: string;
|
|
18
|
+
phases: Array<{
|
|
19
|
+
phaseId: string;
|
|
20
|
+
phaseName: string;
|
|
21
|
+
totalTests: number;
|
|
22
|
+
passed: number;
|
|
23
|
+
failed: number;
|
|
24
|
+
passRate: number;
|
|
25
|
+
durationMs: number;
|
|
26
|
+
}>;
|
|
27
|
+
gitAware: {
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
selectedTests: number;
|
|
30
|
+
gitRef?: string;
|
|
31
|
+
};
|
|
32
|
+
flakyTracking: {
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
};
|
|
35
|
+
totalDuration: number;
|
|
36
|
+
ranAllTests: boolean;
|
|
37
|
+
summary: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class TestScheduleTool extends MCPToolBase<TestScheduleParams, TestScheduleResult> {
|
|
40
|
+
readonly config: MCPToolConfig;
|
|
41
|
+
private buildSchema;
|
|
42
|
+
execute(params: TestScheduleParams, context: MCPToolContext): Promise<ToolResult<TestScheduleResult>>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/test-execution/schedule.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,WAAW,EACX,aAAa,EACb,cAAc,EAGf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAO5C,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,aAAa,EAAE;QACb,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,qBAAa,gBAAiB,SAAQ,WAAW,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACvF,QAAQ,CAAC,MAAM,EAAE,aAAa,CAO5B;IAEF,OAAO,CAAC,WAAW;IA0Bb,OAAO,CACX,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;CAoD3C"}
|